/**
 * HTML elements and other resources for web-based applications that need to
 * interact with the browser and the DOM (Document Object Model).
 *
 * This library includes DOM element types, CSS styling, local storage,
 * media, speech, events, and more.
 * To get started,
 * check out the [Element] class, the base class for many of the HTML
 * DOM types.
 *
 * ## Other resources
 *
 * * If you've never written a web app before, try our
 * tutorials&mdash;[A Game of Darts](http://dartlang.org/docs/tutorials).
 *
 * * To see some web-based Dart apps in action and to play with the code,
 * download
 * [Dart Editor](http://www.dartlang.org/#get-started)
 * and run its built-in examples.
 *
 * * For even more examples, see
 * [Dart HTML5 Samples](https://github.com/dart-lang/dart-html5-samples)
 * on Github.
 */
library dart.dom.html;

import 'dart:async';
import 'dart:collection';
import 'dart:_internal' hide Symbol, deprecated;
import 'dart:html_common';
import 'dart:indexed_db';
import 'dart:isolate';
import "dart:convert";
import 'dart:math';
import 'dart:_native_typed_data';
import 'dart:typed_data';
import 'dart:svg' as svg;
import 'dart:svg' show Matrix;
import 'dart:svg' show SvgSvgElement;
import 'dart:web_audio' as web_audio;
import 'dart:web_gl' as gl;
import 'dart:web_sql';
import 'dart:_isolate_helper' show IsolateNatives;
import 'dart:_foreign_helper' show JS, JS_INTERCEPTOR_CONSTANT;
// 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.

// DO NOT EDIT - unless you are editing documentation as per:
// https://code.google.com/p/dart/wiki/ContributingHTMLDocumentation
// Auto-generated dart:html library.


// Not actually used, but imported since dart:html can generate these objects.
import 'dart:_js_helper' show
    convertDartClosureToJS, Creates, JavaScriptIndexingBehavior,
    JSName, Null, Returns,
    findDispatchTagForInterceptorClass, setNativeSubclassDispatchRecord,
    makeLeafDispatchRecord;
import 'dart:_interceptors' show
    Interceptor, JSExtendableArray, findInterceptorConstructorForType,
    findConstructorForNativeSubclassType, getNativeInterceptor,
    setDispatchProperty;

export 'dart:math' show Rectangle, Point;





/**
 * Top-level container for a web page, which is usually a browser tab or window.
 *
 * Each web page loaded in the browser has its own [Window], which is a
 * container for the web page.
 *
 * If the web page has any `<iframe>` elements, then each `<iframe>` has its own
 * [Window] object, which is accessible only to that `<iframe>`.
 *
 * See also:
 *
 *   * [Window](https://developer.mozilla.org/en-US/docs/Web/API/window) from MDN.
 */
Window get window => JS('Window', 'window');

/**
 * Root node for all content in a web page.
 */
HtmlDocument get document => JS('HtmlDocument', 'document');

// Workaround for tags like <cite> that lack their own Element subclass --
// Dart issue 1990.
class HtmlElement extends Element native "HTMLElement" {
  factory HtmlElement() { throw new UnsupportedError("Not supported"); }

  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  HtmlElement.created() : super.created();
}

// EntryArray type was removed, so explicitly adding it to allow support for
// older Chrome versions.
// Issue #12573.
abstract class _EntryArray implements List<Entry> native "EntryArray" {}

/**
 * Spawn a DOM isolate using the given URI in the same window.
 * This isolate is not concurrent.  It runs on the browser thread
 * with full access to the DOM.
 * Note: this API is still evolving and may move to dart:isolate.
 */
@Experimental()
Future<Isolate> spawnDomUri(Uri uri, List<String> args, message) {
  // TODO(17738): Implement this.
  throw new UnimplementedError();
}
// 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.


@DocsEditable()
@DomName('AbstractWorker')
abstract class AbstractWorker extends Interceptor implements EventTarget native "AbstractWorker" {
  // To suppress missing implicit constructor warnings.
  factory AbstractWorker._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [AbstractWorker].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('AbstractWorker.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<ErrorEvent> errorEvent = const EventStreamProvider<ErrorEvent>('error');

  /// Stream of `error` events handled by this [AbstractWorker].
  @DomName('AbstractWorker.onerror')
  @DocsEditable()
  Stream<ErrorEvent> get onError => errorEvent.forTarget(this);
}
// 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.


@DocsEditable()
@DomName('Algorithm')
@Experimental() // untriaged
class Algorithm extends Interceptor native "Algorithm" {
  // To suppress missing implicit constructor warnings.
  factory Algorithm._() { throw new UnsupportedError("Not supported"); }

  @DomName('Algorithm.name')
  @DocsEditable()
  @Experimental() // untriaged
  final String name;
}
// 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.


@DocsEditable()
@DomName('HTMLAnchorElement')
class AnchorElement extends HtmlElement implements UrlUtils native "HTMLAnchorElement" {
  // To suppress missing implicit constructor warnings.
  factory AnchorElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLAnchorElement.HTMLAnchorElement')
  @DocsEditable()
  factory AnchorElement({String href}) {
    var e = document.createElement("a");
    if (href != null) e.href = href;
    return e;
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  AnchorElement.created() : super.created();

  @DomName('HTMLAnchorElement.download')
  @DocsEditable()
  String download;

  @DomName('HTMLAnchorElement.hreflang')
  @DocsEditable()
  String hreflang;

  @DomName('HTMLAnchorElement.rel')
  @DocsEditable()
  String rel;

  @DomName('HTMLAnchorElement.target')
  @DocsEditable()
  String target;

  @DomName('HTMLAnchorElement.type')
  @DocsEditable()
  String type;

  // From URLUtils

  @DomName('HTMLAnchorElement.hash')
  @DocsEditable()
  String hash;

  @DomName('HTMLAnchorElement.host')
  @DocsEditable()
  String host;

  @DomName('HTMLAnchorElement.hostname')
  @DocsEditable()
  String hostname;

  @DomName('HTMLAnchorElement.href')
  @DocsEditable()
  String href;

  @DomName('HTMLAnchorElement.origin')
  @DocsEditable()
  // WebKit only
  @Experimental() // non-standard
  final String origin;

  @DomName('HTMLAnchorElement.password')
  @DocsEditable()
  @Experimental() // untriaged
  String password;

  @DomName('HTMLAnchorElement.pathname')
  @DocsEditable()
  String pathname;

  @DomName('HTMLAnchorElement.port')
  @DocsEditable()
  String port;

  @DomName('HTMLAnchorElement.protocol')
  @DocsEditable()
  String protocol;

  @DomName('HTMLAnchorElement.search')
  @DocsEditable()
  String search;

  @DomName('HTMLAnchorElement.username')
  @DocsEditable()
  @Experimental() // untriaged
  String username;

  @DomName('HTMLAnchorElement.toString')
  @DocsEditable()
  String toString() native;
}
// 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.


@DocsEditable()
@DomName('Animation')
@Experimental() // untriaged
class Animation extends TimedItem native "Animation" {
  // To suppress missing implicit constructor warnings.
  factory Animation._() { throw new UnsupportedError("Not supported"); }

  @DomName('Animation.Animation')
  @DocsEditable()
  factory Animation(Element target, List<Map> keyframes, [timingInput]) {
    if ((timingInput is Map || timingInput == null) && (keyframes is List<Map> || keyframes == null) && (target is Element || target == null)) {
      return Animation._create_1(target, keyframes, timingInput);
    }
    if ((timingInput is num || timingInput == null) && (keyframes is List<Map> || keyframes == null) && (target is Element || target == null)) {
      return Animation._create_2(target, keyframes, timingInput);
    }
    if ((keyframes is List<Map> || keyframes == null) && (target is Element || target == null) && timingInput == null) {
      return Animation._create_3(target, keyframes);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static Animation _create_1(target, keyframes, timingInput) => JS('Animation', 'new Animation(#,#,#)', target, keyframes, timingInput);
  static Animation _create_2(target, keyframes, timingInput) => JS('Animation', 'new Animation(#,#,#)', target, keyframes, timingInput);
  static Animation _create_3(target, keyframes) => JS('Animation', 'new Animation(#,#)', target, keyframes);
}
// 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.


@DocsEditable()
@DomName('WebKitAnimationEvent')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
class AnimationEvent extends Event native "WebKitAnimationEvent" {
  // To suppress missing implicit constructor warnings.
  factory AnimationEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('WebKitAnimationEvent.animationName')
  @DocsEditable()
  final String animationName;

  @DomName('WebKitAnimationEvent.elapsedTime')
  @DocsEditable()
  final double elapsedTime;
}
// 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.


@DocsEditable()
@DomName('ApplicationCache')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.OPERA)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
class ApplicationCache extends EventTarget native "ApplicationCache,DOMApplicationCache,OfflineResourceList" {
  // To suppress missing implicit constructor warnings.
  factory ApplicationCache._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `cached` events to event
   * handlers that are not necessarily instances of [ApplicationCache].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('ApplicationCache.cachedEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> cachedEvent = const EventStreamProvider<Event>('cached');

  /**
   * Static factory designed to expose `checking` events to event
   * handlers that are not necessarily instances of [ApplicationCache].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('ApplicationCache.checkingEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> checkingEvent = const EventStreamProvider<Event>('checking');

  /**
   * Static factory designed to expose `downloading` events to event
   * handlers that are not necessarily instances of [ApplicationCache].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('ApplicationCache.downloadingEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> downloadingEvent = const EventStreamProvider<Event>('downloading');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [ApplicationCache].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('ApplicationCache.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `noupdate` events to event
   * handlers that are not necessarily instances of [ApplicationCache].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('ApplicationCache.noupdateEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> noUpdateEvent = const EventStreamProvider<Event>('noupdate');

  /**
   * Static factory designed to expose `obsolete` events to event
   * handlers that are not necessarily instances of [ApplicationCache].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('ApplicationCache.obsoleteEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> obsoleteEvent = const EventStreamProvider<Event>('obsolete');

  /**
   * Static factory designed to expose `progress` events to event
   * handlers that are not necessarily instances of [ApplicationCache].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('ApplicationCache.progressEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> progressEvent = const EventStreamProvider<ProgressEvent>('progress');

  /**
   * Static factory designed to expose `updateready` events to event
   * handlers that are not necessarily instances of [ApplicationCache].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('ApplicationCache.updatereadyEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> updateReadyEvent = const EventStreamProvider<Event>('updateready');

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.applicationCache)');

  @DomName('ApplicationCache.CHECKING')
  @DocsEditable()
  static const int CHECKING = 2;

  @DomName('ApplicationCache.DOWNLOADING')
  @DocsEditable()
  static const int DOWNLOADING = 3;

  @DomName('ApplicationCache.IDLE')
  @DocsEditable()
  static const int IDLE = 1;

  @DomName('ApplicationCache.OBSOLETE')
  @DocsEditable()
  static const int OBSOLETE = 5;

  @DomName('ApplicationCache.UNCACHED')
  @DocsEditable()
  static const int UNCACHED = 0;

  @DomName('ApplicationCache.UPDATEREADY')
  @DocsEditable()
  static const int UPDATEREADY = 4;

  @DomName('ApplicationCache.status')
  @DocsEditable()
  final int status;

  @DomName('ApplicationCache.abort')
  @DocsEditable()
  void abort() native;

  @DomName('ApplicationCache.swapCache')
  @DocsEditable()
  void swapCache() native;

  @DomName('ApplicationCache.update')
  @DocsEditable()
  void update() native;

  /// Stream of `cached` events handled by this [ApplicationCache].
  @DomName('ApplicationCache.oncached')
  @DocsEditable()
  Stream<Event> get onCached => cachedEvent.forTarget(this);

  /// Stream of `checking` events handled by this [ApplicationCache].
  @DomName('ApplicationCache.onchecking')
  @DocsEditable()
  Stream<Event> get onChecking => checkingEvent.forTarget(this);

  /// Stream of `downloading` events handled by this [ApplicationCache].
  @DomName('ApplicationCache.ondownloading')
  @DocsEditable()
  Stream<Event> get onDownloading => downloadingEvent.forTarget(this);

  /// Stream of `error` events handled by this [ApplicationCache].
  @DomName('ApplicationCache.onerror')
  @DocsEditable()
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `noupdate` events handled by this [ApplicationCache].
  @DomName('ApplicationCache.onnoupdate')
  @DocsEditable()
  Stream<Event> get onNoUpdate => noUpdateEvent.forTarget(this);

  /// Stream of `obsolete` events handled by this [ApplicationCache].
  @DomName('ApplicationCache.onobsolete')
  @DocsEditable()
  Stream<Event> get onObsolete => obsoleteEvent.forTarget(this);

  /// Stream of `progress` events handled by this [ApplicationCache].
  @DomName('ApplicationCache.onprogress')
  @DocsEditable()
  Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);

  /// Stream of `updateready` events handled by this [ApplicationCache].
  @DomName('ApplicationCache.onupdateready')
  @DocsEditable()
  Stream<Event> get onUpdateReady => updateReadyEvent.forTarget(this);
}
// 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.


@DocsEditable()
/**
 * DOM Area Element, which links regions of an image map with a hyperlink.
 *
 * The element can also define an uninteractive region of the map.
 *
 * See also:
 *
 * * [<area>](https://developer.mozilla.org/en-US/docs/HTML/Element/area)
 * on MDN.
 */
@DomName('HTMLAreaElement')
class AreaElement extends HtmlElement implements UrlUtils native "HTMLAreaElement" {
  // To suppress missing implicit constructor warnings.
  factory AreaElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLAreaElement.HTMLAreaElement')
  @DocsEditable()
  factory AreaElement() => document.createElement("area");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  AreaElement.created() : super.created();

  @DomName('HTMLAreaElement.alt')
  @DocsEditable()
  String alt;

  @DomName('HTMLAreaElement.coords')
  @DocsEditable()
  String coords;

  @DomName('HTMLAreaElement.shape')
  @DocsEditable()
  String shape;

  @DomName('HTMLAreaElement.target')
  @DocsEditable()
  String target;

  // From URLUtils

  @DomName('HTMLAreaElement.hash')
  @DocsEditable()
  String hash;

  @DomName('HTMLAreaElement.host')
  @DocsEditable()
  String host;

  @DomName('HTMLAreaElement.hostname')
  @DocsEditable()
  String hostname;

  @DomName('HTMLAreaElement.href')
  @DocsEditable()
  String href;

  @DomName('HTMLAreaElement.origin')
  @DocsEditable()
  @Experimental() // untriaged
  final String origin;

  @DomName('HTMLAreaElement.password')
  @DocsEditable()
  @Experimental() // untriaged
  String password;

  @DomName('HTMLAreaElement.pathname')
  @DocsEditable()
  String pathname;

  @DomName('HTMLAreaElement.port')
  @DocsEditable()
  String port;

  @DomName('HTMLAreaElement.protocol')
  @DocsEditable()
  String protocol;

  @DomName('HTMLAreaElement.search')
  @DocsEditable()
  String search;

  @DomName('HTMLAreaElement.username')
  @DocsEditable()
  @Experimental() // untriaged
  String username;

  @DomName('HTMLAreaElement.toString')
  @DocsEditable()
  @Experimental() // untriaged
  String toString() native;
}
// 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.


@DocsEditable()
@DomName('HTMLAudioElement')
class AudioElement extends MediaElement native "HTMLAudioElement" {
  // To suppress missing implicit constructor warnings.
  factory AudioElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLAudioElement.HTMLAudioElement')
  @DocsEditable()
  factory AudioElement([String src]) {
    if (src != null) {
      return AudioElement._create_1(src);
    }
    return AudioElement._create_2();
  }
  static AudioElement _create_1(src) => JS('AudioElement', 'new Audio(#)', src);
  static AudioElement _create_2() => JS('AudioElement', 'new Audio()');
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  AudioElement.created() : super.created();
}
// 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.


@DocsEditable()
@DomName('AutocompleteErrorEvent')
// http://wiki.whatwg.org/wiki/RequestAutocomplete
@Experimental()
class AutocompleteErrorEvent extends Event native "AutocompleteErrorEvent" {
  // To suppress missing implicit constructor warnings.
  factory AutocompleteErrorEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('AutocompleteErrorEvent.reason')
  @DocsEditable()
  final String reason;
}
// 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.


@DocsEditable()
@DomName('HTMLBRElement')
class BRElement extends HtmlElement native "HTMLBRElement" {
  // To suppress missing implicit constructor warnings.
  factory BRElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLBRElement.HTMLBRElement')
  @DocsEditable()
  factory BRElement() => document.createElement("br");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  BRElement.created() : super.created();
}
// 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.


@DocsEditable()
@DomName('BarProp')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#barprop
@deprecated // standard
class BarProp extends Interceptor native "BarProp" {
  // To suppress missing implicit constructor warnings.
  factory BarProp._() { throw new UnsupportedError("Not supported"); }

  @DomName('BarProp.visible')
  @DocsEditable()
  final bool visible;
}
// 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.


@DocsEditable()
@DomName('HTMLBaseElement')
class BaseElement extends HtmlElement native "HTMLBaseElement" {
  // To suppress missing implicit constructor warnings.
  factory BaseElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLBaseElement.HTMLBaseElement')
  @DocsEditable()
  factory BaseElement() => document.createElement("base");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  BaseElement.created() : super.created();

  @DomName('HTMLBaseElement.href')
  @DocsEditable()
  String href;

  @DomName('HTMLBaseElement.target')
  @DocsEditable()
  String target;
}
// 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.


@DocsEditable()
@DomName('BeforeLoadEvent')
@Experimental()
class BeforeLoadEvent extends Event native "BeforeLoadEvent" {
  // To suppress missing implicit constructor warnings.
  factory BeforeLoadEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('BeforeLoadEvent.url')
  @DocsEditable()
  final String url;
}
// 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.


@DocsEditable()
@DomName('BeforeUnloadEvent')
class BeforeUnloadEvent extends Event native "BeforeUnloadEvent" {
  // To suppress missing implicit constructor warnings.
  factory BeforeUnloadEvent._() { throw new UnsupportedError("Not supported"); }

  // Shadowing definition.
  String get returnValue => JS("String", "#.returnValue", this);

  void set returnValue(String value) {
    JS("void", "#.returnValue = #", this, value);
  }
}
// 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.


@DomName('Blob')
class Blob extends Interceptor native "Blob" {
  // To suppress missing implicit constructor warnings.
  factory Blob._() { throw new UnsupportedError("Not supported"); }

  @DomName('Blob.size')
  @DocsEditable()
  final int size;

  @DomName('Blob.type')
  @DocsEditable()
  final String type;

  @DomName('Blob.slice')
  @DocsEditable()
  Blob slice([int start, int end, String contentType]) native;

  factory Blob(List blobParts, [String type, String endings]) {
    // TODO: validate that blobParts is a JS Array and convert if not.
    // TODO: any coercions on the elements of blobParts, e.g. coerce a typed
    // array to ArrayBuffer if it is a total view.
    if (type == null && endings == null) {
      return _create_1(blobParts);
    }
    var bag = _create_bag();
    if (type != null) _bag_set(bag, 'type', type);
    if (endings != null) _bag_set(bag, 'endings', endings);
    return _create_2(blobParts, bag);
  }

  static _create_1(parts) => JS('Blob', 'new Blob(#)', parts);
  static _create_2(parts, bag) => JS('Blob', 'new Blob(#, #)', parts, bag);

  static _create_bag() => JS('var', '{}');
  static _bag_set(bag, key, value) { JS('void', '#[#] = #', bag, key, value); }
}

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


@DocsEditable()
@DomName('HTMLBodyElement')
class BodyElement extends HtmlElement implements WindowEventHandlers native "HTMLBodyElement" {
  // To suppress missing implicit constructor warnings.
  factory BodyElement._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `blur` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLBodyElement.blurEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> blurEvent = const EventStreamProvider<Event>('blur');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLBodyElement.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `focus` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLBodyElement.focusEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> focusEvent = const EventStreamProvider<Event>('focus');

  /**
   * Static factory designed to expose `hashchange` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLBodyElement.hashchangeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> hashChangeEvent = const EventStreamProvider<Event>('hashchange');

  /**
   * Static factory designed to expose `load` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLBodyElement.loadEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> loadEvent = const EventStreamProvider<Event>('load');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLBodyElement.messageEvent')
  @DocsEditable()
  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');

  /**
   * Static factory designed to expose `offline` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLBodyElement.offlineEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> offlineEvent = const EventStreamProvider<Event>('offline');

  /**
   * Static factory designed to expose `online` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLBodyElement.onlineEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> onlineEvent = const EventStreamProvider<Event>('online');

  /**
   * Static factory designed to expose `popstate` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLBodyElement.popstateEvent')
  @DocsEditable()
  static const EventStreamProvider<PopStateEvent> popStateEvent = const EventStreamProvider<PopStateEvent>('popstate');

  /**
   * Static factory designed to expose `resize` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLBodyElement.resizeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> resizeEvent = const EventStreamProvider<Event>('resize');

  @DomName('HTMLBodyElement.scrollEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> scrollEvent = const EventStreamProvider<Event>('scroll');

  /**
   * Static factory designed to expose `storage` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLBodyElement.storageEvent')
  @DocsEditable()
  static const EventStreamProvider<StorageEvent> storageEvent = const EventStreamProvider<StorageEvent>('storage');

  /**
   * Static factory designed to expose `unload` events to event
   * handlers that are not necessarily instances of [BodyElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLBodyElement.unloadEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> unloadEvent = const EventStreamProvider<Event>('unload');

  @DomName('HTMLBodyElement.HTMLBodyElement')
  @DocsEditable()
  factory BodyElement() => document.createElement("body");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  BodyElement.created() : super.created();

  /// Stream of `blur` events handled by this [BodyElement].
  @DomName('HTMLBodyElement.onblur')
  @DocsEditable()
  ElementStream<Event> get onBlur => blurEvent.forElement(this);

  /// Stream of `error` events handled by this [BodyElement].
  @DomName('HTMLBodyElement.onerror')
  @DocsEditable()
  ElementStream<Event> get onError => errorEvent.forElement(this);

  /// Stream of `focus` events handled by this [BodyElement].
  @DomName('HTMLBodyElement.onfocus')
  @DocsEditable()
  ElementStream<Event> get onFocus => focusEvent.forElement(this);

  /// Stream of `hashchange` events handled by this [BodyElement].
  @DomName('HTMLBodyElement.onhashchange')
  @DocsEditable()
  ElementStream<Event> get onHashChange => hashChangeEvent.forElement(this);

  /// Stream of `load` events handled by this [BodyElement].
  @DomName('HTMLBodyElement.onload')
  @DocsEditable()
  ElementStream<Event> get onLoad => loadEvent.forElement(this);

  /// Stream of `message` events handled by this [BodyElement].
  @DomName('HTMLBodyElement.onmessage')
  @DocsEditable()
  ElementStream<MessageEvent> get onMessage => messageEvent.forElement(this);

  /// Stream of `offline` events handled by this [BodyElement].
  @DomName('HTMLBodyElement.onoffline')
  @DocsEditable()
  ElementStream<Event> get onOffline => offlineEvent.forElement(this);

  /// Stream of `online` events handled by this [BodyElement].
  @DomName('HTMLBodyElement.ononline')
  @DocsEditable()
  ElementStream<Event> get onOnline => onlineEvent.forElement(this);

  /// Stream of `popstate` events handled by this [BodyElement].
  @DomName('HTMLBodyElement.onpopstate')
  @DocsEditable()
  ElementStream<PopStateEvent> get onPopState => popStateEvent.forElement(this);

  /// Stream of `resize` events handled by this [BodyElement].
  @DomName('HTMLBodyElement.onresize')
  @DocsEditable()
  ElementStream<Event> get onResize => resizeEvent.forElement(this);

  @DomName('HTMLBodyElement.onscroll')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onScroll => scrollEvent.forElement(this);

  /// Stream of `storage` events handled by this [BodyElement].
  @DomName('HTMLBodyElement.onstorage')
  @DocsEditable()
  ElementStream<StorageEvent> get onStorage => storageEvent.forElement(this);

  /// Stream of `unload` events handled by this [BodyElement].
  @DomName('HTMLBodyElement.onunload')
  @DocsEditable()
  ElementStream<Event> get onUnload => unloadEvent.forElement(this);
}
// 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.


@DocsEditable()
@DomName('HTMLButtonElement')
class ButtonElement extends HtmlElement native "HTMLButtonElement" {
  // To suppress missing implicit constructor warnings.
  factory ButtonElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLButtonElement.HTMLButtonElement')
  @DocsEditable()
  factory ButtonElement() => document.createElement("button");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ButtonElement.created() : super.created();

  @DomName('HTMLButtonElement.autofocus')
  @DocsEditable()
  bool autofocus;

  @DomName('HTMLButtonElement.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('HTMLButtonElement.form')
  @DocsEditable()
  final FormElement form;

  @DomName('HTMLButtonElement.formAction')
  @DocsEditable()
  String formAction;

  @DomName('HTMLButtonElement.formEnctype')
  @DocsEditable()
  String formEnctype;

  @DomName('HTMLButtonElement.formMethod')
  @DocsEditable()
  String formMethod;

  @DomName('HTMLButtonElement.formNoValidate')
  @DocsEditable()
  bool formNoValidate;

  @DomName('HTMLButtonElement.formTarget')
  @DocsEditable()
  String formTarget;

  @DomName('HTMLButtonElement.labels')
  @DocsEditable()
  @Unstable()
  @Returns('NodeList')
  @Creates('NodeList')
  final List<Node> labels;

  @DomName('HTMLButtonElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLButtonElement.type')
  @DocsEditable()
  String type;

  @DomName('HTMLButtonElement.validationMessage')
  @DocsEditable()
  final String validationMessage;

  @DomName('HTMLButtonElement.validity')
  @DocsEditable()
  final ValidityState validity;

  @DomName('HTMLButtonElement.value')
  @DocsEditable()
  String value;

  @DomName('HTMLButtonElement.willValidate')
  @DocsEditable()
  final bool willValidate;

  @DomName('HTMLButtonElement.checkValidity')
  @DocsEditable()
  bool checkValidity() native;

  @DomName('HTMLButtonElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) native;
}
// 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.


@DocsEditable()
@DomName('CDATASection')
// http://dom.spec.whatwg.org/#cdatasection
@deprecated // deprecated
class CDataSection extends Text native "CDATASection" {
  // To suppress missing implicit constructor warnings.
  factory CDataSection._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('Canvas2DContextAttributes')
// http://wiki.whatwg.org/wiki/CanvasOpaque#Suggested_IDL
@Experimental()
class Canvas2DContextAttributes extends Interceptor native "Canvas2DContextAttributes" {
  // To suppress missing implicit constructor warnings.
  factory Canvas2DContextAttributes._() { throw new UnsupportedError("Not supported"); }

  @DomName('Canvas2DContextAttributes.alpha')
  @DocsEditable()
  bool alpha;
}
// 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.


@DomName('HTMLCanvasElement')
class CanvasElement extends HtmlElement implements CanvasImageSource native "HTMLCanvasElement" {
  // To suppress missing implicit constructor warnings.
  factory CanvasElement._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `webglcontextlost` events to event
   * handlers that are not necessarily instances of [CanvasElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLCanvasElement.webglcontextlostEvent')
  @DocsEditable()
  static const EventStreamProvider<gl.ContextEvent> webGlContextLostEvent = const EventStreamProvider<gl.ContextEvent>('webglcontextlost');

  /**
   * Static factory designed to expose `webglcontextrestored` events to event
   * handlers that are not necessarily instances of [CanvasElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLCanvasElement.webglcontextrestoredEvent')
  @DocsEditable()
  static const EventStreamProvider<gl.ContextEvent> webGlContextRestoredEvent = const EventStreamProvider<gl.ContextEvent>('webglcontextrestored');

  @DomName('HTMLCanvasElement.HTMLCanvasElement')
  @DocsEditable()
  factory CanvasElement({int width, int height}) {
    var e = document.createElement("canvas");
    if (width != null) e.width = width;
    if (height != null) e.height = height;
    return e;
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  CanvasElement.created() : super.created();

  /// The height of this canvas element in CSS pixels.
  @DomName('HTMLCanvasElement.height')
  @DocsEditable()
  int height;

  /// The width of this canvas element in CSS pixels.
  @DomName('HTMLCanvasElement.width')
  @DocsEditable()
  int width;

  @DomName('HTMLCanvasElement.getContext')
  @DocsEditable()
  CanvasRenderingContext getContext(String contextId, [Map attrs]) {
    if (attrs != null) {
      var attrs_1 = convertDartToNative_Dictionary(attrs);
      return _getContext_1(contextId, attrs_1);
    }
    return _getContext_2(contextId);
  }
  @JSName('getContext')
  @DomName('HTMLCanvasElement.getContext')
  @DocsEditable()
  CanvasRenderingContext _getContext_1(contextId, attrs) native;
  @JSName('getContext')
  @DomName('HTMLCanvasElement.getContext')
  @DocsEditable()
  CanvasRenderingContext _getContext_2(contextId) native;

  @JSName('toDataURL')
  @DomName('HTMLCanvasElement.toDataURL')
  @DocsEditable()
  String _toDataUrl(String type, [num quality]) native;

  /// Stream of `webglcontextlost` events handled by this [CanvasElement].
  @DomName('HTMLCanvasElement.onwebglcontextlost')
  @DocsEditable()
  ElementStream<gl.ContextEvent> get onWebGlContextLost => webGlContextLostEvent.forElement(this);

  /// Stream of `webglcontextrestored` events handled by this [CanvasElement].
  @DomName('HTMLCanvasElement.onwebglcontextrestored')
  @DocsEditable()
  ElementStream<gl.ContextEvent> get onWebGlContextRestored => webGlContextRestoredEvent.forElement(this);

  /** An API for drawing on this canvas. */
  CanvasRenderingContext2D get context2D =>
      JS('Null|CanvasRenderingContext2D', '#.getContext(#)', this, '2d');

  /**
   * Returns a new Web GL context for this canvas.
   *
   * ## Other resources
   *
   * * [WebGL fundamentals]
   * (http://www.html5rocks.com/en/tutorials/webgl/webgl_fundamentals/) from
   * HTML5Rocks.
   * * [WebGL homepage] (http://get.webgl.org/).
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @Experimental()
  gl.RenderingContext getContext3d({alpha: true, depth: true, stencil: false,
    antialias: true, premultipliedAlpha: true, preserveDrawingBuffer: false}) {

    var options = {
      'alpha': alpha,
      'depth': depth,
      'stencil': stencil,
      'antialias': antialias,
      'premultipliedAlpha': premultipliedAlpha,
      'preserveDrawingBuffer': preserveDrawingBuffer,
    };
    var context = getContext('webgl', options);
    if (context == null) {
      context = getContext('experimental-webgl', options);
    }
    return context;
  }

  /**
   * Returns a data URI containing a representation of the image in the
   * format specified by type (defaults to 'image/png').
   *
   * Data Uri format is as follow
   * `data:[<MIME-type>][;charset=<encoding>][;base64],<data>`
   *
   * Optional parameter [quality] in the range of 0.0 and 1.0 can be used when
   * requesting [type] 'image/jpeg' or 'image/webp'. If [quality] is not passed
   * the default value is used. Note: the default value varies by browser.
   *
   * If the height or width of this canvas element is 0, then 'data:' is
   * returned, representing no data.
   *
   * If the type requested is not 'image/png', and the returned value is
   * 'data:image/png', then the requested type is not supported.
   *
   * Example usage:
   *
   *     CanvasElement canvas = new CanvasElement();
   *     var ctx = canvas.context2D
   *     ..fillStyle = "rgb(200,0,0)"
   *     ..fillRect(10, 10, 55, 50);
   *     var dataUrl = canvas.toDataUrl("image/jpeg", 0.95);
   *     // The Data Uri would look similar to
   *     // 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
   *     // AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
   *     // 9TXL0Y4OHwAAAABJRU5ErkJggg=='
   *     //Create a new image element from the data URI.
   *     var img = new ImageElement();
   *     img.src = dataUrl;
   *     document.body.children.add(img);
   *
   * See also:
   *
   * * [Data URI Scheme](http://en.wikipedia.org/wiki/Data_URI_scheme) from Wikipedia.
   *
   * * [HTMLCanvasElement](https://developer.mozilla.org/en-US/docs/DOM/HTMLCanvasElement) from MDN.
   *
   * * [toDataUrl](http://dev.w3.org/html5/spec/the-canvas-element.html#dom-canvas-todataurl) from W3C.
   */
  String toDataUrl([String type = 'image/png', num quality]) =>
      _toDataUrl(type, quality);
}
// 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.


@DocsEditable()
/**
 * An opaque canvas object representing a gradient.
 *
 * Created by calling [createLinearGradient] or [createRadialGradient] on a
 * [CanvasRenderingContext2D] object.
 *
 * Example usage:
 *
 *     var canvas = new CanvasElement(width: 600, height: 600);
 *     var ctx = canvas.context2D;
 *     ctx.clearRect(0, 0, 600, 600);
 *     ctx.save();
 *     // Create radial gradient.
 *     CanvasGradient gradient = ctx.createRadialGradient(0, 0, 0, 0, 0, 600);
 *     gradient.addColorStop(0, '#000');
 *     gradient.addColorStop(1, 'rgb(255, 255, 255)');
 *     // Assign gradients to fill.
 *     ctx.fillStyle = gradient;
 *     // Draw a rectangle with a gradient fill.
 *     ctx.fillRect(0, 0, 600, 600);
 *     ctx.save();
 *     document.body.children.add(canvas);
 *
 * See also:
 *
 * * [CanvasGradient](https://developer.mozilla.org/en-US/docs/DOM/CanvasGradient) from MDN.
 * * [CanvasGradient](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvasgradient) from whatwg.
 * * [CanvasGradient](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvasgradient) from W3C.
 */
@DomName('CanvasGradient')
class CanvasGradient extends Interceptor native "CanvasGradient" {
  // To suppress missing implicit constructor warnings.
  factory CanvasGradient._() { throw new UnsupportedError("Not supported"); }

  /**
   * Adds a color stop to this gradient at the offset.
   *
   * The [offset] can range between 0.0 and 1.0.
   *
   * See also:
   *
   * * [Multiple Color Stops](https://developer.mozilla.org/en-US/docs/CSS/linear-gradient#Gradient_with_multiple_color_stops) from MDN.
   */
  @DomName('CanvasGradient.addColorStop')
  @DocsEditable()
  void addColorStop(num offset, String color) native;
}
// 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.


@DocsEditable()
/**
 * An opaque object representing a pattern of image, canvas, or video.
 *
 * Created by calling [createPattern] on a [CanvasRenderingContext2D] object.
 *
 * Example usage:
 *
 *     var canvas = new CanvasElement(width: 600, height: 600);
 *     var ctx = canvas.context2D;
 *     var img = new ImageElement();
 *     // Image src needs to be loaded before pattern is applied.
 *     img.onLoad.listen((event) {
 *       // When the image is loaded, create a pattern
 *       // from the ImageElement.
 *       CanvasPattern pattern = ctx.createPattern(img, 'repeat');
 *       ctx.rect(0, 0, canvas.width, canvas.height);
 *       ctx.fillStyle = pattern;
 *       ctx.fill();
 *     });
 *     img.src = "images/foo.jpg";
 *     document.body.children.add(canvas);
 *
 * See also:
 * * [CanvasPattern](https://developer.mozilla.org/en-US/docs/DOM/CanvasPattern) from MDN.
 * * [CanvasPattern](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvaspattern) from whatwg.
 * * [CanvasPattern](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvaspattern) from W3C.
 */
@DomName('CanvasPattern')
class CanvasPattern extends Interceptor native "CanvasPattern" {
  // To suppress missing implicit constructor warnings.
  factory CanvasPattern._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
/**
 * A rendering context for a canvas element.
 *
 * This context is extended by [CanvasRenderingContext2D] and
 * [WebGLRenderingContext].
 */
@DomName('CanvasRenderingContext')
class CanvasRenderingContext extends Interceptor native "CanvasRenderingContext" {
  // To suppress missing implicit constructor warnings.
  factory CanvasRenderingContext._() { throw new UnsupportedError("Not supported"); }

  /// Reference to the canvas element to which this context belongs.
  @DomName('CanvasRenderingContext.canvas')
  @DocsEditable()
  final CanvasElement canvas;
}
// 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.


@DomName('CanvasRenderingContext2D')
class CanvasRenderingContext2D extends CanvasRenderingContext native "CanvasRenderingContext2D" {
  // To suppress missing implicit constructor warnings.
  factory CanvasRenderingContext2D._() { throw new UnsupportedError("Not supported"); }

  /**
   * The current default path of this canvas context, if there is one.
   *
   * ## Other resources
   *
   * * [Current default path]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#current-default-path)
   * from WHATWG.
   */
  @DomName('CanvasRenderingContext2D.currentPath')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#path-objects
  @Experimental()
  Path currentPath;

  @DomName('CanvasRenderingContext2D.currentTransform')
  @DocsEditable()
  @Experimental() // untriaged
  Matrix currentTransform;

  @DomName('CanvasRenderingContext2D.fillStyle')
  @DocsEditable()
  @Creates('String|CanvasGradient|CanvasPattern')
  @Returns('String|CanvasGradient|CanvasPattern')
  Object fillStyle;

  @DomName('CanvasRenderingContext2D.font')
  @DocsEditable()
  String font;

  @DomName('CanvasRenderingContext2D.globalAlpha')
  @DocsEditable()
  num globalAlpha;

  @DomName('CanvasRenderingContext2D.globalCompositeOperation')
  @DocsEditable()
  String globalCompositeOperation;

  /**
   * Whether images and patterns on this canvas will be smoothed when this
   * canvas is scaled.
   *
   * ## Other resources
   *
   * * [Image smoothing]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#image-smoothing)
   * from WHATWG.
   */
  @DomName('CanvasRenderingContext2D.imageSmoothingEnabled')
  @DocsEditable()
  @Experimental() // untriaged
  bool imageSmoothingEnabled;

  @DomName('CanvasRenderingContext2D.lineCap')
  @DocsEditable()
  String lineCap;

  @DomName('CanvasRenderingContext2D.lineJoin')
  @DocsEditable()
  String lineJoin;

  @DomName('CanvasRenderingContext2D.lineWidth')
  @DocsEditable()
  num lineWidth;

  @DomName('CanvasRenderingContext2D.miterLimit')
  @DocsEditable()
  num miterLimit;

  @DomName('CanvasRenderingContext2D.shadowBlur')
  @DocsEditable()
  num shadowBlur;

  @DomName('CanvasRenderingContext2D.shadowColor')
  @DocsEditable()
  String shadowColor;

  @DomName('CanvasRenderingContext2D.shadowOffsetX')
  @DocsEditable()
  num shadowOffsetX;

  @DomName('CanvasRenderingContext2D.shadowOffsetY')
  @DocsEditable()
  num shadowOffsetY;

  @DomName('CanvasRenderingContext2D.strokeStyle')
  @DocsEditable()
  @Creates('String|CanvasGradient|CanvasPattern')
  @Returns('String|CanvasGradient|CanvasPattern')
  Object strokeStyle;

  @DomName('CanvasRenderingContext2D.textAlign')
  @DocsEditable()
  String textAlign;

  @DomName('CanvasRenderingContext2D.textBaseline')
  @DocsEditable()
  String textBaseline;

  @JSName('webkitBackingStorePixelRatio')
  /**
   * The ratio between this canvas' backing store dimensions and the canvas'
   * logical dimensions.
   *
   * ## Other resources
   *
   * * [High DPI Canvas tutorial]
   * (http://www.html5rocks.com/en/tutorials/canvas/hidpi/) from HTML5Rocks.
   */
  @DomName('CanvasRenderingContext2D.webkitBackingStorePixelRatio')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  final double backingStorePixelRatio;

  @JSName('arc')
  @DomName('CanvasRenderingContext2D.arc')
  @DocsEditable()
  void _arc(num x, num y, num radius, num startAngle, num endAngle, bool anticlockwise) native;

  @DomName('CanvasRenderingContext2D.arcTo')
  @DocsEditable()
  void arcTo(num x1, num y1, num x2, num y2, num radius) native;

  @DomName('CanvasRenderingContext2D.beginPath')
  @DocsEditable()
  void beginPath() native;

  @DomName('CanvasRenderingContext2D.bezierCurveTo')
  @DocsEditable()
  void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y, num x, num y) native;

  @DomName('CanvasRenderingContext2D.clearRect')
  @DocsEditable()
  void clearRect(num x, num y, num width, num height) native;

  @DomName('CanvasRenderingContext2D.clip')
  @DocsEditable()
  void clip([String winding]) native;

  @DomName('CanvasRenderingContext2D.closePath')
  @DocsEditable()
  void closePath() native;

  @DomName('CanvasRenderingContext2D.createImageData')
  @DocsEditable()
  @Creates('ImageData|=Object')
  ImageData createImageData(num sw, num sh) {
    return convertNativeToDart_ImageData(_createImageData_1(sw, sh));
  }
  @JSName('createImageData')
  @DomName('CanvasRenderingContext2D.createImageData')
  @DocsEditable()
  @Creates('ImageData|=Object')
  _createImageData_1(sw, sh) native;

  @DomName('CanvasRenderingContext2D.createImageData')
  @DocsEditable()
  @Creates('ImageData|=Object')
  ImageData createImageDataFromImageData(ImageData imagedata) {
    var imagedata_1 = convertDartToNative_ImageData(imagedata);
    return convertNativeToDart_ImageData(_createImageDataFromImageData_1(imagedata_1));
  }
  @JSName('createImageData')
  @DomName('CanvasRenderingContext2D.createImageData')
  @DocsEditable()
  @Creates('ImageData|=Object')
  _createImageDataFromImageData_1(imagedata) native;

  @DomName('CanvasRenderingContext2D.createLinearGradient')
  @DocsEditable()
  CanvasGradient createLinearGradient(num x0, num y0, num x1, num y1) native;

  @DomName('CanvasRenderingContext2D.createPattern')
  @DocsEditable()
  CanvasPattern createPattern(CanvasElement canvas, String repetitionType) native;

  @JSName('createPattern')
  @DomName('CanvasRenderingContext2D.createPattern')
  @DocsEditable()
  CanvasPattern createPatternFromImage(ImageElement image, String repetitionType) native;

  @DomName('CanvasRenderingContext2D.createRadialGradient')
  @DocsEditable()
  CanvasGradient createRadialGradient(num x0, num y0, num r0, num x1, num y1, num r1) native;

  @DomName('CanvasRenderingContext2D.drawCustomFocusRing')
  @DocsEditable()
  @Experimental() // untriaged
  bool drawCustomFocusRing(Element element) native;

  @DomName('CanvasRenderingContext2D.ellipse')
  @DocsEditable()
  @Experimental() // untriaged
  void ellipse(num x, num y, num radiusX, num radiusY, num rotation, num startAngle, num endAngle, bool anticlockwise) native;

  @DomName('CanvasRenderingContext2D.fillRect')
  @DocsEditable()
  void fillRect(num x, num y, num width, num height) native;

  @DomName('CanvasRenderingContext2D.getContextAttributes')
  @DocsEditable()
  // http://wiki.whatwg.org/wiki/CanvasOpaque#Suggested_IDL
  @Experimental()
  Canvas2DContextAttributes getContextAttributes() native;

  @DomName('CanvasRenderingContext2D.getImageData')
  @DocsEditable()
  @Creates('ImageData|=Object')
  ImageData getImageData(num sx, num sy, num sw, num sh) {
    return convertNativeToDart_ImageData(_getImageData_1(sx, sy, sw, sh));
  }
  @JSName('getImageData')
  @DomName('CanvasRenderingContext2D.getImageData')
  @DocsEditable()
  @Creates('ImageData|=Object')
  _getImageData_1(sx, sy, sw, sh) native;

  @JSName('getLineDash')
  @DomName('CanvasRenderingContext2D.getLineDash')
  @DocsEditable()
  List<num> _getLineDash() native;

  @DomName('CanvasRenderingContext2D.isPointInPath')
  @DocsEditable()
  bool isPointInPath(num x, num y, [String winding]) native;

  @DomName('CanvasRenderingContext2D.isPointInStroke')
  @DocsEditable()
  bool isPointInStroke(num x, num y) native;

  @DomName('CanvasRenderingContext2D.lineTo')
  @DocsEditable()
  void lineTo(num x, num y) native;

  @DomName('CanvasRenderingContext2D.measureText')
  @DocsEditable()
  TextMetrics measureText(String text) native;

  @DomName('CanvasRenderingContext2D.moveTo')
  @DocsEditable()
  void moveTo(num x, num y) native;

  @DomName('CanvasRenderingContext2D.putImageData')
  @DocsEditable()
  void putImageData(ImageData imagedata, num dx, num dy, [num dirtyX, num dirtyY, num dirtyWidth, num dirtyHeight]) {
    if (dirtyX == null && dirtyY == null && dirtyWidth == null && dirtyHeight == null) {
      var imagedata_1 = convertDartToNative_ImageData(imagedata);
      _putImageData_1(imagedata_1, dx, dy);
      return;
    }
    if (dirtyHeight != null && dirtyWidth != null && dirtyY != null && dirtyX != null) {
      var imagedata_2 = convertDartToNative_ImageData(imagedata);
      _putImageData_2(imagedata_2, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  @JSName('putImageData')
  @DomName('CanvasRenderingContext2D.putImageData')
  @DocsEditable()
  void _putImageData_1(imagedata, dx, dy) native;
  @JSName('putImageData')
  @DomName('CanvasRenderingContext2D.putImageData')
  @DocsEditable()
  void _putImageData_2(imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight) native;

  @DomName('CanvasRenderingContext2D.quadraticCurveTo')
  @DocsEditable()
  void quadraticCurveTo(num cpx, num cpy, num x, num y) native;

  @DomName('CanvasRenderingContext2D.rect')
  @DocsEditable()
  void rect(num x, num y, num width, num height) native;

  @DomName('CanvasRenderingContext2D.resetTransform')
  @DocsEditable()
  @Experimental() // untriaged
  void resetTransform() native;

  @DomName('CanvasRenderingContext2D.restore')
  @DocsEditable()
  void restore() native;

  @DomName('CanvasRenderingContext2D.rotate')
  @DocsEditable()
  void rotate(num angle) native;

  @DomName('CanvasRenderingContext2D.save')
  @DocsEditable()
  void save() native;

  @DomName('CanvasRenderingContext2D.scale')
  @DocsEditable()
  void scale(num sx, num sy) native;

  @DomName('CanvasRenderingContext2D.setTransform')
  @DocsEditable()
  void setTransform(num m11, num m12, num m21, num m22, num dx, num dy) native;

  @DomName('CanvasRenderingContext2D.stroke')
  @DocsEditable()
  void stroke() native;

  @DomName('CanvasRenderingContext2D.strokeRect')
  @DocsEditable()
  void strokeRect(num x, num y, num width, num height) native;

  @DomName('CanvasRenderingContext2D.strokeText')
  @DocsEditable()
  void strokeText(String text, num x, num y, [num maxWidth]) native;

  @DomName('CanvasRenderingContext2D.transform')
  @DocsEditable()
  void transform(num m11, num m12, num m21, num m22, num dx, num dy) native;

  @DomName('CanvasRenderingContext2D.translate')
  @DocsEditable()
  void translate(num tx, num ty) native;

  @DomName('CanvasRenderingContext2D.webkitGetImageDataHD')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Creates('ImageData|=Object')
  ImageData getImageDataHD(num sx, num sy, num sw, num sh) {
    return convertNativeToDart_ImageData(_getImageDataHD_1(sx, sy, sw, sh));
  }
  @JSName('webkitGetImageDataHD')
  @DomName('CanvasRenderingContext2D.webkitGetImageDataHD')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Creates('ImageData|=Object')
  _getImageDataHD_1(sx, sy, sw, sh) native;

  @DomName('CanvasRenderingContext2D.webkitPutImageDataHD')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  void putImageDataHD(ImageData imagedata, num dx, num dy, [num dirtyX, num dirtyY, num dirtyWidth, num dirtyHeight]) {
    if (dirtyX == null && dirtyY == null && dirtyWidth == null && dirtyHeight == null) {
      var imagedata_1 = convertDartToNative_ImageData(imagedata);
      _putImageDataHD_1(imagedata_1, dx, dy);
      return;
    }
    if (dirtyHeight != null && dirtyWidth != null && dirtyY != null && dirtyX != null) {
      var imagedata_2 = convertDartToNative_ImageData(imagedata);
      _putImageDataHD_2(imagedata_2, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  @JSName('webkitPutImageDataHD')
  @DomName('CanvasRenderingContext2D.webkitPutImageDataHD')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  void _putImageDataHD_1(imagedata, dx, dy) native;
  @JSName('webkitPutImageDataHD')
  @DomName('CanvasRenderingContext2D.webkitPutImageDataHD')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  void _putImageDataHD_2(imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight) native;


  /**
   * Sets the color used inside shapes.
   * [r], [g], [b] are 0-255, [a] is 0-1.
   */
  void setFillColorRgb(int r, int g, int b, [num a = 1]) {
    this.fillStyle = 'rgba($r, $g, $b, $a)';
  }

  /**
   * Sets the color used inside shapes.
   * [h] is in degrees, 0-360.
   * [s], [l] are in percent, 0-100.
   * [a] is 0-1.
   */
  void setFillColorHsl(int h, num s, num l, [num a = 1]) {
    this.fillStyle = 'hsla($h, $s%, $l%, $a)';
  }

  /**
   * Sets the color used for stroking shapes.
   * [r], [g], [b] are 0-255, [a] is 0-1.
   */
  void setStrokeColorRgb(int r, int g, int b, [num a = 1]) {
    this.strokeStyle = 'rgba($r, $g, $b, $a)';
  }

  /**
   * Sets the color used for stroking shapes.
   * [h] is in degrees, 0-360.
   * [s], [l] are in percent, 0-100.
   * [a] is 0-1.
   */
  void setStrokeColorHsl(int h, num s, num l, [num a = 1]) {
    this.strokeStyle = 'hsla($h, $s%, $l%, $a)';
  }

  @DomName('CanvasRenderingContext2D.arc')
  void arc(num x,  num y,  num radius,  num startAngle, num endAngle,
      [bool anticlockwise = false]) {
    _arc(x, y, radius, startAngle, endAngle, anticlockwise);
  }

  /**
   * Draws an image from a CanvasImageSource to an area of this canvas.
   *
   * The image will be drawn to an area of this canvas defined by
   * [destRect]. [sourceRect] defines the region of the source image that is
   * drawn.
   * If [sourceRect] is not provided, then
   * the entire rectangular image from [source] will be drawn to this context.
   *
   * If the image is larger than canvas
   * will allow, the image will be clipped to fit the available space.
   *
   *     CanvasElement canvas = new CanvasElement(width: 600, height: 600);
   *     CanvasRenderingContext2D ctx = canvas.context2D;
   *     ImageElement img = document.query('img');
   *     img.width = 100;
   *     img.height = 100;
   *
   *     // Scale the image to 20x20.
   *     ctx.drawImageToRect(img, new Rectangle(50, 50, 20, 20));
   *
   *     VideoElement video = document.query('video');
   *     video.width = 100;
   *     video.height = 100;
   *     // Take the middle 20x20 pixels from the video and stretch them.
   *     ctx.drawImageToRect(video, new Rectangle(50, 50, 100, 100),
   *         sourceRect: new Rectangle(40, 40, 20, 20));
   *
   *     // Draw the top 100x20 pixels from the otherCanvas.
   *     CanvasElement otherCanvas = document.query('canvas');
   *     ctx.drawImageToRect(otherCanvas, new Rectangle(0, 0, 100, 20),
   *         sourceRect: new Rectangle(0, 0, 100, 20));
   *
   * See also:
   *
   *   * [CanvasImageSource] for more information on what data is retrieved
   * from [source].
   *   * [drawImage](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
   * from the WHATWG.
   */
  @DomName('CanvasRenderingContext2D.drawImage')
  void drawImageToRect(CanvasImageSource source, Rectangle destRect,
      {Rectangle sourceRect}) {
    if (sourceRect == null) {
      drawImageScaled(source,
          destRect.left,
          destRect.top,
          destRect.width,
          destRect.height);
    } else {
      drawImageScaledFromSource(source,
          sourceRect.left,
          sourceRect.top,
          sourceRect.width,
          sourceRect.height,
          destRect.left,
          destRect.top,
          destRect.width,
          destRect.height);
    }
  }

  /**
   * Draws an image from a CanvasImageSource to this canvas.
   *
   * The entire image from [source] will be drawn to this context with its top
   * left corner at the point ([destX], [destY]). If the image is
   * larger than canvas will allow, the image will be clipped to fit the
   * available space.
   *
   *     CanvasElement canvas = new CanvasElement(width: 600, height: 600);
   *     CanvasRenderingContext2D ctx = canvas.context2D;
   *     ImageElement img = document.query('img');
   *
   *     ctx.drawImage(img, 100, 100);
   *
   *     VideoElement video = document.query('video');
   *     ctx.drawImage(video, 0, 0);
   *
   *     CanvasElement otherCanvas = document.query('canvas');
   *     otherCanvas.width = 100;
   *     otherCanvas.height = 100;
   *     ctx.drawImage(otherCanvas, 590, 590); // will get clipped
   *
   * See also:
   *
   *   * [CanvasImageSource] for more information on what data is retrieved
   * from [source].
   *   * [drawImage](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
   * from the WHATWG.
   */
  @DomName('CanvasRenderingContext2D.drawImage')
  @JSName('drawImage')
  void drawImage(CanvasImageSource source, num destX, num destY) native;

  /**
   * Draws an image from a CanvasImageSource to an area of this canvas.
   *
   * The image will be drawn to this context with its top left corner at the
   * point ([destX], [destY]) and will be scaled to be [destWidth] wide and
   * [destHeight] tall.
   *
   * If the image is larger than canvas
   * will allow, the image will be clipped to fit the available space.
   *
   *     CanvasElement canvas = new CanvasElement(width: 600, height: 600);
   *     CanvasRenderingContext2D ctx = canvas.context2D;
   *     ImageElement img = document.query('img');
   *     img.width = 100;
   *     img.height = 100;
   *
   *     // Scale the image to 300x50 at the point (20, 20)
   *     ctx.drawImageScaled(img, 20, 20, 300, 50);
   *
   * See also:
   *
   *   * [CanvasImageSource] for more information on what data is retrieved
   * from [source].
   *   * [drawImage](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
   * from the WHATWG.
   */
  @DomName('CanvasRenderingContext2D.drawImage')
  @JSName('drawImage')
  void drawImageScaled(CanvasImageSource source,
      num destX, num destY, num destWidth, num destHeight) native;

  /**
   * Draws an image from a CanvasImageSource to an area of this canvas.
   *
   * The image is a region of [source] that is [sourceWidth] wide and
   * [destHeight] tall with top left corner at ([sourceX], [sourceY]).
   * The image will be drawn to this context with its top left corner at the
   * point ([destX], [destY]) and will be scaled to be [destWidth] wide and
   * [destHeight] tall.
   *
   * If the image is larger than canvas
   * will allow, the image will be clipped to fit the available space.
   *
   *     VideoElement video = document.query('video');
   *     video.width = 100;
   *     video.height = 100;
   *     // Take the middle 20x20 pixels from the video and stretch them.
   *     ctx.drawImageScaledFromSource(video, 40, 40, 20, 20, 50, 50, 100, 100);
   *
   *     // Draw the top 100x20 pixels from the otherCanvas to this one.
   *     CanvasElement otherCanvas = document.query('canvas');
   *     ctx.drawImageScaledFromSource(otherCanvas, 0, 0, 100, 20, 0, 0, 100, 20);
   *
   * See also:
   *
   *   * [CanvasImageSource] for more information on what data is retrieved
   * from [source].
   *   * [drawImage](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
   * from the WHATWG.
   */
  @DomName('CanvasRenderingContext2D.drawImage')
  @JSName('drawImage')
  void drawImageScaledFromSource(CanvasImageSource source,
      num sourceX, num sourceY, num sourceWidth, num sourceHeight,
      num destX, num destY, num destWidth, num destHeight) native;

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @SupportedBrowser(SupportedBrowser.IE, '11')
  @Unstable()
  @DomName('CanvasRenderingContext2D.lineDashOffset')
  // TODO(14316): Firefox has this functionality with mozDashOffset, but it
  // needs to be polyfilled.
  num get lineDashOffset => JS('num',
      '#.lineDashOffset || #.webkitLineDashOffset', this, this);

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @SupportedBrowser(SupportedBrowser.IE, '11')
  @Unstable()
  @DomName('CanvasRenderingContext2D.lineDashOffset')
  // TODO(14316): Firefox has this functionality with mozDashOffset, but it
  // needs to be polyfilled.
  void set lineDashOffset(num value) => JS('void',
      'typeof #.lineDashOffset != "undefined" ? #.lineDashOffset = # : '
      '#.webkitLineDashOffset = #', this, this, value, this, value);

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @SupportedBrowser(SupportedBrowser.IE, '11')
  @Unstable()
  @DomName('CanvasRenderingContext2D.getLineDash')
  List<num> getLineDash() {
    // TODO(14316): Firefox has this functionality with mozDash, but it's a bit
    // different.
    if (JS('bool', '!!#.getLineDash', this)) {
      return JS('List<num>', '#.getLineDash()', this);
    } else if (JS('bool', '!!#.webkitLineDash', this)) {
      return JS('List<num>', '#.webkitLineDash', this);
    } 
  }

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @SupportedBrowser(SupportedBrowser.IE, '11')
  @Unstable()
  @DomName('CanvasRenderingContext2D.setLineDash')
  void setLineDash(List<num> dash) {
    // TODO(14316): Firefox has this functionality with mozDash, but it's a bit
    // different.
    if (JS('bool', '!!#.setLineDash', this)) {
      JS('void', '#.setLineDash(#)', this, dash);
    } else if (JS('bool', '!!#.webkitLineDash', this)) {
      JS('void', '#.webkitLineDash = #', this, dash);
    }
  }


  /**
   * Draws text to the canvas.
   *
   * The text is drawn starting at coordinates ([x], [y]).
   * If [maxWidth] is provided and the [text] is computed to be wider than
   * [maxWidth], then the drawn text is scaled down horizontally to fit.
   *
   * The text uses the current [CanvasRenderingContext2D.font] property for font
   * options, such as typeface and size, and the current
   * [CanvasRenderingContext2D.fillStyle] for style options such as color.
   * The current [CanvasRenderingContext2D.textAlign] and
   * [CanvasRenderingContext2D.textBaseLine] properties are also applied to the
   * drawn text.
   */
  @DomName('CanvasRenderingContext2D.fillText')
  void fillText(String text, num x, num y, [num maxWidth]) {
    if (maxWidth != null) {
      JS('void', '#.fillText(#, #, #, #)', this, text, x, y, maxWidth);
    } else {
      JS('void', '#.fillText(#, #, #)', this, text, x, y);
    }
  }

  @DomName('CanvasRenderingContext2D.fill')
  void fill([String winding = 'nonzero']) {
    JS('void', '#.fill(#)', this, winding);
  }
}

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


@DocsEditable()
@DomName('CharacterData')
class CharacterData extends Node implements ChildNode native "CharacterData" {
  // To suppress missing implicit constructor warnings.
  factory CharacterData._() { throw new UnsupportedError("Not supported"); }

  @DomName('CharacterData.data')
  @DocsEditable()
  String data;

  @DomName('CharacterData.length')
  @DocsEditable()
  final int length;

  @DomName('CharacterData.appendData')
  @DocsEditable()
  void appendData(String data) native;

  @DomName('CharacterData.deleteData')
  @DocsEditable()
  void deleteData(int offset, int length) native;

  @DomName('CharacterData.insertData')
  @DocsEditable()
  void insertData(int offset, String data) native;

  @DomName('CharacterData.replaceData')
  @DocsEditable()
  void replaceData(int offset, int length, String data) native;

  @DomName('CharacterData.substringData')
  @DocsEditable()
  String substringData(int offset, int length) native;

  // From ChildNode

  @DomName('CharacterData.nextElementSibling')
  @DocsEditable()
  final Element nextElementSibling;

  @DomName('CharacterData.previousElementSibling')
  @DocsEditable()
  final Element previousElementSibling;
}
// 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.


@DocsEditable()
@DomName('ChildNode')
@Experimental() // untriaged
abstract class ChildNode extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ChildNode._() { throw new UnsupportedError("Not supported"); }

  final Element nextElementSibling;

  final Element previousElementSibling;

  void remove();
}
// 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.


@DocsEditable()
@DomName('CloseEvent')
class CloseEvent extends Event native "CloseEvent" {
  // To suppress missing implicit constructor warnings.
  factory CloseEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('CloseEvent.code')
  @DocsEditable()
  final int code;

  @DomName('CloseEvent.reason')
  @DocsEditable()
  final String reason;

  @DomName('CloseEvent.wasClean')
  @DocsEditable()
  final bool wasClean;
}
// 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.


@DocsEditable()
@DomName('Comment')
class Comment extends CharacterData native "Comment" {
  factory Comment([String data]) {
    if (data != null) {
      return JS('Comment', '#.createComment(#)', document, data);
    }
    return JS('Comment', '#.createComment("")', document);
  }
  // To suppress missing implicit constructor warnings.
  factory Comment._() { throw new UnsupportedError("Not supported"); }
}
// 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.

// WARNING: Do not edit - generated code.


@DomName('CompositionEvent')
class CompositionEvent extends UIEvent native "CompositionEvent" {
  factory CompositionEvent(String type,
      {bool canBubble: false, bool cancelable: false, Window view,
      String data}) {
    if (view == null) {
      view = window;
    }
    var e = document._createEvent("CompositionEvent");
    e._initCompositionEvent(type, canBubble, cancelable, view, data);
    return e;
  }
  // To suppress missing implicit constructor warnings.
  factory CompositionEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('CompositionEvent.activeSegmentEnd')
  @DocsEditable()
  @Experimental() // untriaged
  final int activeSegmentEnd;

  @DomName('CompositionEvent.activeSegmentStart')
  @DocsEditable()
  @Experimental() // untriaged
  final int activeSegmentStart;

  @DomName('CompositionEvent.data')
  @DocsEditable()
  final String data;

  @JSName('initCompositionEvent')
  @DomName('CompositionEvent.initCompositionEvent')
  @DocsEditable()
  void _initCompositionEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Window viewArg, String dataArg) native;

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


@DomName('Console')
class Console {

  const Console._safe();

  static const Console _safeConsole = const Console._safe();

  bool get _isConsoleDefined => JS('bool', 'typeof console != "undefined"');

  @DomName('Console.memory')
  MemoryInfo get memory => _isConsoleDefined ?
      JS('MemoryInfo', 'console.memory') : null;

  @DomName('Console.assertCondition')
  void assertCondition(bool condition, Object arg) => _isConsoleDefined ?
      JS('void', 'console.assertCondition(#, #)', condition, arg) : null;

  @DomName('Console.clear')
  void clear(Object arg) => _isConsoleDefined ?
      JS('void', 'console.clear(#)', arg) : null;

  @DomName('Console.count')
  void count(Object arg) => _isConsoleDefined ?
      JS('void', 'console.count(#)', arg) : null;

  @DomName('Console.debug')
  void debug(Object arg) => _isConsoleDefined ?
      JS('void', 'console.debug(#)', arg) : null;

  @DomName('Console.dir')
  void dir(Object arg) => _isConsoleDefined ?
      JS('void', 'console.dir(#)', arg) : null;

  @DomName('Console.dirxml')
  void dirxml(Object arg) => _isConsoleDefined ?
      JS('void', 'console.dirxml(#)', arg) : null;

  @DomName('Console.error')
  void error(Object arg) => _isConsoleDefined ?
      JS('void', 'console.error(#)', arg) : null;

  @DomName('Console.group')
  void group(Object arg) => _isConsoleDefined ?
      JS('void', 'console.group(#)', arg) : null;

  @DomName('Console.groupCollapsed')
  void groupCollapsed(Object arg) => _isConsoleDefined ?
      JS('void', 'console.groupCollapsed(#)', arg) : null;

  @DomName('Console.groupEnd')
  void groupEnd() => _isConsoleDefined ?
      JS('void', 'console.groupEnd()') : null;

  @DomName('Console.info')
  void info(Object arg) => _isConsoleDefined ?
      JS('void', 'console.info(#)', arg) : null;

  @DomName('Console.log')
  void log(Object arg) => _isConsoleDefined ?
      JS('void', 'console.log(#)', arg) : null;

  @DomName('Console.markTimeline')
  void markTimeline(Object arg) => _isConsoleDefined ?
      JS('void', 'console.markTimeline(#)', arg) : null;

  @DomName('Console.profile')
  void profile(String title) => _isConsoleDefined ?
      JS('void', 'console.profile(#)', title) : null;

  @DomName('Console.profileEnd')
  void profileEnd(String title) => _isConsoleDefined ?
      JS('void', 'console.profileEnd(#)', title) : null;

  @DomName('Console.table')
  void table(Object arg) => _isConsoleDefined ?
      JS('void', 'console.table(#)', arg) : null;

  @DomName('Console.time')
  void time(String title) => _isConsoleDefined ?
      JS('void', 'console.time(#)', title) : null;

  @DomName('Console.timeEnd')
  void timeEnd(String title) => _isConsoleDefined ?
      JS('void', 'console.timeEnd(#)', title) : null;

  @DomName('Console.timeStamp')
  void timeStamp(Object arg) => _isConsoleDefined ?
      JS('void', 'console.timeStamp(#)', arg) : null;

  @DomName('Console.trace')
  void trace(Object arg) => _isConsoleDefined ?
      JS('void', 'console.trace(#)', arg) : null;

  @DomName('Console.warn')
  void warn(Object arg) => _isConsoleDefined ?
      JS('void', 'console.warn(#)', arg) : null;
  // To suppress missing implicit constructor warnings.
  factory Console._() { throw new UnsupportedError("Not supported"); }

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


@DocsEditable()
@DomName('ConsoleBase')
@Experimental() // untriaged
class ConsoleBase extends Interceptor native "ConsoleBase" {
  // To suppress missing implicit constructor warnings.
  factory ConsoleBase._() { throw new UnsupportedError("Not supported"); }

  @DomName('ConsoleBase.timeline')
  @DocsEditable()
  @Experimental() // untriaged
  void timeline(String title) native;

  @DomName('ConsoleBase.timelineEnd')
  @DocsEditable()
  @Experimental() // untriaged
  void timelineEnd(String title) native;
}
// 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.


@DocsEditable()
@DomName('HTMLContentElement')
@SupportedBrowser(SupportedBrowser.CHROME, '26')
@Experimental()
// https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#content-element
class ContentElement extends HtmlElement native "HTMLContentElement" {
  // To suppress missing implicit constructor warnings.
  factory ContentElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLContentElement.HTMLContentElement')
  @DocsEditable()
  factory ContentElement() => document.createElement("content");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ContentElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('content');

  @DomName('HTMLContentElement.resetStyleInheritance')
  @DocsEditable()
  bool resetStyleInheritance;

  @DomName('HTMLContentElement.select')
  @DocsEditable()
  String select;

  @DomName('HTMLContentElement.getDistributedNodes')
  @DocsEditable()
  @Returns('NodeList')
  @Creates('NodeList')
  List<Node> getDistributedNodes() native;
}
// 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.


@DocsEditable()
@DomName('Coordinates')
class Coordinates extends Interceptor native "Coordinates" {
  // To suppress missing implicit constructor warnings.
  factory Coordinates._() { throw new UnsupportedError("Not supported"); }

  @DomName('Coordinates.accuracy')
  @DocsEditable()
  final double accuracy;

  @DomName('Coordinates.altitude')
  @DocsEditable()
  final double altitude;

  @DomName('Coordinates.altitudeAccuracy')
  @DocsEditable()
  final double altitudeAccuracy;

  @DomName('Coordinates.heading')
  @DocsEditable()
  final double heading;

  @DomName('Coordinates.latitude')
  @DocsEditable()
  final double latitude;

  @DomName('Coordinates.longitude')
  @DocsEditable()
  final double longitude;

  @DomName('Coordinates.speed')
  @DocsEditable()
  final double speed;
}
// 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.


@DocsEditable()
@DomName('Crypto')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
// http://www.w3.org/TR/WebCryptoAPI/
class Crypto extends Interceptor native "Crypto" {
  // To suppress missing implicit constructor warnings.
  factory Crypto._() { throw new UnsupportedError("Not supported"); }

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.crypto && window.crypto.getRandomValues)');

  @DomName('Crypto.subtle')
  @DocsEditable()
  @Experimental() // untriaged
  final _SubtleCrypto subtle;

  @DomName('Crypto.getRandomValues')
  @DocsEditable()
  @Creates('TypedData')
  @Returns('TypedData|Null')
  TypedData getRandomValues(TypedData array) native;
}
// 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.


@DocsEditable()
@DomName('Key')
@Experimental() // untriaged
class CryptoKey extends Interceptor native "Key" {
  // To suppress missing implicit constructor warnings.
  factory CryptoKey._() { throw new UnsupportedError("Not supported"); }

  @DomName('Key.algorithm')
  @DocsEditable()
  @Experimental() // untriaged
  final Algorithm algorithm;

  @DomName('Key.extractable')
  @DocsEditable()
  @Experimental() // untriaged
  final bool extractable;

  @DomName('Key.type')
  @DocsEditable()
  @Experimental() // untriaged
  final String type;

  @DomName('Key.usages')
  @DocsEditable()
  @Experimental() // untriaged
  final List<String> usages;
}
// 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.


@DocsEditable()
@DomName('CSS')
// http://www.w3.org/TR/css3-conditional/#the-css-interface
@Experimental() // None
class Css extends Interceptor native "CSS" {
  // To suppress missing implicit constructor warnings.
  factory Css._() { throw new UnsupportedError("Not supported"); }

  @DomName('CSS.supports')
  @DocsEditable()
  bool supports(String property, String value) native;

  @JSName('supports')
  @DomName('CSS.supports')
  @DocsEditable()
  bool supportsCondition(String conditionText) native;
}
// 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.


@DocsEditable()
@DomName('CSSCharsetRule')
// http://dev.w3.org/csswg/cssom/#the-csscharsetrule-interface
@Experimental()
class CssCharsetRule extends CssRule native "CSSCharsetRule" {
  // To suppress missing implicit constructor warnings.
  factory CssCharsetRule._() { throw new UnsupportedError("Not supported"); }

  @DomName('CSSCharsetRule.encoding')
  @DocsEditable()
  String encoding;
}
// 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.


@DocsEditable()
@DomName('WebKitCSSFilterRule')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
// http://www.w3.org/TR/filter-effects/
class CssFilterRule extends CssRule native "WebKitCSSFilterRule" {
  // To suppress missing implicit constructor warnings.
  factory CssFilterRule._() { throw new UnsupportedError("Not supported"); }

  @DomName('WebKitCSSFilterRule.style')
  @DocsEditable()
  final CssStyleDeclaration style;
}
// 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.


@DocsEditable()
@DomName('CSSFontFaceLoadEvent')
// http://www.w3.org/TR/css3-fonts/
@Experimental()
class CssFontFaceLoadEvent extends Event native "CSSFontFaceLoadEvent" {
  // To suppress missing implicit constructor warnings.
  factory CssFontFaceLoadEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('CSSFontFaceLoadEvent.fontfaces')
  @DocsEditable()
  @Experimental() // untriaged
  final List<FontFace> fontfaces;
}
// 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.


@DocsEditable()
@DomName('CSSFontFaceRule')
class CssFontFaceRule extends CssRule native "CSSFontFaceRule" {
  // To suppress missing implicit constructor warnings.
  factory CssFontFaceRule._() { throw new UnsupportedError("Not supported"); }

  @DomName('CSSFontFaceRule.style')
  @DocsEditable()
  final CssStyleDeclaration style;
}
// 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.


@DocsEditable()
@DomName('CSSImportRule')
class CssImportRule extends CssRule native "CSSImportRule" {
  // To suppress missing implicit constructor warnings.
  factory CssImportRule._() { throw new UnsupportedError("Not supported"); }

  @DomName('CSSImportRule.href')
  @DocsEditable()
  final String href;

  @DomName('CSSImportRule.media')
  @DocsEditable()
  final MediaList media;

  @DomName('CSSImportRule.styleSheet')
  @DocsEditable()
  final CssStyleSheet styleSheet;
}
// 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.


@DocsEditable()
@DomName('CSSKeyframeRule')
@Experimental() // untriaged
class CssKeyframeRule extends CssRule native "CSSKeyframeRule,MozCSSKeyframeRule,WebKitCSSKeyframeRule" {
  // To suppress missing implicit constructor warnings.
  factory CssKeyframeRule._() { throw new UnsupportedError("Not supported"); }

  @DomName('CSSKeyframeRule.keyText')
  @DocsEditable()
  @Experimental() // untriaged
  String keyText;

  @DomName('CSSKeyframeRule.style')
  @DocsEditable()
  @Experimental() // untriaged
  final CssStyleDeclaration style;
}
// 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.


@DocsEditable()
@DomName('CSSKeyframesRule')
@Experimental() // untriaged
class CssKeyframesRule extends CssRule native "CSSKeyframesRule,MozCSSKeyframesRule,WebKitCSSKeyframesRule" {
  // To suppress missing implicit constructor warnings.
  factory CssKeyframesRule._() { throw new UnsupportedError("Not supported"); }

  @DomName('CSSKeyframesRule.cssRules')
  @DocsEditable()
  @Experimental() // untriaged
  @Returns('_CssRuleList')
  @Creates('_CssRuleList')
  final List<CssRule> cssRules;

  @DomName('CSSKeyframesRule.name')
  @DocsEditable()
  @Experimental() // untriaged
  String name;

  @DomName('CSSKeyframesRule.__getter__')
  @DocsEditable()
  @Experimental() // untriaged
  CssKeyframeRule __getter__(int index) native;

  @DomName('CSSKeyframesRule.deleteRule')
  @DocsEditable()
  @Experimental() // untriaged
  void deleteRule(String key) native;

  @DomName('CSSKeyframesRule.findRule')
  @DocsEditable()
  @Experimental() // untriaged
  CssKeyframeRule findRule(String key) native;

  @JSName('insertRule')
  @DomName('CSSKeyframesRule.insertRule')
  @DocsEditable()
  @Experimental() // untriaged
  void appendRule(String rule) native;
}
// 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.


@DocsEditable()
@DomName('CSSMediaRule')
class CssMediaRule extends CssRule native "CSSMediaRule" {
  // To suppress missing implicit constructor warnings.
  factory CssMediaRule._() { throw new UnsupportedError("Not supported"); }

  @DomName('CSSMediaRule.cssRules')
  @DocsEditable()
  @Returns('_CssRuleList')
  @Creates('_CssRuleList')
  final List<CssRule> cssRules;

  @DomName('CSSMediaRule.media')
  @DocsEditable()
  final MediaList media;

  @DomName('CSSMediaRule.deleteRule')
  @DocsEditable()
  void deleteRule(int index) native;

  @DomName('CSSMediaRule.insertRule')
  @DocsEditable()
  int insertRule(String rule, int index) native;
}
// 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.


@DocsEditable()
@DomName('CSSPageRule')
class CssPageRule extends CssRule native "CSSPageRule" {
  // To suppress missing implicit constructor warnings.
  factory CssPageRule._() { throw new UnsupportedError("Not supported"); }

  @DomName('CSSPageRule.selectorText')
  @DocsEditable()
  String selectorText;

  @DomName('CSSPageRule.style')
  @DocsEditable()
  final CssStyleDeclaration style;
}
// 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.


@DocsEditable()
@DomName('CSSRule')
class CssRule extends Interceptor native "CSSRule" {
  // To suppress missing implicit constructor warnings.
  factory CssRule._() { throw new UnsupportedError("Not supported"); }

  @DomName('CSSRule.CHARSET_RULE')
  @DocsEditable()
  static const int CHARSET_RULE = 2;

  @DomName('CSSRule.FONT_FACE_RULE')
  @DocsEditable()
  static const int FONT_FACE_RULE = 5;

  @DomName('CSSRule.IMPORT_RULE')
  @DocsEditable()
  static const int IMPORT_RULE = 3;

  @DomName('CSSRule.KEYFRAMES_RULE')
  @DocsEditable()
  @Experimental() // untriaged
  static const int KEYFRAMES_RULE = 7;

  @DomName('CSSRule.KEYFRAME_RULE')
  @DocsEditable()
  @Experimental() // untriaged
  static const int KEYFRAME_RULE = 8;

  @DomName('CSSRule.MEDIA_RULE')
  @DocsEditable()
  static const int MEDIA_RULE = 4;

  @DomName('CSSRule.PAGE_RULE')
  @DocsEditable()
  static const int PAGE_RULE = 6;

  @DomName('CSSRule.STYLE_RULE')
  @DocsEditable()
  static const int STYLE_RULE = 1;

  @DomName('CSSRule.SUPPORTS_RULE')
  @DocsEditable()
  static const int SUPPORTS_RULE = 12;

  @DomName('CSSRule.VIEWPORT_RULE')
  @DocsEditable()
  @Experimental() // untriaged
  static const int VIEWPORT_RULE = 15;

  @DomName('CSSRule.WEBKIT_FILTER_RULE')
  @DocsEditable()
  // http://www.w3.org/TR/filter-effects/
  @Experimental()
  static const int WEBKIT_FILTER_RULE = 17;

  @DomName('CSSRule.WEBKIT_KEYFRAMES_RULE')
  @DocsEditable()
  // http://www.w3.org/TR/css3-animations/#cssrule
  @Experimental()
  static const int WEBKIT_KEYFRAMES_RULE = 7;

  @DomName('CSSRule.WEBKIT_KEYFRAME_RULE')
  @DocsEditable()
  // http://www.w3.org/TR/css3-animations/#cssrule
  @Experimental()
  static const int WEBKIT_KEYFRAME_RULE = 8;

  @DomName('CSSRule.cssText')
  @DocsEditable()
  String cssText;

  @DomName('CSSRule.parentRule')
  @DocsEditable()
  final CssRule parentRule;

  @DomName('CSSRule.parentStyleSheet')
  @DocsEditable()
  final CssStyleSheet parentStyleSheet;

  @DomName('CSSRule.type')
  @DocsEditable()
  final int type;
}
// 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.


@DomName('CSSStyleDeclaration')
 class CssStyleDeclaration  extends Interceptor with 
    CssStyleDeclarationBase  native "CSSStyleDeclaration,MSStyleCSSProperties,CSS2Properties" {
  factory CssStyleDeclaration() => new CssStyleDeclaration.css('');

  factory CssStyleDeclaration.css(String css) {
    final style = new Element.tag('div').style;
    style.cssText = css;
    return style;
  }
  
  String getPropertyValue(String propertyName) {
    var propValue = _getPropertyValue(propertyName);
    return propValue != null ? propValue : '';
  }

  @DomName('CSSStyleDeclaration.setProperty')
  void setProperty(String propertyName, String value, [String priority]) {
    // try/catch for IE9 which throws on unsupported values.
    try {
      if (priority == null) {
        priority = '';
      }
      JS('void', '#.setProperty(#, #, #)', this, propertyName, value, priority);
      // Bug #2772, IE9 requires a poke to actually apply the value.
      if (JS('bool', '!!#.setAttribute', this)) {
        JS('void', '#.setAttribute(#, #)', this, propertyName, value);
      }
    } catch (e) {}
  }
  
  /**
   * Checks to see if CSS Transitions are supported.
   */
  static bool get supportsTransitions {
    if (JS('bool', '"transition" in document.body.style')) {
      return true;
    }
    var propertyName = '${Device.propertyPrefix}Transition';
    return JS('bool', '# in document.body.style', propertyName);
  }
  // To suppress missing implicit constructor warnings.
  factory CssStyleDeclaration._() { throw new UnsupportedError("Not supported"); }

  @DomName('CSSStyleDeclaration.cssText')
  @DocsEditable()
  String cssText;

  @DomName('CSSStyleDeclaration.length')
  @DocsEditable()
  final int length;

  @DomName('CSSStyleDeclaration.parentRule')
  @DocsEditable()
  final CssRule parentRule;

  @DomName('CSSStyleDeclaration.__setter__')
  @DocsEditable()
  void __setter__(String propertyName, String propertyValue) native;

  @DomName('CSSStyleDeclaration.getPropertyPriority')
  @DocsEditable()
  String getPropertyPriority(String propertyName) native;

  @JSName('getPropertyValue')
  @DomName('CSSStyleDeclaration.getPropertyValue')
  @DocsEditable()
  String _getPropertyValue(String propertyName) native;

  @DomName('CSSStyleDeclaration.item')
  @DocsEditable()
  String item(int index) native;

  @DomName('CSSStyleDeclaration.removeProperty')
  @DocsEditable()
  String removeProperty(String propertyName) native;

}

class _CssStyleDeclarationSet extends Object with CssStyleDeclarationBase {
  final Iterable<Element> _elementIterable;
  Iterable<CssStyleDeclaration> _elementCssStyleDeclarationSetIterable;

  _CssStyleDeclarationSet(this._elementIterable) {
    _elementCssStyleDeclarationSetIterable = new List.from(
        _elementIterable).map((e) => e.style);
  }

  String getPropertyValue(String propertyName) =>
      _elementCssStyleDeclarationSetIterable.first.getPropertyValue(
          propertyName);

  void setProperty(String propertyName, String value, [String priority]) {
    _elementCssStyleDeclarationSetIterable.forEach((e) =>
        e.setProperty(propertyName, value, priority));
  }
  // Important note: CssStyleDeclarationSet does NOT implement every method
  // available in CssStyleDeclaration. Some of the methods don't make so much
  // sense in terms of having a resonable value to return when you're
  // considering a list of Elements. You will need to manually add any of the
  // items in the MEMBERS set if you want that functionality.
}

abstract class CssStyleDeclarationBase {
  String getPropertyValue(String propertyName);  
  void setProperty(String propertyName, String value, [String priority]);

  // TODO(jacobr): generate this list of properties using the existing script.
  /** Gets the value of "align-content" */
  String get alignContent =>
    getPropertyValue('${Device.cssPrefix}align-content');

  /** Sets the value of "align-content" */
  void set alignContent(String value) {
    setProperty('${Device.cssPrefix}align-content', value, '');
  }

  /** Gets the value of "align-items" */
  String get alignItems =>
    getPropertyValue('${Device.cssPrefix}align-items');

  /** Sets the value of "align-items" */
  void set alignItems(String value) {
    setProperty('${Device.cssPrefix}align-items', value, '');
  }

  /** Gets the value of "align-self" */
  String get alignSelf =>
    getPropertyValue('${Device.cssPrefix}align-self');

  /** Sets the value of "align-self" */
  void set alignSelf(String value) {
    setProperty('${Device.cssPrefix}align-self', value, '');
  }

  /** Gets the value of "animation" */
  String get animation =>
    getPropertyValue('${Device.cssPrefix}animation');

  /** Sets the value of "animation" */
  void set animation(String value) {
    setProperty('${Device.cssPrefix}animation', value, '');
  }

  /** Gets the value of "animation-delay" */
  String get animationDelay =>
    getPropertyValue('${Device.cssPrefix}animation-delay');

  /** Sets the value of "animation-delay" */
  void set animationDelay(String value) {
    setProperty('${Device.cssPrefix}animation-delay', value, '');
  }

  /** Gets the value of "animation-direction" */
  String get animationDirection =>
    getPropertyValue('${Device.cssPrefix}animation-direction');

  /** Sets the value of "animation-direction" */
  void set animationDirection(String value) {
    setProperty('${Device.cssPrefix}animation-direction', value, '');
  }

  /** Gets the value of "animation-duration" */
  String get animationDuration =>
    getPropertyValue('${Device.cssPrefix}animation-duration');

  /** Sets the value of "animation-duration" */
  void set animationDuration(String value) {
    setProperty('${Device.cssPrefix}animation-duration', value, '');
  }

  /** Gets the value of "animation-fill-mode" */
  String get animationFillMode =>
    getPropertyValue('${Device.cssPrefix}animation-fill-mode');

  /** Sets the value of "animation-fill-mode" */
  void set animationFillMode(String value) {
    setProperty('${Device.cssPrefix}animation-fill-mode', value, '');
  }

  /** Gets the value of "animation-iteration-count" */
  String get animationIterationCount =>
    getPropertyValue('${Device.cssPrefix}animation-iteration-count');

  /** Sets the value of "animation-iteration-count" */
  void set animationIterationCount(String value) {
    setProperty('${Device.cssPrefix}animation-iteration-count', value, '');
  }

  /** Gets the value of "animation-name" */
  String get animationName =>
    getPropertyValue('${Device.cssPrefix}animation-name');

  /** Sets the value of "animation-name" */
  void set animationName(String value) {
    setProperty('${Device.cssPrefix}animation-name', value, '');
  }

  /** Gets the value of "animation-play-state" */
  String get animationPlayState =>
    getPropertyValue('${Device.cssPrefix}animation-play-state');

  /** Sets the value of "animation-play-state" */
  void set animationPlayState(String value) {
    setProperty('${Device.cssPrefix}animation-play-state', value, '');
  }

  /** Gets the value of "animation-timing-function" */
  String get animationTimingFunction =>
    getPropertyValue('${Device.cssPrefix}animation-timing-function');

  /** Sets the value of "animation-timing-function" */
  void set animationTimingFunction(String value) {
    setProperty('${Device.cssPrefix}animation-timing-function', value, '');
  }

  /** Gets the value of "app-region" */
  String get appRegion =>
    getPropertyValue('${Device.cssPrefix}app-region');

  /** Sets the value of "app-region" */
  void set appRegion(String value) {
    setProperty('${Device.cssPrefix}app-region', value, '');
  }

  /** Gets the value of "appearance" */
  String get appearance =>
    getPropertyValue('${Device.cssPrefix}appearance');

  /** Sets the value of "appearance" */
  void set appearance(String value) {
    setProperty('${Device.cssPrefix}appearance', value, '');
  }

  /** Gets the value of "aspect-ratio" */
  String get aspectRatio =>
    getPropertyValue('${Device.cssPrefix}aspect-ratio');

  /** Sets the value of "aspect-ratio" */
  void set aspectRatio(String value) {
    setProperty('${Device.cssPrefix}aspect-ratio', value, '');
  }

  /** Gets the value of "backface-visibility" */
  String get backfaceVisibility =>
    getPropertyValue('${Device.cssPrefix}backface-visibility');

  /** Sets the value of "backface-visibility" */
  void set backfaceVisibility(String value) {
    setProperty('${Device.cssPrefix}backface-visibility', value, '');
  }

  /** Gets the value of "background" */
  String get background =>
    getPropertyValue('background');

  /** Sets the value of "background" */
  void set background(String value) {
    setProperty('background', value, '');
  }

  /** Gets the value of "background-attachment" */
  String get backgroundAttachment =>
    getPropertyValue('background-attachment');

  /** Sets the value of "background-attachment" */
  void set backgroundAttachment(String value) {
    setProperty('background-attachment', value, '');
  }

  /** Gets the value of "background-clip" */
  String get backgroundClip =>
    getPropertyValue('background-clip');

  /** Sets the value of "background-clip" */
  void set backgroundClip(String value) {
    setProperty('background-clip', value, '');
  }

  /** Gets the value of "background-color" */
  String get backgroundColor =>
    getPropertyValue('background-color');

  /** Sets the value of "background-color" */
  void set backgroundColor(String value) {
    setProperty('background-color', value, '');
  }

  /** Gets the value of "background-composite" */
  String get backgroundComposite =>
    getPropertyValue('${Device.cssPrefix}background-composite');

  /** Sets the value of "background-composite" */
  void set backgroundComposite(String value) {
    setProperty('${Device.cssPrefix}background-composite', value, '');
  }

  /** Gets the value of "background-image" */
  String get backgroundImage =>
    getPropertyValue('background-image');

  /** Sets the value of "background-image" */
  void set backgroundImage(String value) {
    setProperty('background-image', value, '');
  }

  /** Gets the value of "background-origin" */
  String get backgroundOrigin =>
    getPropertyValue('background-origin');

  /** Sets the value of "background-origin" */
  void set backgroundOrigin(String value) {
    setProperty('background-origin', value, '');
  }

  /** Gets the value of "background-position" */
  String get backgroundPosition =>
    getPropertyValue('background-position');

  /** Sets the value of "background-position" */
  void set backgroundPosition(String value) {
    setProperty('background-position', value, '');
  }

  /** Gets the value of "background-position-x" */
  String get backgroundPositionX =>
    getPropertyValue('background-position-x');

  /** Sets the value of "background-position-x" */
  void set backgroundPositionX(String value) {
    setProperty('background-position-x', value, '');
  }

  /** Gets the value of "background-position-y" */
  String get backgroundPositionY =>
    getPropertyValue('background-position-y');

  /** Sets the value of "background-position-y" */
  void set backgroundPositionY(String value) {
    setProperty('background-position-y', value, '');
  }

  /** Gets the value of "background-repeat" */
  String get backgroundRepeat =>
    getPropertyValue('background-repeat');

  /** Sets the value of "background-repeat" */
  void set backgroundRepeat(String value) {
    setProperty('background-repeat', value, '');
  }

  /** Gets the value of "background-repeat-x" */
  String get backgroundRepeatX =>
    getPropertyValue('background-repeat-x');

  /** Sets the value of "background-repeat-x" */
  void set backgroundRepeatX(String value) {
    setProperty('background-repeat-x', value, '');
  }

  /** Gets the value of "background-repeat-y" */
  String get backgroundRepeatY =>
    getPropertyValue('background-repeat-y');

  /** Sets the value of "background-repeat-y" */
  void set backgroundRepeatY(String value) {
    setProperty('background-repeat-y', value, '');
  }

  /** Gets the value of "background-size" */
  String get backgroundSize =>
    getPropertyValue('background-size');

  /** Sets the value of "background-size" */
  void set backgroundSize(String value) {
    setProperty('background-size', value, '');
  }

  /** Gets the value of "blend-mode" */
  String get blendMode =>
    getPropertyValue('${Device.cssPrefix}blend-mode');

  /** Sets the value of "blend-mode" */
  void set blendMode(String value) {
    setProperty('${Device.cssPrefix}blend-mode', value, '');
  }

  /** Gets the value of "border" */
  String get border =>
    getPropertyValue('border');

  /** Sets the value of "border" */
  void set border(String value) {
    setProperty('border', value, '');
  }

  /** Gets the value of "border-after" */
  String get borderAfter =>
    getPropertyValue('${Device.cssPrefix}border-after');

  /** Sets the value of "border-after" */
  void set borderAfter(String value) {
    setProperty('${Device.cssPrefix}border-after', value, '');
  }

  /** Gets the value of "border-after-color" */
  String get borderAfterColor =>
    getPropertyValue('${Device.cssPrefix}border-after-color');

  /** Sets the value of "border-after-color" */
  void set borderAfterColor(String value) {
    setProperty('${Device.cssPrefix}border-after-color', value, '');
  }

  /** Gets the value of "border-after-style" */
  String get borderAfterStyle =>
    getPropertyValue('${Device.cssPrefix}border-after-style');

  /** Sets the value of "border-after-style" */
  void set borderAfterStyle(String value) {
    setProperty('${Device.cssPrefix}border-after-style', value, '');
  }

  /** Gets the value of "border-after-width" */
  String get borderAfterWidth =>
    getPropertyValue('${Device.cssPrefix}border-after-width');

  /** Sets the value of "border-after-width" */
  void set borderAfterWidth(String value) {
    setProperty('${Device.cssPrefix}border-after-width', value, '');
  }

  /** Gets the value of "border-before" */
  String get borderBefore =>
    getPropertyValue('${Device.cssPrefix}border-before');

  /** Sets the value of "border-before" */
  void set borderBefore(String value) {
    setProperty('${Device.cssPrefix}border-before', value, '');
  }

  /** Gets the value of "border-before-color" */
  String get borderBeforeColor =>
    getPropertyValue('${Device.cssPrefix}border-before-color');

  /** Sets the value of "border-before-color" */
  void set borderBeforeColor(String value) {
    setProperty('${Device.cssPrefix}border-before-color', value, '');
  }

  /** Gets the value of "border-before-style" */
  String get borderBeforeStyle =>
    getPropertyValue('${Device.cssPrefix}border-before-style');

  /** Sets the value of "border-before-style" */
  void set borderBeforeStyle(String value) {
    setProperty('${Device.cssPrefix}border-before-style', value, '');
  }

  /** Gets the value of "border-before-width" */
  String get borderBeforeWidth =>
    getPropertyValue('${Device.cssPrefix}border-before-width');

  /** Sets the value of "border-before-width" */
  void set borderBeforeWidth(String value) {
    setProperty('${Device.cssPrefix}border-before-width', value, '');
  }

  /** Gets the value of "border-bottom" */
  String get borderBottom =>
    getPropertyValue('border-bottom');

  /** Sets the value of "border-bottom" */
  void set borderBottom(String value) {
    setProperty('border-bottom', value, '');
  }

  /** Gets the value of "border-bottom-color" */
  String get borderBottomColor =>
    getPropertyValue('border-bottom-color');

  /** Sets the value of "border-bottom-color" */
  void set borderBottomColor(String value) {
    setProperty('border-bottom-color', value, '');
  }

  /** Gets the value of "border-bottom-left-radius" */
  String get borderBottomLeftRadius =>
    getPropertyValue('border-bottom-left-radius');

  /** Sets the value of "border-bottom-left-radius" */
  void set borderBottomLeftRadius(String value) {
    setProperty('border-bottom-left-radius', value, '');
  }

  /** Gets the value of "border-bottom-right-radius" */
  String get borderBottomRightRadius =>
    getPropertyValue('border-bottom-right-radius');

  /** Sets the value of "border-bottom-right-radius" */
  void set borderBottomRightRadius(String value) {
    setProperty('border-bottom-right-radius', value, '');
  }

  /** Gets the value of "border-bottom-style" */
  String get borderBottomStyle =>
    getPropertyValue('border-bottom-style');

  /** Sets the value of "border-bottom-style" */
  void set borderBottomStyle(String value) {
    setProperty('border-bottom-style', value, '');
  }

  /** Gets the value of "border-bottom-width" */
  String get borderBottomWidth =>
    getPropertyValue('border-bottom-width');

  /** Sets the value of "border-bottom-width" */
  void set borderBottomWidth(String value) {
    setProperty('border-bottom-width', value, '');
  }

  /** Gets the value of "border-collapse" */
  String get borderCollapse =>
    getPropertyValue('border-collapse');

  /** Sets the value of "border-collapse" */
  void set borderCollapse(String value) {
    setProperty('border-collapse', value, '');
  }

  /** Gets the value of "border-color" */
  String get borderColor =>
    getPropertyValue('border-color');

  /** Sets the value of "border-color" */
  void set borderColor(String value) {
    setProperty('border-color', value, '');
  }

  /** Gets the value of "border-end" */
  String get borderEnd =>
    getPropertyValue('${Device.cssPrefix}border-end');

  /** Sets the value of "border-end" */
  void set borderEnd(String value) {
    setProperty('${Device.cssPrefix}border-end', value, '');
  }

  /** Gets the value of "border-end-color" */
  String get borderEndColor =>
    getPropertyValue('${Device.cssPrefix}border-end-color');

  /** Sets the value of "border-end-color" */
  void set borderEndColor(String value) {
    setProperty('${Device.cssPrefix}border-end-color', value, '');
  }

  /** Gets the value of "border-end-style" */
  String get borderEndStyle =>
    getPropertyValue('${Device.cssPrefix}border-end-style');

  /** Sets the value of "border-end-style" */
  void set borderEndStyle(String value) {
    setProperty('${Device.cssPrefix}border-end-style', value, '');
  }

  /** Gets the value of "border-end-width" */
  String get borderEndWidth =>
    getPropertyValue('${Device.cssPrefix}border-end-width');

  /** Sets the value of "border-end-width" */
  void set borderEndWidth(String value) {
    setProperty('${Device.cssPrefix}border-end-width', value, '');
  }

  /** Gets the value of "border-fit" */
  String get borderFit =>
    getPropertyValue('${Device.cssPrefix}border-fit');

  /** Sets the value of "border-fit" */
  void set borderFit(String value) {
    setProperty('${Device.cssPrefix}border-fit', value, '');
  }

  /** Gets the value of "border-horizontal-spacing" */
  String get borderHorizontalSpacing =>
    getPropertyValue('${Device.cssPrefix}border-horizontal-spacing');

  /** Sets the value of "border-horizontal-spacing" */
  void set borderHorizontalSpacing(String value) {
    setProperty('${Device.cssPrefix}border-horizontal-spacing', value, '');
  }

  /** Gets the value of "border-image" */
  String get borderImage =>
    getPropertyValue('border-image');

  /** Sets the value of "border-image" */
  void set borderImage(String value) {
    setProperty('border-image', value, '');
  }

  /** Gets the value of "border-image-outset" */
  String get borderImageOutset =>
    getPropertyValue('border-image-outset');

  /** Sets the value of "border-image-outset" */
  void set borderImageOutset(String value) {
    setProperty('border-image-outset', value, '');
  }

  /** Gets the value of "border-image-repeat" */
  String get borderImageRepeat =>
    getPropertyValue('border-image-repeat');

  /** Sets the value of "border-image-repeat" */
  void set borderImageRepeat(String value) {
    setProperty('border-image-repeat', value, '');
  }

  /** Gets the value of "border-image-slice" */
  String get borderImageSlice =>
    getPropertyValue('border-image-slice');

  /** Sets the value of "border-image-slice" */
  void set borderImageSlice(String value) {
    setProperty('border-image-slice', value, '');
  }

  /** Gets the value of "border-image-source" */
  String get borderImageSource =>
    getPropertyValue('border-image-source');

  /** Sets the value of "border-image-source" */
  void set borderImageSource(String value) {
    setProperty('border-image-source', value, '');
  }

  /** Gets the value of "border-image-width" */
  String get borderImageWidth =>
    getPropertyValue('border-image-width');

  /** Sets the value of "border-image-width" */
  void set borderImageWidth(String value) {
    setProperty('border-image-width', value, '');
  }

  /** Gets the value of "border-left" */
  String get borderLeft =>
    getPropertyValue('border-left');

  /** Sets the value of "border-left" */
  void set borderLeft(String value) {
    setProperty('border-left', value, '');
  }

  /** Gets the value of "border-left-color" */
  String get borderLeftColor =>
    getPropertyValue('border-left-color');

  /** Sets the value of "border-left-color" */
  void set borderLeftColor(String value) {
    setProperty('border-left-color', value, '');
  }

  /** Gets the value of "border-left-style" */
  String get borderLeftStyle =>
    getPropertyValue('border-left-style');

  /** Sets the value of "border-left-style" */
  void set borderLeftStyle(String value) {
    setProperty('border-left-style', value, '');
  }

  /** Gets the value of "border-left-width" */
  String get borderLeftWidth =>
    getPropertyValue('border-left-width');

  /** Sets the value of "border-left-width" */
  void set borderLeftWidth(String value) {
    setProperty('border-left-width', value, '');
  }

  /** Gets the value of "border-radius" */
  String get borderRadius =>
    getPropertyValue('border-radius');

  /** Sets the value of "border-radius" */
  void set borderRadius(String value) {
    setProperty('border-radius', value, '');
  }

  /** Gets the value of "border-right" */
  String get borderRight =>
    getPropertyValue('border-right');

  /** Sets the value of "border-right" */
  void set borderRight(String value) {
    setProperty('border-right', value, '');
  }

  /** Gets the value of "border-right-color" */
  String get borderRightColor =>
    getPropertyValue('border-right-color');

  /** Sets the value of "border-right-color" */
  void set borderRightColor(String value) {
    setProperty('border-right-color', value, '');
  }

  /** Gets the value of "border-right-style" */
  String get borderRightStyle =>
    getPropertyValue('border-right-style');

  /** Sets the value of "border-right-style" */
  void set borderRightStyle(String value) {
    setProperty('border-right-style', value, '');
  }

  /** Gets the value of "border-right-width" */
  String get borderRightWidth =>
    getPropertyValue('border-right-width');

  /** Sets the value of "border-right-width" */
  void set borderRightWidth(String value) {
    setProperty('border-right-width', value, '');
  }

  /** Gets the value of "border-spacing" */
  String get borderSpacing =>
    getPropertyValue('border-spacing');

  /** Sets the value of "border-spacing" */
  void set borderSpacing(String value) {
    setProperty('border-spacing', value, '');
  }

  /** Gets the value of "border-start" */
  String get borderStart =>
    getPropertyValue('${Device.cssPrefix}border-start');

  /** Sets the value of "border-start" */
  void set borderStart(String value) {
    setProperty('${Device.cssPrefix}border-start', value, '');
  }

  /** Gets the value of "border-start-color" */
  String get borderStartColor =>
    getPropertyValue('${Device.cssPrefix}border-start-color');

  /** Sets the value of "border-start-color" */
  void set borderStartColor(String value) {
    setProperty('${Device.cssPrefix}border-start-color', value, '');
  }

  /** Gets the value of "border-start-style" */
  String get borderStartStyle =>
    getPropertyValue('${Device.cssPrefix}border-start-style');

  /** Sets the value of "border-start-style" */
  void set borderStartStyle(String value) {
    setProperty('${Device.cssPrefix}border-start-style', value, '');
  }

  /** Gets the value of "border-start-width" */
  String get borderStartWidth =>
    getPropertyValue('${Device.cssPrefix}border-start-width');

  /** Sets the value of "border-start-width" */
  void set borderStartWidth(String value) {
    setProperty('${Device.cssPrefix}border-start-width', value, '');
  }

  /** Gets the value of "border-style" */
  String get borderStyle =>
    getPropertyValue('border-style');

  /** Sets the value of "border-style" */
  void set borderStyle(String value) {
    setProperty('border-style', value, '');
  }

  /** Gets the value of "border-top" */
  String get borderTop =>
    getPropertyValue('border-top');

  /** Sets the value of "border-top" */
  void set borderTop(String value) {
    setProperty('border-top', value, '');
  }

  /** Gets the value of "border-top-color" */
  String get borderTopColor =>
    getPropertyValue('border-top-color');

  /** Sets the value of "border-top-color" */
  void set borderTopColor(String value) {
    setProperty('border-top-color', value, '');
  }

  /** Gets the value of "border-top-left-radius" */
  String get borderTopLeftRadius =>
    getPropertyValue('border-top-left-radius');

  /** Sets the value of "border-top-left-radius" */
  void set borderTopLeftRadius(String value) {
    setProperty('border-top-left-radius', value, '');
  }

  /** Gets the value of "border-top-right-radius" */
  String get borderTopRightRadius =>
    getPropertyValue('border-top-right-radius');

  /** Sets the value of "border-top-right-radius" */
  void set borderTopRightRadius(String value) {
    setProperty('border-top-right-radius', value, '');
  }

  /** Gets the value of "border-top-style" */
  String get borderTopStyle =>
    getPropertyValue('border-top-style');

  /** Sets the value of "border-top-style" */
  void set borderTopStyle(String value) {
    setProperty('border-top-style', value, '');
  }

  /** Gets the value of "border-top-width" */
  String get borderTopWidth =>
    getPropertyValue('border-top-width');

  /** Sets the value of "border-top-width" */
  void set borderTopWidth(String value) {
    setProperty('border-top-width', value, '');
  }

  /** Gets the value of "border-vertical-spacing" */
  String get borderVerticalSpacing =>
    getPropertyValue('${Device.cssPrefix}border-vertical-spacing');

  /** Sets the value of "border-vertical-spacing" */
  void set borderVerticalSpacing(String value) {
    setProperty('${Device.cssPrefix}border-vertical-spacing', value, '');
  }

  /** Gets the value of "border-width" */
  String get borderWidth =>
    getPropertyValue('border-width');

  /** Sets the value of "border-width" */
  void set borderWidth(String value) {
    setProperty('border-width', value, '');
  }

  /** Gets the value of "bottom" */
  String get bottom =>
    getPropertyValue('bottom');

  /** Sets the value of "bottom" */
  void set bottom(String value) {
    setProperty('bottom', value, '');
  }

  /** Gets the value of "box-align" */
  String get boxAlign =>
    getPropertyValue('${Device.cssPrefix}box-align');

  /** Sets the value of "box-align" */
  void set boxAlign(String value) {
    setProperty('${Device.cssPrefix}box-align', value, '');
  }

  /** Gets the value of "box-decoration-break" */
  String get boxDecorationBreak =>
    getPropertyValue('${Device.cssPrefix}box-decoration-break');

  /** Sets the value of "box-decoration-break" */
  void set boxDecorationBreak(String value) {
    setProperty('${Device.cssPrefix}box-decoration-break', value, '');
  }

  /** Gets the value of "box-direction" */
  String get boxDirection =>
    getPropertyValue('${Device.cssPrefix}box-direction');

  /** Sets the value of "box-direction" */
  void set boxDirection(String value) {
    setProperty('${Device.cssPrefix}box-direction', value, '');
  }

  /** Gets the value of "box-flex" */
  String get boxFlex =>
    getPropertyValue('${Device.cssPrefix}box-flex');

  /** Sets the value of "box-flex" */
  void set boxFlex(String value) {
    setProperty('${Device.cssPrefix}box-flex', value, '');
  }

  /** Gets the value of "box-flex-group" */
  String get boxFlexGroup =>
    getPropertyValue('${Device.cssPrefix}box-flex-group');

  /** Sets the value of "box-flex-group" */
  void set boxFlexGroup(String value) {
    setProperty('${Device.cssPrefix}box-flex-group', value, '');
  }

  /** Gets the value of "box-lines" */
  String get boxLines =>
    getPropertyValue('${Device.cssPrefix}box-lines');

  /** Sets the value of "box-lines" */
  void set boxLines(String value) {
    setProperty('${Device.cssPrefix}box-lines', value, '');
  }

  /** Gets the value of "box-ordinal-group" */
  String get boxOrdinalGroup =>
    getPropertyValue('${Device.cssPrefix}box-ordinal-group');

  /** Sets the value of "box-ordinal-group" */
  void set boxOrdinalGroup(String value) {
    setProperty('${Device.cssPrefix}box-ordinal-group', value, '');
  }

  /** Gets the value of "box-orient" */
  String get boxOrient =>
    getPropertyValue('${Device.cssPrefix}box-orient');

  /** Sets the value of "box-orient" */
  void set boxOrient(String value) {
    setProperty('${Device.cssPrefix}box-orient', value, '');
  }

  /** Gets the value of "box-pack" */
  String get boxPack =>
    getPropertyValue('${Device.cssPrefix}box-pack');

  /** Sets the value of "box-pack" */
  void set boxPack(String value) {
    setProperty('${Device.cssPrefix}box-pack', value, '');
  }

  /** Gets the value of "box-reflect" */
  String get boxReflect =>
    getPropertyValue('${Device.cssPrefix}box-reflect');

  /** Sets the value of "box-reflect" */
  void set boxReflect(String value) {
    setProperty('${Device.cssPrefix}box-reflect', value, '');
  }

  /** Gets the value of "box-shadow" */
  String get boxShadow =>
    getPropertyValue('box-shadow');

  /** Sets the value of "box-shadow" */
  void set boxShadow(String value) {
    setProperty('box-shadow', value, '');
  }

  /** Gets the value of "box-sizing" */
  String get boxSizing => Device.isFirefox ? 
      getPropertyValue('${Device.cssPrefix}box-sizing') : 
      getPropertyValue('box-sizing');

  /** Sets the value of "box-sizing" */
  void set boxSizing(String value) {
    if (Device.isFirefox) {
      setProperty('${Device.cssPrefix}box-sizing', value, '');
    } else {
      setProperty('box-sizing', value, '');
    }
  }

  /** Gets the value of "caption-side" */
  String get captionSide =>
    getPropertyValue('caption-side');

  /** Sets the value of "caption-side" */
  void set captionSide(String value) {
    setProperty('caption-side', value, '');
  }

  /** Gets the value of "clear" */
  String get clear =>
    getPropertyValue('clear');

  /** Sets the value of "clear" */
  void set clear(String value) {
    setProperty('clear', value, '');
  }

  /** Gets the value of "clip" */
  String get clip =>
    getPropertyValue('clip');

  /** Sets the value of "clip" */
  void set clip(String value) {
    setProperty('clip', value, '');
  }

  /** Gets the value of "clip-path" */
  String get clipPath =>
    getPropertyValue('${Device.cssPrefix}clip-path');

  /** Sets the value of "clip-path" */
  void set clipPath(String value) {
    setProperty('${Device.cssPrefix}clip-path', value, '');
  }

  /** Gets the value of "color" */
  String get color =>
    getPropertyValue('color');

  /** Sets the value of "color" */
  void set color(String value) {
    setProperty('color', value, '');
  }

  /** Gets the value of "color-correction" */
  String get colorCorrection =>
    getPropertyValue('${Device.cssPrefix}color-correction');

  /** Sets the value of "color-correction" */
  void set colorCorrection(String value) {
    setProperty('${Device.cssPrefix}color-correction', value, '');
  }

  /** Gets the value of "column-axis" */
  String get columnAxis =>
    getPropertyValue('${Device.cssPrefix}column-axis');

  /** Sets the value of "column-axis" */
  void set columnAxis(String value) {
    setProperty('${Device.cssPrefix}column-axis', value, '');
  }

  /** Gets the value of "column-break-after" */
  String get columnBreakAfter =>
    getPropertyValue('${Device.cssPrefix}column-break-after');

  /** Sets the value of "column-break-after" */
  void set columnBreakAfter(String value) {
    setProperty('${Device.cssPrefix}column-break-after', value, '');
  }

  /** Gets the value of "column-break-before" */
  String get columnBreakBefore =>
    getPropertyValue('${Device.cssPrefix}column-break-before');

  /** Sets the value of "column-break-before" */
  void set columnBreakBefore(String value) {
    setProperty('${Device.cssPrefix}column-break-before', value, '');
  }

  /** Gets the value of "column-break-inside" */
  String get columnBreakInside =>
    getPropertyValue('${Device.cssPrefix}column-break-inside');

  /** Sets the value of "column-break-inside" */
  void set columnBreakInside(String value) {
    setProperty('${Device.cssPrefix}column-break-inside', value, '');
  }

  /** Gets the value of "column-count" */
  String get columnCount =>
    getPropertyValue('${Device.cssPrefix}column-count');

  /** Sets the value of "column-count" */
  void set columnCount(String value) {
    setProperty('${Device.cssPrefix}column-count', value, '');
  }

  /** Gets the value of "column-gap" */
  String get columnGap =>
    getPropertyValue('${Device.cssPrefix}column-gap');

  /** Sets the value of "column-gap" */
  void set columnGap(String value) {
    setProperty('${Device.cssPrefix}column-gap', value, '');
  }

  /** Gets the value of "column-progression" */
  String get columnProgression =>
    getPropertyValue('${Device.cssPrefix}column-progression');

  /** Sets the value of "column-progression" */
  void set columnProgression(String value) {
    setProperty('${Device.cssPrefix}column-progression', value, '');
  }

  /** Gets the value of "column-rule" */
  String get columnRule =>
    getPropertyValue('${Device.cssPrefix}column-rule');

  /** Sets the value of "column-rule" */
  void set columnRule(String value) {
    setProperty('${Device.cssPrefix}column-rule', value, '');
  }

  /** Gets the value of "column-rule-color" */
  String get columnRuleColor =>
    getPropertyValue('${Device.cssPrefix}column-rule-color');

  /** Sets the value of "column-rule-color" */
  void set columnRuleColor(String value) {
    setProperty('${Device.cssPrefix}column-rule-color', value, '');
  }

  /** Gets the value of "column-rule-style" */
  String get columnRuleStyle =>
    getPropertyValue('${Device.cssPrefix}column-rule-style');

  /** Sets the value of "column-rule-style" */
  void set columnRuleStyle(String value) {
    setProperty('${Device.cssPrefix}column-rule-style', value, '');
  }

  /** Gets the value of "column-rule-width" */
  String get columnRuleWidth =>
    getPropertyValue('${Device.cssPrefix}column-rule-width');

  /** Sets the value of "column-rule-width" */
  void set columnRuleWidth(String value) {
    setProperty('${Device.cssPrefix}column-rule-width', value, '');
  }

  /** Gets the value of "column-span" */
  String get columnSpan =>
    getPropertyValue('${Device.cssPrefix}column-span');

  /** Sets the value of "column-span" */
  void set columnSpan(String value) {
    setProperty('${Device.cssPrefix}column-span', value, '');
  }

  /** Gets the value of "column-width" */
  String get columnWidth =>
    getPropertyValue('${Device.cssPrefix}column-width');

  /** Sets the value of "column-width" */
  void set columnWidth(String value) {
    setProperty('${Device.cssPrefix}column-width', value, '');
  }

  /** Gets the value of "columns" */
  String get columns =>
    getPropertyValue('${Device.cssPrefix}columns');

  /** Sets the value of "columns" */
  void set columns(String value) {
    setProperty('${Device.cssPrefix}columns', value, '');
  }

  /** Gets the value of "content" */
  String get content =>
    getPropertyValue('content');

  /** Sets the value of "content" */
  void set content(String value) {
    setProperty('content', value, '');
  }

  /** Gets the value of "counter-increment" */
  String get counterIncrement =>
    getPropertyValue('counter-increment');

  /** Sets the value of "counter-increment" */
  void set counterIncrement(String value) {
    setProperty('counter-increment', value, '');
  }

  /** Gets the value of "counter-reset" */
  String get counterReset =>
    getPropertyValue('counter-reset');

  /** Sets the value of "counter-reset" */
  void set counterReset(String value) {
    setProperty('counter-reset', value, '');
  }

  /** Gets the value of "cursor" */
  String get cursor =>
    getPropertyValue('cursor');

  /** Sets the value of "cursor" */
  void set cursor(String value) {
    setProperty('cursor', value, '');
  }

  /** Gets the value of "dashboard-region" */
  String get dashboardRegion =>
    getPropertyValue('${Device.cssPrefix}dashboard-region');

  /** Sets the value of "dashboard-region" */
  void set dashboardRegion(String value) {
    setProperty('${Device.cssPrefix}dashboard-region', value, '');
  }

  /** Gets the value of "direction" */
  String get direction =>
    getPropertyValue('direction');

  /** Sets the value of "direction" */
  void set direction(String value) {
    setProperty('direction', value, '');
  }

  /** Gets the value of "display" */
  String get display =>
    getPropertyValue('display');

  /** Sets the value of "display" */
  void set display(String value) {
    setProperty('display', value, '');
  }

  /** Gets the value of "empty-cells" */
  String get emptyCells =>
    getPropertyValue('empty-cells');

  /** Sets the value of "empty-cells" */
  void set emptyCells(String value) {
    setProperty('empty-cells', value, '');
  }

  /** Gets the value of "filter" */
  String get filter =>
    getPropertyValue('${Device.cssPrefix}filter');

  /** Sets the value of "filter" */
  void set filter(String value) {
    setProperty('${Device.cssPrefix}filter', value, '');
  }

  /** Gets the value of "flex" */
  String get flex =>
    getPropertyValue('${Device.cssPrefix}flex');

  /** Sets the value of "flex" */
  void set flex(String value) {
    setProperty('${Device.cssPrefix}flex', value, '');
  }

  /** Gets the value of "flex-basis" */
  String get flexBasis =>
    getPropertyValue('${Device.cssPrefix}flex-basis');

  /** Sets the value of "flex-basis" */
  void set flexBasis(String value) {
    setProperty('${Device.cssPrefix}flex-basis', value, '');
  }

  /** Gets the value of "flex-direction" */
  String get flexDirection =>
    getPropertyValue('${Device.cssPrefix}flex-direction');

  /** Sets the value of "flex-direction" */
  void set flexDirection(String value) {
    setProperty('${Device.cssPrefix}flex-direction', value, '');
  }

  /** Gets the value of "flex-flow" */
  String get flexFlow =>
    getPropertyValue('${Device.cssPrefix}flex-flow');

  /** Sets the value of "flex-flow" */
  void set flexFlow(String value) {
    setProperty('${Device.cssPrefix}flex-flow', value, '');
  }

  /** Gets the value of "flex-grow" */
  String get flexGrow =>
    getPropertyValue('${Device.cssPrefix}flex-grow');

  /** Sets the value of "flex-grow" */
  void set flexGrow(String value) {
    setProperty('${Device.cssPrefix}flex-grow', value, '');
  }

  /** Gets the value of "flex-shrink" */
  String get flexShrink =>
    getPropertyValue('${Device.cssPrefix}flex-shrink');

  /** Sets the value of "flex-shrink" */
  void set flexShrink(String value) {
    setProperty('${Device.cssPrefix}flex-shrink', value, '');
  }

  /** Gets the value of "flex-wrap" */
  String get flexWrap =>
    getPropertyValue('${Device.cssPrefix}flex-wrap');

  /** Sets the value of "flex-wrap" */
  void set flexWrap(String value) {
    setProperty('${Device.cssPrefix}flex-wrap', value, '');
  }

  /** Gets the value of "float" */
  String get float =>
    getPropertyValue('float');

  /** Sets the value of "float" */
  void set float(String value) {
    setProperty('float', value, '');
  }

  /** Gets the value of "flow-from" */
  String get flowFrom =>
    getPropertyValue('${Device.cssPrefix}flow-from');

  /** Sets the value of "flow-from" */
  void set flowFrom(String value) {
    setProperty('${Device.cssPrefix}flow-from', value, '');
  }

  /** Gets the value of "flow-into" */
  String get flowInto =>
    getPropertyValue('${Device.cssPrefix}flow-into');

  /** Sets the value of "flow-into" */
  void set flowInto(String value) {
    setProperty('${Device.cssPrefix}flow-into', value, '');
  }

  /** Gets the value of "font" */
  String get font =>
    getPropertyValue('font');

  /** Sets the value of "font" */
  void set font(String value) {
    setProperty('font', value, '');
  }

  /** Gets the value of "font-family" */
  String get fontFamily =>
    getPropertyValue('font-family');

  /** Sets the value of "font-family" */
  void set fontFamily(String value) {
    setProperty('font-family', value, '');
  }

  /** Gets the value of "font-feature-settings" */
  String get fontFeatureSettings =>
    getPropertyValue('${Device.cssPrefix}font-feature-settings');

  /** Sets the value of "font-feature-settings" */
  void set fontFeatureSettings(String value) {
    setProperty('${Device.cssPrefix}font-feature-settings', value, '');
  }

  /** Gets the value of "font-kerning" */
  String get fontKerning =>
    getPropertyValue('${Device.cssPrefix}font-kerning');

  /** Sets the value of "font-kerning" */
  void set fontKerning(String value) {
    setProperty('${Device.cssPrefix}font-kerning', value, '');
  }

  /** Gets the value of "font-size" */
  String get fontSize =>
    getPropertyValue('font-size');

  /** Sets the value of "font-size" */
  void set fontSize(String value) {
    setProperty('font-size', value, '');
  }

  /** Gets the value of "font-size-delta" */
  String get fontSizeDelta =>
    getPropertyValue('${Device.cssPrefix}font-size-delta');

  /** Sets the value of "font-size-delta" */
  void set fontSizeDelta(String value) {
    setProperty('${Device.cssPrefix}font-size-delta', value, '');
  }

  /** Gets the value of "font-smoothing" */
  String get fontSmoothing =>
    getPropertyValue('${Device.cssPrefix}font-smoothing');

  /** Sets the value of "font-smoothing" */
  void set fontSmoothing(String value) {
    setProperty('${Device.cssPrefix}font-smoothing', value, '');
  }

  /** Gets the value of "font-stretch" */
  String get fontStretch =>
    getPropertyValue('font-stretch');

  /** Sets the value of "font-stretch" */
  void set fontStretch(String value) {
    setProperty('font-stretch', value, '');
  }

  /** Gets the value of "font-style" */
  String get fontStyle =>
    getPropertyValue('font-style');

  /** Sets the value of "font-style" */
  void set fontStyle(String value) {
    setProperty('font-style', value, '');
  }

  /** Gets the value of "font-variant" */
  String get fontVariant =>
    getPropertyValue('font-variant');

  /** Sets the value of "font-variant" */
  void set fontVariant(String value) {
    setProperty('font-variant', value, '');
  }

  /** Gets the value of "font-variant-ligatures" */
  String get fontVariantLigatures =>
    getPropertyValue('${Device.cssPrefix}font-variant-ligatures');

  /** Sets the value of "font-variant-ligatures" */
  void set fontVariantLigatures(String value) {
    setProperty('${Device.cssPrefix}font-variant-ligatures', value, '');
  }

  /** Gets the value of "font-weight" */
  String get fontWeight =>
    getPropertyValue('font-weight');

  /** Sets the value of "font-weight" */
  void set fontWeight(String value) {
    setProperty('font-weight', value, '');
  }

  /** Gets the value of "grid-column" */
  String get gridColumn =>
    getPropertyValue('${Device.cssPrefix}grid-column');

  /** Sets the value of "grid-column" */
  void set gridColumn(String value) {
    setProperty('${Device.cssPrefix}grid-column', value, '');
  }

  /** Gets the value of "grid-columns" */
  String get gridColumns =>
    getPropertyValue('${Device.cssPrefix}grid-columns');

  /** Sets the value of "grid-columns" */
  void set gridColumns(String value) {
    setProperty('${Device.cssPrefix}grid-columns', value, '');
  }

  /** Gets the value of "grid-row" */
  String get gridRow =>
    getPropertyValue('${Device.cssPrefix}grid-row');

  /** Sets the value of "grid-row" */
  void set gridRow(String value) {
    setProperty('${Device.cssPrefix}grid-row', value, '');
  }

  /** Gets the value of "grid-rows" */
  String get gridRows =>
    getPropertyValue('${Device.cssPrefix}grid-rows');

  /** Sets the value of "grid-rows" */
  void set gridRows(String value) {
    setProperty('${Device.cssPrefix}grid-rows', value, '');
  }

  /** Gets the value of "height" */
  String get height =>
    getPropertyValue('height');

  /** Sets the value of "height" */
  void set height(String value) {
    setProperty('height', value, '');
  }

  /** Gets the value of "highlight" */
  String get highlight =>
    getPropertyValue('${Device.cssPrefix}highlight');

  /** Sets the value of "highlight" */
  void set highlight(String value) {
    setProperty('${Device.cssPrefix}highlight', value, '');
  }

  /** Gets the value of "hyphenate-character" */
  String get hyphenateCharacter =>
    getPropertyValue('${Device.cssPrefix}hyphenate-character');

  /** Sets the value of "hyphenate-character" */
  void set hyphenateCharacter(String value) {
    setProperty('${Device.cssPrefix}hyphenate-character', value, '');
  }

  /** Gets the value of "hyphenate-limit-after" */
  String get hyphenateLimitAfter =>
    getPropertyValue('${Device.cssPrefix}hyphenate-limit-after');

  /** Sets the value of "hyphenate-limit-after" */
  void set hyphenateLimitAfter(String value) {
    setProperty('${Device.cssPrefix}hyphenate-limit-after', value, '');
  }

  /** Gets the value of "hyphenate-limit-before" */
  String get hyphenateLimitBefore =>
    getPropertyValue('${Device.cssPrefix}hyphenate-limit-before');

  /** Sets the value of "hyphenate-limit-before" */
  void set hyphenateLimitBefore(String value) {
    setProperty('${Device.cssPrefix}hyphenate-limit-before', value, '');
  }

  /** Gets the value of "hyphenate-limit-lines" */
  String get hyphenateLimitLines =>
    getPropertyValue('${Device.cssPrefix}hyphenate-limit-lines');

  /** Sets the value of "hyphenate-limit-lines" */
  void set hyphenateLimitLines(String value) {
    setProperty('${Device.cssPrefix}hyphenate-limit-lines', value, '');
  }

  /** Gets the value of "hyphens" */
  String get hyphens =>
    getPropertyValue('${Device.cssPrefix}hyphens');

  /** Sets the value of "hyphens" */
  void set hyphens(String value) {
    setProperty('${Device.cssPrefix}hyphens', value, '');
  }

  /** Gets the value of "image-orientation" */
  String get imageOrientation =>
    getPropertyValue('image-orientation');

  /** Sets the value of "image-orientation" */
  void set imageOrientation(String value) {
    setProperty('image-orientation', value, '');
  }

  /** Gets the value of "image-rendering" */
  String get imageRendering =>
    getPropertyValue('image-rendering');

  /** Sets the value of "image-rendering" */
  void set imageRendering(String value) {
    setProperty('image-rendering', value, '');
  }

  /** Gets the value of "image-resolution" */
  String get imageResolution =>
    getPropertyValue('image-resolution');

  /** Sets the value of "image-resolution" */
  void set imageResolution(String value) {
    setProperty('image-resolution', value, '');
  }

  /** Gets the value of "justify-content" */
  String get justifyContent =>
    getPropertyValue('${Device.cssPrefix}justify-content');

  /** Sets the value of "justify-content" */
  void set justifyContent(String value) {
    setProperty('${Device.cssPrefix}justify-content', value, '');
  }

  /** Gets the value of "left" */
  String get left =>
    getPropertyValue('left');

  /** Sets the value of "left" */
  void set left(String value) {
    setProperty('left', value, '');
  }

  /** Gets the value of "letter-spacing" */
  String get letterSpacing =>
    getPropertyValue('letter-spacing');

  /** Sets the value of "letter-spacing" */
  void set letterSpacing(String value) {
    setProperty('letter-spacing', value, '');
  }

  /** Gets the value of "line-align" */
  String get lineAlign =>
    getPropertyValue('${Device.cssPrefix}line-align');

  /** Sets the value of "line-align" */
  void set lineAlign(String value) {
    setProperty('${Device.cssPrefix}line-align', value, '');
  }

  /** Gets the value of "line-box-contain" */
  String get lineBoxContain =>
    getPropertyValue('${Device.cssPrefix}line-box-contain');

  /** Sets the value of "line-box-contain" */
  void set lineBoxContain(String value) {
    setProperty('${Device.cssPrefix}line-box-contain', value, '');
  }

  /** Gets the value of "line-break" */
  String get lineBreak =>
    getPropertyValue('${Device.cssPrefix}line-break');

  /** Sets the value of "line-break" */
  void set lineBreak(String value) {
    setProperty('${Device.cssPrefix}line-break', value, '');
  }

  /** Gets the value of "line-clamp" */
  String get lineClamp =>
    getPropertyValue('${Device.cssPrefix}line-clamp');

  /** Sets the value of "line-clamp" */
  void set lineClamp(String value) {
    setProperty('${Device.cssPrefix}line-clamp', value, '');
  }

  /** Gets the value of "line-grid" */
  String get lineGrid =>
    getPropertyValue('${Device.cssPrefix}line-grid');

  /** Sets the value of "line-grid" */
  void set lineGrid(String value) {
    setProperty('${Device.cssPrefix}line-grid', value, '');
  }

  /** Gets the value of "line-height" */
  String get lineHeight =>
    getPropertyValue('line-height');

  /** Sets the value of "line-height" */
  void set lineHeight(String value) {
    setProperty('line-height', value, '');
  }

  /** Gets the value of "line-snap" */
  String get lineSnap =>
    getPropertyValue('${Device.cssPrefix}line-snap');

  /** Sets the value of "line-snap" */
  void set lineSnap(String value) {
    setProperty('${Device.cssPrefix}line-snap', value, '');
  }

  /** Gets the value of "list-style" */
  String get listStyle =>
    getPropertyValue('list-style');

  /** Sets the value of "list-style" */
  void set listStyle(String value) {
    setProperty('list-style', value, '');
  }

  /** Gets the value of "list-style-image" */
  String get listStyleImage =>
    getPropertyValue('list-style-image');

  /** Sets the value of "list-style-image" */
  void set listStyleImage(String value) {
    setProperty('list-style-image', value, '');
  }

  /** Gets the value of "list-style-position" */
  String get listStylePosition =>
    getPropertyValue('list-style-position');

  /** Sets the value of "list-style-position" */
  void set listStylePosition(String value) {
    setProperty('list-style-position', value, '');
  }

  /** Gets the value of "list-style-type" */
  String get listStyleType =>
    getPropertyValue('list-style-type');

  /** Sets the value of "list-style-type" */
  void set listStyleType(String value) {
    setProperty('list-style-type', value, '');
  }

  /** Gets the value of "locale" */
  String get locale =>
    getPropertyValue('${Device.cssPrefix}locale');

  /** Sets the value of "locale" */
  void set locale(String value) {
    setProperty('${Device.cssPrefix}locale', value, '');
  }

  /** Gets the value of "logical-height" */
  String get logicalHeight =>
    getPropertyValue('${Device.cssPrefix}logical-height');

  /** Sets the value of "logical-height" */
  void set logicalHeight(String value) {
    setProperty('${Device.cssPrefix}logical-height', value, '');
  }

  /** Gets the value of "logical-width" */
  String get logicalWidth =>
    getPropertyValue('${Device.cssPrefix}logical-width');

  /** Sets the value of "logical-width" */
  void set logicalWidth(String value) {
    setProperty('${Device.cssPrefix}logical-width', value, '');
  }

  /** Gets the value of "margin" */
  String get margin =>
    getPropertyValue('margin');

  /** Sets the value of "margin" */
  void set margin(String value) {
    setProperty('margin', value, '');
  }

  /** Gets the value of "margin-after" */
  String get marginAfter =>
    getPropertyValue('${Device.cssPrefix}margin-after');

  /** Sets the value of "margin-after" */
  void set marginAfter(String value) {
    setProperty('${Device.cssPrefix}margin-after', value, '');
  }

  /** Gets the value of "margin-after-collapse" */
  String get marginAfterCollapse =>
    getPropertyValue('${Device.cssPrefix}margin-after-collapse');

  /** Sets the value of "margin-after-collapse" */
  void set marginAfterCollapse(String value) {
    setProperty('${Device.cssPrefix}margin-after-collapse', value, '');
  }

  /** Gets the value of "margin-before" */
  String get marginBefore =>
    getPropertyValue('${Device.cssPrefix}margin-before');

  /** Sets the value of "margin-before" */
  void set marginBefore(String value) {
    setProperty('${Device.cssPrefix}margin-before', value, '');
  }

  /** Gets the value of "margin-before-collapse" */
  String get marginBeforeCollapse =>
    getPropertyValue('${Device.cssPrefix}margin-before-collapse');

  /** Sets the value of "margin-before-collapse" */
  void set marginBeforeCollapse(String value) {
    setProperty('${Device.cssPrefix}margin-before-collapse', value, '');
  }

  /** Gets the value of "margin-bottom" */
  String get marginBottom =>
    getPropertyValue('margin-bottom');

  /** Sets the value of "margin-bottom" */
  void set marginBottom(String value) {
    setProperty('margin-bottom', value, '');
  }

  /** Gets the value of "margin-bottom-collapse" */
  String get marginBottomCollapse =>
    getPropertyValue('${Device.cssPrefix}margin-bottom-collapse');

  /** Sets the value of "margin-bottom-collapse" */
  void set marginBottomCollapse(String value) {
    setProperty('${Device.cssPrefix}margin-bottom-collapse', value, '');
  }

  /** Gets the value of "margin-collapse" */
  String get marginCollapse =>
    getPropertyValue('${Device.cssPrefix}margin-collapse');

  /** Sets the value of "margin-collapse" */
  void set marginCollapse(String value) {
    setProperty('${Device.cssPrefix}margin-collapse', value, '');
  }

  /** Gets the value of "margin-end" */
  String get marginEnd =>
    getPropertyValue('${Device.cssPrefix}margin-end');

  /** Sets the value of "margin-end" */
  void set marginEnd(String value) {
    setProperty('${Device.cssPrefix}margin-end', value, '');
  }

  /** Gets the value of "margin-left" */
  String get marginLeft =>
    getPropertyValue('margin-left');

  /** Sets the value of "margin-left" */
  void set marginLeft(String value) {
    setProperty('margin-left', value, '');
  }

  /** Gets the value of "margin-right" */
  String get marginRight =>
    getPropertyValue('margin-right');

  /** Sets the value of "margin-right" */
  void set marginRight(String value) {
    setProperty('margin-right', value, '');
  }

  /** Gets the value of "margin-start" */
  String get marginStart =>
    getPropertyValue('${Device.cssPrefix}margin-start');

  /** Sets the value of "margin-start" */
  void set marginStart(String value) {
    setProperty('${Device.cssPrefix}margin-start', value, '');
  }

  /** Gets the value of "margin-top" */
  String get marginTop =>
    getPropertyValue('margin-top');

  /** Sets the value of "margin-top" */
  void set marginTop(String value) {
    setProperty('margin-top', value, '');
  }

  /** Gets the value of "margin-top-collapse" */
  String get marginTopCollapse =>
    getPropertyValue('${Device.cssPrefix}margin-top-collapse');

  /** Sets the value of "margin-top-collapse" */
  void set marginTopCollapse(String value) {
    setProperty('${Device.cssPrefix}margin-top-collapse', value, '');
  }

  /** Gets the value of "marquee" */
  String get marquee =>
    getPropertyValue('${Device.cssPrefix}marquee');

  /** Sets the value of "marquee" */
  void set marquee(String value) {
    setProperty('${Device.cssPrefix}marquee', value, '');
  }

  /** Gets the value of "marquee-direction" */
  String get marqueeDirection =>
    getPropertyValue('${Device.cssPrefix}marquee-direction');

  /** Sets the value of "marquee-direction" */
  void set marqueeDirection(String value) {
    setProperty('${Device.cssPrefix}marquee-direction', value, '');
  }

  /** Gets the value of "marquee-increment" */
  String get marqueeIncrement =>
    getPropertyValue('${Device.cssPrefix}marquee-increment');

  /** Sets the value of "marquee-increment" */
  void set marqueeIncrement(String value) {
    setProperty('${Device.cssPrefix}marquee-increment', value, '');
  }

  /** Gets the value of "marquee-repetition" */
  String get marqueeRepetition =>
    getPropertyValue('${Device.cssPrefix}marquee-repetition');

  /** Sets the value of "marquee-repetition" */
  void set marqueeRepetition(String value) {
    setProperty('${Device.cssPrefix}marquee-repetition', value, '');
  }

  /** Gets the value of "marquee-speed" */
  String get marqueeSpeed =>
    getPropertyValue('${Device.cssPrefix}marquee-speed');

  /** Sets the value of "marquee-speed" */
  void set marqueeSpeed(String value) {
    setProperty('${Device.cssPrefix}marquee-speed', value, '');
  }

  /** Gets the value of "marquee-style" */
  String get marqueeStyle =>
    getPropertyValue('${Device.cssPrefix}marquee-style');

  /** Sets the value of "marquee-style" */
  void set marqueeStyle(String value) {
    setProperty('${Device.cssPrefix}marquee-style', value, '');
  }

  /** Gets the value of "mask" */
  String get mask =>
    getPropertyValue('${Device.cssPrefix}mask');

  /** Sets the value of "mask" */
  void set mask(String value) {
    setProperty('${Device.cssPrefix}mask', value, '');
  }

  /** Gets the value of "mask-attachment" */
  String get maskAttachment =>
    getPropertyValue('${Device.cssPrefix}mask-attachment');

  /** Sets the value of "mask-attachment" */
  void set maskAttachment(String value) {
    setProperty('${Device.cssPrefix}mask-attachment', value, '');
  }

  /** Gets the value of "mask-box-image" */
  String get maskBoxImage =>
    getPropertyValue('${Device.cssPrefix}mask-box-image');

  /** Sets the value of "mask-box-image" */
  void set maskBoxImage(String value) {
    setProperty('${Device.cssPrefix}mask-box-image', value, '');
  }

  /** Gets the value of "mask-box-image-outset" */
  String get maskBoxImageOutset =>
    getPropertyValue('${Device.cssPrefix}mask-box-image-outset');

  /** Sets the value of "mask-box-image-outset" */
  void set maskBoxImageOutset(String value) {
    setProperty('${Device.cssPrefix}mask-box-image-outset', value, '');
  }

  /** Gets the value of "mask-box-image-repeat" */
  String get maskBoxImageRepeat =>
    getPropertyValue('${Device.cssPrefix}mask-box-image-repeat');

  /** Sets the value of "mask-box-image-repeat" */
  void set maskBoxImageRepeat(String value) {
    setProperty('${Device.cssPrefix}mask-box-image-repeat', value, '');
  }

  /** Gets the value of "mask-box-image-slice" */
  String get maskBoxImageSlice =>
    getPropertyValue('${Device.cssPrefix}mask-box-image-slice');

  /** Sets the value of "mask-box-image-slice" */
  void set maskBoxImageSlice(String value) {
    setProperty('${Device.cssPrefix}mask-box-image-slice', value, '');
  }

  /** Gets the value of "mask-box-image-source" */
  String get maskBoxImageSource =>
    getPropertyValue('${Device.cssPrefix}mask-box-image-source');

  /** Sets the value of "mask-box-image-source" */
  void set maskBoxImageSource(String value) {
    setProperty('${Device.cssPrefix}mask-box-image-source', value, '');
  }

  /** Gets the value of "mask-box-image-width" */
  String get maskBoxImageWidth =>
    getPropertyValue('${Device.cssPrefix}mask-box-image-width');

  /** Sets the value of "mask-box-image-width" */
  void set maskBoxImageWidth(String value) {
    setProperty('${Device.cssPrefix}mask-box-image-width', value, '');
  }

  /** Gets the value of "mask-clip" */
  String get maskClip =>
    getPropertyValue('${Device.cssPrefix}mask-clip');

  /** Sets the value of "mask-clip" */
  void set maskClip(String value) {
    setProperty('${Device.cssPrefix}mask-clip', value, '');
  }

  /** Gets the value of "mask-composite" */
  String get maskComposite =>
    getPropertyValue('${Device.cssPrefix}mask-composite');

  /** Sets the value of "mask-composite" */
  void set maskComposite(String value) {
    setProperty('${Device.cssPrefix}mask-composite', value, '');
  }

  /** Gets the value of "mask-image" */
  String get maskImage =>
    getPropertyValue('${Device.cssPrefix}mask-image');

  /** Sets the value of "mask-image" */
  void set maskImage(String value) {
    setProperty('${Device.cssPrefix}mask-image', value, '');
  }

  /** Gets the value of "mask-origin" */
  String get maskOrigin =>
    getPropertyValue('${Device.cssPrefix}mask-origin');

  /** Sets the value of "mask-origin" */
  void set maskOrigin(String value) {
    setProperty('${Device.cssPrefix}mask-origin', value, '');
  }

  /** Gets the value of "mask-position" */
  String get maskPosition =>
    getPropertyValue('${Device.cssPrefix}mask-position');

  /** Sets the value of "mask-position" */
  void set maskPosition(String value) {
    setProperty('${Device.cssPrefix}mask-position', value, '');
  }

  /** Gets the value of "mask-position-x" */
  String get maskPositionX =>
    getPropertyValue('${Device.cssPrefix}mask-position-x');

  /** Sets the value of "mask-position-x" */
  void set maskPositionX(String value) {
    setProperty('${Device.cssPrefix}mask-position-x', value, '');
  }

  /** Gets the value of "mask-position-y" */
  String get maskPositionY =>
    getPropertyValue('${Device.cssPrefix}mask-position-y');

  /** Sets the value of "mask-position-y" */
  void set maskPositionY(String value) {
    setProperty('${Device.cssPrefix}mask-position-y', value, '');
  }

  /** Gets the value of "mask-repeat" */
  String get maskRepeat =>
    getPropertyValue('${Device.cssPrefix}mask-repeat');

  /** Sets the value of "mask-repeat" */
  void set maskRepeat(String value) {
    setProperty('${Device.cssPrefix}mask-repeat', value, '');
  }

  /** Gets the value of "mask-repeat-x" */
  String get maskRepeatX =>
    getPropertyValue('${Device.cssPrefix}mask-repeat-x');

  /** Sets the value of "mask-repeat-x" */
  void set maskRepeatX(String value) {
    setProperty('${Device.cssPrefix}mask-repeat-x', value, '');
  }

  /** Gets the value of "mask-repeat-y" */
  String get maskRepeatY =>
    getPropertyValue('${Device.cssPrefix}mask-repeat-y');

  /** Sets the value of "mask-repeat-y" */
  void set maskRepeatY(String value) {
    setProperty('${Device.cssPrefix}mask-repeat-y', value, '');
  }

  /** Gets the value of "mask-size" */
  String get maskSize =>
    getPropertyValue('${Device.cssPrefix}mask-size');

  /** Sets the value of "mask-size" */
  void set maskSize(String value) {
    setProperty('${Device.cssPrefix}mask-size', value, '');
  }

  /** Gets the value of "max-height" */
  String get maxHeight =>
    getPropertyValue('max-height');

  /** Sets the value of "max-height" */
  void set maxHeight(String value) {
    setProperty('max-height', value, '');
  }

  /** Gets the value of "max-logical-height" */
  String get maxLogicalHeight =>
    getPropertyValue('${Device.cssPrefix}max-logical-height');

  /** Sets the value of "max-logical-height" */
  void set maxLogicalHeight(String value) {
    setProperty('${Device.cssPrefix}max-logical-height', value, '');
  }

  /** Gets the value of "max-logical-width" */
  String get maxLogicalWidth =>
    getPropertyValue('${Device.cssPrefix}max-logical-width');

  /** Sets the value of "max-logical-width" */
  void set maxLogicalWidth(String value) {
    setProperty('${Device.cssPrefix}max-logical-width', value, '');
  }

  /** Gets the value of "max-width" */
  String get maxWidth =>
    getPropertyValue('max-width');

  /** Sets the value of "max-width" */
  void set maxWidth(String value) {
    setProperty('max-width', value, '');
  }

  /** Gets the value of "max-zoom" */
  String get maxZoom =>
    getPropertyValue('max-zoom');

  /** Sets the value of "max-zoom" */
  void set maxZoom(String value) {
    setProperty('max-zoom', value, '');
  }

  /** Gets the value of "min-height" */
  String get minHeight =>
    getPropertyValue('min-height');

  /** Sets the value of "min-height" */
  void set minHeight(String value) {
    setProperty('min-height', value, '');
  }

  /** Gets the value of "min-logical-height" */
  String get minLogicalHeight =>
    getPropertyValue('${Device.cssPrefix}min-logical-height');

  /** Sets the value of "min-logical-height" */
  void set minLogicalHeight(String value) {
    setProperty('${Device.cssPrefix}min-logical-height', value, '');
  }

  /** Gets the value of "min-logical-width" */
  String get minLogicalWidth =>
    getPropertyValue('${Device.cssPrefix}min-logical-width');

  /** Sets the value of "min-logical-width" */
  void set minLogicalWidth(String value) {
    setProperty('${Device.cssPrefix}min-logical-width', value, '');
  }

  /** Gets the value of "min-width" */
  String get minWidth =>
    getPropertyValue('min-width');

  /** Sets the value of "min-width" */
  void set minWidth(String value) {
    setProperty('min-width', value, '');
  }

  /** Gets the value of "min-zoom" */
  String get minZoom =>
    getPropertyValue('min-zoom');

  /** Sets the value of "min-zoom" */
  void set minZoom(String value) {
    setProperty('min-zoom', value, '');
  }

  /** Gets the value of "nbsp-mode" */
  String get nbspMode =>
    getPropertyValue('${Device.cssPrefix}nbsp-mode');

  /** Sets the value of "nbsp-mode" */
  void set nbspMode(String value) {
    setProperty('${Device.cssPrefix}nbsp-mode', value, '');
  }

  /** Gets the value of "opacity" */
  String get opacity =>
    getPropertyValue('opacity');

  /** Sets the value of "opacity" */
  void set opacity(String value) {
    setProperty('opacity', value, '');
  }

  /** Gets the value of "order" */
  String get order =>
    getPropertyValue('${Device.cssPrefix}order');

  /** Sets the value of "order" */
  void set order(String value) {
    setProperty('${Device.cssPrefix}order', value, '');
  }

  /** Gets the value of "orientation" */
  String get orientation =>
    getPropertyValue('orientation');

  /** Sets the value of "orientation" */
  void set orientation(String value) {
    setProperty('orientation', value, '');
  }

  /** Gets the value of "orphans" */
  String get orphans =>
    getPropertyValue('orphans');

  /** Sets the value of "orphans" */
  void set orphans(String value) {
    setProperty('orphans', value, '');
  }

  /** Gets the value of "outline" */
  String get outline =>
    getPropertyValue('outline');

  /** Sets the value of "outline" */
  void set outline(String value) {
    setProperty('outline', value, '');
  }

  /** Gets the value of "outline-color" */
  String get outlineColor =>
    getPropertyValue('outline-color');

  /** Sets the value of "outline-color" */
  void set outlineColor(String value) {
    setProperty('outline-color', value, '');
  }

  /** Gets the value of "outline-offset" */
  String get outlineOffset =>
    getPropertyValue('outline-offset');

  /** Sets the value of "outline-offset" */
  void set outlineOffset(String value) {
    setProperty('outline-offset', value, '');
  }

  /** Gets the value of "outline-style" */
  String get outlineStyle =>
    getPropertyValue('outline-style');

  /** Sets the value of "outline-style" */
  void set outlineStyle(String value) {
    setProperty('outline-style', value, '');
  }

  /** Gets the value of "outline-width" */
  String get outlineWidth =>
    getPropertyValue('outline-width');

  /** Sets the value of "outline-width" */
  void set outlineWidth(String value) {
    setProperty('outline-width', value, '');
  }

  /** Gets the value of "overflow" */
  String get overflow =>
    getPropertyValue('overflow');

  /** Sets the value of "overflow" */
  void set overflow(String value) {
    setProperty('overflow', value, '');
  }

  /** Gets the value of "overflow-scrolling" */
  String get overflowScrolling =>
    getPropertyValue('${Device.cssPrefix}overflow-scrolling');

  /** Sets the value of "overflow-scrolling" */
  void set overflowScrolling(String value) {
    setProperty('${Device.cssPrefix}overflow-scrolling', value, '');
  }

  /** Gets the value of "overflow-wrap" */
  String get overflowWrap =>
    getPropertyValue('overflow-wrap');

  /** Sets the value of "overflow-wrap" */
  void set overflowWrap(String value) {
    setProperty('overflow-wrap', value, '');
  }

  /** Gets the value of "overflow-x" */
  String get overflowX =>
    getPropertyValue('overflow-x');

  /** Sets the value of "overflow-x" */
  void set overflowX(String value) {
    setProperty('overflow-x', value, '');
  }

  /** Gets the value of "overflow-y" */
  String get overflowY =>
    getPropertyValue('overflow-y');

  /** Sets the value of "overflow-y" */
  void set overflowY(String value) {
    setProperty('overflow-y', value, '');
  }

  /** Gets the value of "padding" */
  String get padding =>
    getPropertyValue('padding');

  /** Sets the value of "padding" */
  void set padding(String value) {
    setProperty('padding', value, '');
  }

  /** Gets the value of "padding-after" */
  String get paddingAfter =>
    getPropertyValue('${Device.cssPrefix}padding-after');

  /** Sets the value of "padding-after" */
  void set paddingAfter(String value) {
    setProperty('${Device.cssPrefix}padding-after', value, '');
  }

  /** Gets the value of "padding-before" */
  String get paddingBefore =>
    getPropertyValue('${Device.cssPrefix}padding-before');

  /** Sets the value of "padding-before" */
  void set paddingBefore(String value) {
    setProperty('${Device.cssPrefix}padding-before', value, '');
  }

  /** Gets the value of "padding-bottom" */
  String get paddingBottom =>
    getPropertyValue('padding-bottom');

  /** Sets the value of "padding-bottom" */
  void set paddingBottom(String value) {
    setProperty('padding-bottom', value, '');
  }

  /** Gets the value of "padding-end" */
  String get paddingEnd =>
    getPropertyValue('${Device.cssPrefix}padding-end');

  /** Sets the value of "padding-end" */
  void set paddingEnd(String value) {
    setProperty('${Device.cssPrefix}padding-end', value, '');
  }

  /** Gets the value of "padding-left" */
  String get paddingLeft =>
    getPropertyValue('padding-left');

  /** Sets the value of "padding-left" */
  void set paddingLeft(String value) {
    setProperty('padding-left', value, '');
  }

  /** Gets the value of "padding-right" */
  String get paddingRight =>
    getPropertyValue('padding-right');

  /** Sets the value of "padding-right" */
  void set paddingRight(String value) {
    setProperty('padding-right', value, '');
  }

  /** Gets the value of "padding-start" */
  String get paddingStart =>
    getPropertyValue('${Device.cssPrefix}padding-start');

  /** Sets the value of "padding-start" */
  void set paddingStart(String value) {
    setProperty('${Device.cssPrefix}padding-start', value, '');
  }

  /** Gets the value of "padding-top" */
  String get paddingTop =>
    getPropertyValue('padding-top');

  /** Sets the value of "padding-top" */
  void set paddingTop(String value) {
    setProperty('padding-top', value, '');
  }

  /** Gets the value of "page" */
  String get page =>
    getPropertyValue('page');

  /** Sets the value of "page" */
  void set page(String value) {
    setProperty('page', value, '');
  }

  /** Gets the value of "page-break-after" */
  String get pageBreakAfter =>
    getPropertyValue('page-break-after');

  /** Sets the value of "page-break-after" */
  void set pageBreakAfter(String value) {
    setProperty('page-break-after', value, '');
  }

  /** Gets the value of "page-break-before" */
  String get pageBreakBefore =>
    getPropertyValue('page-break-before');

  /** Sets the value of "page-break-before" */
  void set pageBreakBefore(String value) {
    setProperty('page-break-before', value, '');
  }

  /** Gets the value of "page-break-inside" */
  String get pageBreakInside =>
    getPropertyValue('page-break-inside');

  /** Sets the value of "page-break-inside" */
  void set pageBreakInside(String value) {
    setProperty('page-break-inside', value, '');
  }

  /** Gets the value of "perspective" */
  String get perspective =>
    getPropertyValue('${Device.cssPrefix}perspective');

  /** Sets the value of "perspective" */
  void set perspective(String value) {
    setProperty('${Device.cssPrefix}perspective', value, '');
  }

  /** Gets the value of "perspective-origin" */
  String get perspectiveOrigin =>
    getPropertyValue('${Device.cssPrefix}perspective-origin');

  /** Sets the value of "perspective-origin" */
  void set perspectiveOrigin(String value) {
    setProperty('${Device.cssPrefix}perspective-origin', value, '');
  }

  /** Gets the value of "perspective-origin-x" */
  String get perspectiveOriginX =>
    getPropertyValue('${Device.cssPrefix}perspective-origin-x');

  /** Sets the value of "perspective-origin-x" */
  void set perspectiveOriginX(String value) {
    setProperty('${Device.cssPrefix}perspective-origin-x', value, '');
  }

  /** Gets the value of "perspective-origin-y" */
  String get perspectiveOriginY =>
    getPropertyValue('${Device.cssPrefix}perspective-origin-y');

  /** Sets the value of "perspective-origin-y" */
  void set perspectiveOriginY(String value) {
    setProperty('${Device.cssPrefix}perspective-origin-y', value, '');
  }

  /** Gets the value of "pointer-events" */
  String get pointerEvents =>
    getPropertyValue('pointer-events');

  /** Sets the value of "pointer-events" */
  void set pointerEvents(String value) {
    setProperty('pointer-events', value, '');
  }

  /** Gets the value of "position" */
  String get position =>
    getPropertyValue('position');

  /** Sets the value of "position" */
  void set position(String value) {
    setProperty('position', value, '');
  }

  /** Gets the value of "print-color-adjust" */
  String get printColorAdjust =>
    getPropertyValue('${Device.cssPrefix}print-color-adjust');

  /** Sets the value of "print-color-adjust" */
  void set printColorAdjust(String value) {
    setProperty('${Device.cssPrefix}print-color-adjust', value, '');
  }

  /** Gets the value of "quotes" */
  String get quotes =>
    getPropertyValue('quotes');

  /** Sets the value of "quotes" */
  void set quotes(String value) {
    setProperty('quotes', value, '');
  }

  /** Gets the value of "region-break-after" */
  String get regionBreakAfter =>
    getPropertyValue('${Device.cssPrefix}region-break-after');

  /** Sets the value of "region-break-after" */
  void set regionBreakAfter(String value) {
    setProperty('${Device.cssPrefix}region-break-after', value, '');
  }

  /** Gets the value of "region-break-before" */
  String get regionBreakBefore =>
    getPropertyValue('${Device.cssPrefix}region-break-before');

  /** Sets the value of "region-break-before" */
  void set regionBreakBefore(String value) {
    setProperty('${Device.cssPrefix}region-break-before', value, '');
  }

  /** Gets the value of "region-break-inside" */
  String get regionBreakInside =>
    getPropertyValue('${Device.cssPrefix}region-break-inside');

  /** Sets the value of "region-break-inside" */
  void set regionBreakInside(String value) {
    setProperty('${Device.cssPrefix}region-break-inside', value, '');
  }

  /** Gets the value of "region-overflow" */
  String get regionOverflow =>
    getPropertyValue('${Device.cssPrefix}region-overflow');

  /** Sets the value of "region-overflow" */
  void set regionOverflow(String value) {
    setProperty('${Device.cssPrefix}region-overflow', value, '');
  }

  /** Gets the value of "resize" */
  String get resize =>
    getPropertyValue('resize');

  /** Sets the value of "resize" */
  void set resize(String value) {
    setProperty('resize', value, '');
  }

  /** Gets the value of "right" */
  String get right =>
    getPropertyValue('right');

  /** Sets the value of "right" */
  void set right(String value) {
    setProperty('right', value, '');
  }

  /** Gets the value of "rtl-ordering" */
  String get rtlOrdering =>
    getPropertyValue('${Device.cssPrefix}rtl-ordering');

  /** Sets the value of "rtl-ordering" */
  void set rtlOrdering(String value) {
    setProperty('${Device.cssPrefix}rtl-ordering', value, '');
  }

  /** Gets the value of "shape-inside" */
  String get shapeInside =>
    getPropertyValue('${Device.cssPrefix}shape-inside');

  /** Sets the value of "shape-inside" */
  void set shapeInside(String value) {
    setProperty('${Device.cssPrefix}shape-inside', value, '');
  }

  /** Gets the value of "shape-margin" */
  String get shapeMargin =>
    getPropertyValue('${Device.cssPrefix}shape-margin');

  /** Sets the value of "shape-margin" */
  void set shapeMargin(String value) {
    setProperty('${Device.cssPrefix}shape-margin', value, '');
  }

  /** Gets the value of "shape-outside" */
  String get shapeOutside =>
    getPropertyValue('${Device.cssPrefix}shape-outside');

  /** Sets the value of "shape-outside" */
  void set shapeOutside(String value) {
    setProperty('${Device.cssPrefix}shape-outside', value, '');
  }

  /** Gets the value of "shape-padding" */
  String get shapePadding =>
    getPropertyValue('${Device.cssPrefix}shape-padding');

  /** Sets the value of "shape-padding" */
  void set shapePadding(String value) {
    setProperty('${Device.cssPrefix}shape-padding', value, '');
  }

  /** Gets the value of "size" */
  String get size =>
    getPropertyValue('size');

  /** Sets the value of "size" */
  void set size(String value) {
    setProperty('size', value, '');
  }

  /** Gets the value of "speak" */
  String get speak =>
    getPropertyValue('speak');

  /** Sets the value of "speak" */
  void set speak(String value) {
    setProperty('speak', value, '');
  }

  /** Gets the value of "src" */
  String get src =>
    getPropertyValue('src');

  /** Sets the value of "src" */
  void set src(String value) {
    setProperty('src', value, '');
  }

  /** Gets the value of "tab-size" */
  String get tabSize =>
    getPropertyValue('tab-size');

  /** Sets the value of "tab-size" */
  void set tabSize(String value) {
    setProperty('tab-size', value, '');
  }

  /** Gets the value of "table-layout" */
  String get tableLayout =>
    getPropertyValue('table-layout');

  /** Sets the value of "table-layout" */
  void set tableLayout(String value) {
    setProperty('table-layout', value, '');
  }

  /** Gets the value of "tap-highlight-color" */
  String get tapHighlightColor =>
    getPropertyValue('${Device.cssPrefix}tap-highlight-color');

  /** Sets the value of "tap-highlight-color" */
  void set tapHighlightColor(String value) {
    setProperty('${Device.cssPrefix}tap-highlight-color', value, '');
  }

  /** Gets the value of "text-align" */
  String get textAlign =>
    getPropertyValue('text-align');

  /** Sets the value of "text-align" */
  void set textAlign(String value) {
    setProperty('text-align', value, '');
  }

  /** Gets the value of "text-align-last" */
  String get textAlignLast =>
    getPropertyValue('${Device.cssPrefix}text-align-last');

  /** Sets the value of "text-align-last" */
  void set textAlignLast(String value) {
    setProperty('${Device.cssPrefix}text-align-last', value, '');
  }

  /** Gets the value of "text-combine" */
  String get textCombine =>
    getPropertyValue('${Device.cssPrefix}text-combine');

  /** Sets the value of "text-combine" */
  void set textCombine(String value) {
    setProperty('${Device.cssPrefix}text-combine', value, '');
  }

  /** Gets the value of "text-decoration" */
  String get textDecoration =>
    getPropertyValue('text-decoration');

  /** Sets the value of "text-decoration" */
  void set textDecoration(String value) {
    setProperty('text-decoration', value, '');
  }

  /** Gets the value of "text-decoration-line" */
  String get textDecorationLine =>
    getPropertyValue('${Device.cssPrefix}text-decoration-line');

  /** Sets the value of "text-decoration-line" */
  void set textDecorationLine(String value) {
    setProperty('${Device.cssPrefix}text-decoration-line', value, '');
  }

  /** Gets the value of "text-decoration-style" */
  String get textDecorationStyle =>
    getPropertyValue('${Device.cssPrefix}text-decoration-style');

  /** Sets the value of "text-decoration-style" */
  void set textDecorationStyle(String value) {
    setProperty('${Device.cssPrefix}text-decoration-style', value, '');
  }

  /** Gets the value of "text-decorations-in-effect" */
  String get textDecorationsInEffect =>
    getPropertyValue('${Device.cssPrefix}text-decorations-in-effect');

  /** Sets the value of "text-decorations-in-effect" */
  void set textDecorationsInEffect(String value) {
    setProperty('${Device.cssPrefix}text-decorations-in-effect', value, '');
  }

  /** Gets the value of "text-emphasis" */
  String get textEmphasis =>
    getPropertyValue('${Device.cssPrefix}text-emphasis');

  /** Sets the value of "text-emphasis" */
  void set textEmphasis(String value) {
    setProperty('${Device.cssPrefix}text-emphasis', value, '');
  }

  /** Gets the value of "text-emphasis-color" */
  String get textEmphasisColor =>
    getPropertyValue('${Device.cssPrefix}text-emphasis-color');

  /** Sets the value of "text-emphasis-color" */
  void set textEmphasisColor(String value) {
    setProperty('${Device.cssPrefix}text-emphasis-color', value, '');
  }

  /** Gets the value of "text-emphasis-position" */
  String get textEmphasisPosition =>
    getPropertyValue('${Device.cssPrefix}text-emphasis-position');

  /** Sets the value of "text-emphasis-position" */
  void set textEmphasisPosition(String value) {
    setProperty('${Device.cssPrefix}text-emphasis-position', value, '');
  }

  /** Gets the value of "text-emphasis-style" */
  String get textEmphasisStyle =>
    getPropertyValue('${Device.cssPrefix}text-emphasis-style');

  /** Sets the value of "text-emphasis-style" */
  void set textEmphasisStyle(String value) {
    setProperty('${Device.cssPrefix}text-emphasis-style', value, '');
  }

  /** Gets the value of "text-fill-color" */
  String get textFillColor =>
    getPropertyValue('${Device.cssPrefix}text-fill-color');

  /** Sets the value of "text-fill-color" */
  void set textFillColor(String value) {
    setProperty('${Device.cssPrefix}text-fill-color', value, '');
  }

  /** Gets the value of "text-indent" */
  String get textIndent =>
    getPropertyValue('text-indent');

  /** Sets the value of "text-indent" */
  void set textIndent(String value) {
    setProperty('text-indent', value, '');
  }

  /** Gets the value of "text-line-through" */
  String get textLineThrough =>
    getPropertyValue('text-line-through');

  /** Sets the value of "text-line-through" */
  void set textLineThrough(String value) {
    setProperty('text-line-through', value, '');
  }

  /** Gets the value of "text-line-through-color" */
  String get textLineThroughColor =>
    getPropertyValue('text-line-through-color');

  /** Sets the value of "text-line-through-color" */
  void set textLineThroughColor(String value) {
    setProperty('text-line-through-color', value, '');
  }

  /** Gets the value of "text-line-through-mode" */
  String get textLineThroughMode =>
    getPropertyValue('text-line-through-mode');

  /** Sets the value of "text-line-through-mode" */
  void set textLineThroughMode(String value) {
    setProperty('text-line-through-mode', value, '');
  }

  /** Gets the value of "text-line-through-style" */
  String get textLineThroughStyle =>
    getPropertyValue('text-line-through-style');

  /** Sets the value of "text-line-through-style" */
  void set textLineThroughStyle(String value) {
    setProperty('text-line-through-style', value, '');
  }

  /** Gets the value of "text-line-through-width" */
  String get textLineThroughWidth =>
    getPropertyValue('text-line-through-width');

  /** Sets the value of "text-line-through-width" */
  void set textLineThroughWidth(String value) {
    setProperty('text-line-through-width', value, '');
  }

  /** Gets the value of "text-orientation" */
  String get textOrientation =>
    getPropertyValue('${Device.cssPrefix}text-orientation');

  /** Sets the value of "text-orientation" */
  void set textOrientation(String value) {
    setProperty('${Device.cssPrefix}text-orientation', value, '');
  }

  /** Gets the value of "text-overflow" */
  String get textOverflow =>
    getPropertyValue('text-overflow');

  /** Sets the value of "text-overflow" */
  void set textOverflow(String value) {
    setProperty('text-overflow', value, '');
  }

  /** Gets the value of "text-overline" */
  String get textOverline =>
    getPropertyValue('text-overline');

  /** Sets the value of "text-overline" */
  void set textOverline(String value) {
    setProperty('text-overline', value, '');
  }

  /** Gets the value of "text-overline-color" */
  String get textOverlineColor =>
    getPropertyValue('text-overline-color');

  /** Sets the value of "text-overline-color" */
  void set textOverlineColor(String value) {
    setProperty('text-overline-color', value, '');
  }

  /** Gets the value of "text-overline-mode" */
  String get textOverlineMode =>
    getPropertyValue('text-overline-mode');

  /** Sets the value of "text-overline-mode" */
  void set textOverlineMode(String value) {
    setProperty('text-overline-mode', value, '');
  }

  /** Gets the value of "text-overline-style" */
  String get textOverlineStyle =>
    getPropertyValue('text-overline-style');

  /** Sets the value of "text-overline-style" */
  void set textOverlineStyle(String value) {
    setProperty('text-overline-style', value, '');
  }

  /** Gets the value of "text-overline-width" */
  String get textOverlineWidth =>
    getPropertyValue('text-overline-width');

  /** Sets the value of "text-overline-width" */
  void set textOverlineWidth(String value) {
    setProperty('text-overline-width', value, '');
  }

  /** Gets the value of "text-rendering" */
  String get textRendering =>
    getPropertyValue('text-rendering');

  /** Sets the value of "text-rendering" */
  void set textRendering(String value) {
    setProperty('text-rendering', value, '');
  }

  /** Gets the value of "text-security" */
  String get textSecurity =>
    getPropertyValue('${Device.cssPrefix}text-security');

  /** Sets the value of "text-security" */
  void set textSecurity(String value) {
    setProperty('${Device.cssPrefix}text-security', value, '');
  }

  /** Gets the value of "text-shadow" */
  String get textShadow =>
    getPropertyValue('text-shadow');

  /** Sets the value of "text-shadow" */
  void set textShadow(String value) {
    setProperty('text-shadow', value, '');
  }

  /** Gets the value of "text-size-adjust" */
  String get textSizeAdjust =>
    getPropertyValue('${Device.cssPrefix}text-size-adjust');

  /** Sets the value of "text-size-adjust" */
  void set textSizeAdjust(String value) {
    setProperty('${Device.cssPrefix}text-size-adjust', value, '');
  }

  /** Gets the value of "text-stroke" */
  String get textStroke =>
    getPropertyValue('${Device.cssPrefix}text-stroke');

  /** Sets the value of "text-stroke" */
  void set textStroke(String value) {
    setProperty('${Device.cssPrefix}text-stroke', value, '');
  }

  /** Gets the value of "text-stroke-color" */
  String get textStrokeColor =>
    getPropertyValue('${Device.cssPrefix}text-stroke-color');

  /** Sets the value of "text-stroke-color" */
  void set textStrokeColor(String value) {
    setProperty('${Device.cssPrefix}text-stroke-color', value, '');
  }

  /** Gets the value of "text-stroke-width" */
  String get textStrokeWidth =>
    getPropertyValue('${Device.cssPrefix}text-stroke-width');

  /** Sets the value of "text-stroke-width" */
  void set textStrokeWidth(String value) {
    setProperty('${Device.cssPrefix}text-stroke-width', value, '');
  }

  /** Gets the value of "text-transform" */
  String get textTransform =>
    getPropertyValue('text-transform');

  /** Sets the value of "text-transform" */
  void set textTransform(String value) {
    setProperty('text-transform', value, '');
  }

  /** Gets the value of "text-underline" */
  String get textUnderline =>
    getPropertyValue('text-underline');

  /** Sets the value of "text-underline" */
  void set textUnderline(String value) {
    setProperty('text-underline', value, '');
  }

  /** Gets the value of "text-underline-color" */
  String get textUnderlineColor =>
    getPropertyValue('text-underline-color');

  /** Sets the value of "text-underline-color" */
  void set textUnderlineColor(String value) {
    setProperty('text-underline-color', value, '');
  }

  /** Gets the value of "text-underline-mode" */
  String get textUnderlineMode =>
    getPropertyValue('text-underline-mode');

  /** Sets the value of "text-underline-mode" */
  void set textUnderlineMode(String value) {
    setProperty('text-underline-mode', value, '');
  }

  /** Gets the value of "text-underline-style" */
  String get textUnderlineStyle =>
    getPropertyValue('text-underline-style');

  /** Sets the value of "text-underline-style" */
  void set textUnderlineStyle(String value) {
    setProperty('text-underline-style', value, '');
  }

  /** Gets the value of "text-underline-width" */
  String get textUnderlineWidth =>
    getPropertyValue('text-underline-width');

  /** Sets the value of "text-underline-width" */
  void set textUnderlineWidth(String value) {
    setProperty('text-underline-width', value, '');
  }

  /** Gets the value of "top" */
  String get top =>
    getPropertyValue('top');

  /** Sets the value of "top" */
  void set top(String value) {
    setProperty('top', value, '');
  }

  /** Gets the value of "transform" */
  String get transform =>
    getPropertyValue('${Device.cssPrefix}transform');

  /** Sets the value of "transform" */
  void set transform(String value) {
    setProperty('${Device.cssPrefix}transform', value, '');
  }

  /** Gets the value of "transform-origin" */
  String get transformOrigin =>
    getPropertyValue('${Device.cssPrefix}transform-origin');

  /** Sets the value of "transform-origin" */
  void set transformOrigin(String value) {
    setProperty('${Device.cssPrefix}transform-origin', value, '');
  }

  /** Gets the value of "transform-origin-x" */
  String get transformOriginX =>
    getPropertyValue('${Device.cssPrefix}transform-origin-x');

  /** Sets the value of "transform-origin-x" */
  void set transformOriginX(String value) {
    setProperty('${Device.cssPrefix}transform-origin-x', value, '');
  }

  /** Gets the value of "transform-origin-y" */
  String get transformOriginY =>
    getPropertyValue('${Device.cssPrefix}transform-origin-y');

  /** Sets the value of "transform-origin-y" */
  void set transformOriginY(String value) {
    setProperty('${Device.cssPrefix}transform-origin-y', value, '');
  }

  /** Gets the value of "transform-origin-z" */
  String get transformOriginZ =>
    getPropertyValue('${Device.cssPrefix}transform-origin-z');

  /** Sets the value of "transform-origin-z" */
  void set transformOriginZ(String value) {
    setProperty('${Device.cssPrefix}transform-origin-z', value, '');
  }

  /** Gets the value of "transform-style" */
  String get transformStyle =>
    getPropertyValue('${Device.cssPrefix}transform-style');

  /** Sets the value of "transform-style" */
  void set transformStyle(String value) {
    setProperty('${Device.cssPrefix}transform-style', value, '');
  }

  /** Gets the value of "transition" */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  String get transition =>
    getPropertyValue('${Device.cssPrefix}transition');

  /** Sets the value of "transition" */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void set transition(String value) {
    setProperty('${Device.cssPrefix}transition', value, '');
  }

  /** Gets the value of "transition-delay" */
  String get transitionDelay =>
    getPropertyValue('${Device.cssPrefix}transition-delay');

  /** Sets the value of "transition-delay" */
  void set transitionDelay(String value) {
    setProperty('${Device.cssPrefix}transition-delay', value, '');
  }

  /** Gets the value of "transition-duration" */
  String get transitionDuration =>
    getPropertyValue('${Device.cssPrefix}transition-duration');

  /** Sets the value of "transition-duration" */
  void set transitionDuration(String value) {
    setProperty('${Device.cssPrefix}transition-duration', value, '');
  }

  /** Gets the value of "transition-property" */
  String get transitionProperty =>
    getPropertyValue('${Device.cssPrefix}transition-property');

  /** Sets the value of "transition-property" */
  void set transitionProperty(String value) {
    setProperty('${Device.cssPrefix}transition-property', value, '');
  }

  /** Gets the value of "transition-timing-function" */
  String get transitionTimingFunction =>
    getPropertyValue('${Device.cssPrefix}transition-timing-function');

  /** Sets the value of "transition-timing-function" */
  void set transitionTimingFunction(String value) {
    setProperty('${Device.cssPrefix}transition-timing-function', value, '');
  }

  /** Gets the value of "unicode-bidi" */
  String get unicodeBidi =>
    getPropertyValue('unicode-bidi');

  /** Sets the value of "unicode-bidi" */
  void set unicodeBidi(String value) {
    setProperty('unicode-bidi', value, '');
  }

  /** Gets the value of "unicode-range" */
  String get unicodeRange =>
    getPropertyValue('unicode-range');

  /** Sets the value of "unicode-range" */
  void set unicodeRange(String value) {
    setProperty('unicode-range', value, '');
  }

  /** Gets the value of "user-drag" */
  String get userDrag =>
    getPropertyValue('${Device.cssPrefix}user-drag');

  /** Sets the value of "user-drag" */
  void set userDrag(String value) {
    setProperty('${Device.cssPrefix}user-drag', value, '');
  }

  /** Gets the value of "user-modify" */
  String get userModify =>
    getPropertyValue('${Device.cssPrefix}user-modify');

  /** Sets the value of "user-modify" */
  void set userModify(String value) {
    setProperty('${Device.cssPrefix}user-modify', value, '');
  }

  /** Gets the value of "user-select" */
  String get userSelect =>
    getPropertyValue('${Device.cssPrefix}user-select');

  /** Sets the value of "user-select" */
  void set userSelect(String value) {
    setProperty('${Device.cssPrefix}user-select', value, '');
  }

  /** Gets the value of "user-zoom" */
  String get userZoom =>
    getPropertyValue('user-zoom');

  /** Sets the value of "user-zoom" */
  void set userZoom(String value) {
    setProperty('user-zoom', value, '');
  }

  /** Gets the value of "vertical-align" */
  String get verticalAlign =>
    getPropertyValue('vertical-align');

  /** Sets the value of "vertical-align" */
  void set verticalAlign(String value) {
    setProperty('vertical-align', value, '');
  }

  /** Gets the value of "visibility" */
  String get visibility =>
    getPropertyValue('visibility');

  /** Sets the value of "visibility" */
  void set visibility(String value) {
    setProperty('visibility', value, '');
  }

  /** Gets the value of "white-space" */
  String get whiteSpace =>
    getPropertyValue('white-space');

  /** Sets the value of "white-space" */
  void set whiteSpace(String value) {
    setProperty('white-space', value, '');
  }

  /** Gets the value of "widows" */
  String get widows =>
    getPropertyValue('widows');

  /** Sets the value of "widows" */
  void set widows(String value) {
    setProperty('widows', value, '');
  }

  /** Gets the value of "width" */
  String get width =>
    getPropertyValue('width');

  /** Sets the value of "width" */
  void set width(String value) {
    setProperty('width', value, '');
  }

  /** Gets the value of "word-break" */
  String get wordBreak =>
    getPropertyValue('word-break');

  /** Sets the value of "word-break" */
  void set wordBreak(String value) {
    setProperty('word-break', value, '');
  }

  /** Gets the value of "word-spacing" */
  String get wordSpacing =>
    getPropertyValue('word-spacing');

  /** Sets the value of "word-spacing" */
  void set wordSpacing(String value) {
    setProperty('word-spacing', value, '');
  }

  /** Gets the value of "word-wrap" */
  String get wordWrap =>
    getPropertyValue('word-wrap');

  /** Sets the value of "word-wrap" */
  void set wordWrap(String value) {
    setProperty('word-wrap', value, '');
  }

  /** Gets the value of "wrap" */
  String get wrap =>
    getPropertyValue('${Device.cssPrefix}wrap');

  /** Sets the value of "wrap" */
  void set wrap(String value) {
    setProperty('${Device.cssPrefix}wrap', value, '');
  }

  /** Gets the value of "wrap-flow" */
  String get wrapFlow =>
    getPropertyValue('${Device.cssPrefix}wrap-flow');

  /** Sets the value of "wrap-flow" */
  void set wrapFlow(String value) {
    setProperty('${Device.cssPrefix}wrap-flow', value, '');
  }

  /** Gets the value of "wrap-through" */
  String get wrapThrough =>
    getPropertyValue('${Device.cssPrefix}wrap-through');

  /** Sets the value of "wrap-through" */
  void set wrapThrough(String value) {
    setProperty('${Device.cssPrefix}wrap-through', value, '');
  }

  /** Gets the value of "writing-mode" */
  String get writingMode =>
    getPropertyValue('${Device.cssPrefix}writing-mode');

  /** Sets the value of "writing-mode" */
  void set writingMode(String value) {
    setProperty('${Device.cssPrefix}writing-mode', value, '');
  }

  /** Gets the value of "z-index" */
  String get zIndex =>
    getPropertyValue('z-index');

  /** Sets the value of "z-index" */
  void set zIndex(String value) {
    setProperty('z-index', value, '');
  }

  /** Gets the value of "zoom" */
  String get zoom =>
    getPropertyValue('zoom');

  /** Sets the value of "zoom" */
  void set zoom(String value) {
    setProperty('zoom', value, '');
  }
}
// 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.


@DocsEditable()
@DomName('CSSStyleRule')
class CssStyleRule extends CssRule native "CSSStyleRule" {
  // To suppress missing implicit constructor warnings.
  factory CssStyleRule._() { throw new UnsupportedError("Not supported"); }

  @DomName('CSSStyleRule.selectorText')
  @DocsEditable()
  String selectorText;

  @DomName('CSSStyleRule.style')
  @DocsEditable()
  final CssStyleDeclaration style;
}
// 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.


@DocsEditable()
@DomName('CSSStyleSheet')
class CssStyleSheet extends StyleSheet native "CSSStyleSheet" {
  // To suppress missing implicit constructor warnings.
  factory CssStyleSheet._() { throw new UnsupportedError("Not supported"); }

  @DomName('CSSStyleSheet.cssRules')
  @DocsEditable()
  @Returns('_CssRuleList')
  @Creates('_CssRuleList')
  final List<CssRule> cssRules;

  @DomName('CSSStyleSheet.ownerRule')
  @DocsEditable()
  final CssRule ownerRule;

  @DomName('CSSStyleSheet.rules')
  @DocsEditable()
  @Experimental() // non-standard
  @Returns('_CssRuleList')
  @Creates('_CssRuleList')
  final List<CssRule> rules;

  @DomName('CSSStyleSheet.addRule')
  @DocsEditable()
  @Experimental() // non-standard
  int addRule(String selector, String style, [int index]) native;

  @DomName('CSSStyleSheet.deleteRule')
  @DocsEditable()
  void deleteRule(int index) native;

  @DomName('CSSStyleSheet.insertRule')
  @DocsEditable()
  int insertRule(String rule, [int index]) native;

  @DomName('CSSStyleSheet.removeRule')
  @DocsEditable()
  @Experimental() // non-standard
  void removeRule(int index) native;
}
// 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.


@DocsEditable()
@DomName('CSSSupportsRule')
class CssSupportsRule extends CssRule native "CSSSupportsRule" {
  // To suppress missing implicit constructor warnings.
  factory CssSupportsRule._() { throw new UnsupportedError("Not supported"); }

  @DomName('CSSSupportsRule.conditionText')
  @DocsEditable()
  final String conditionText;

  @DomName('CSSSupportsRule.cssRules')
  @DocsEditable()
  @Returns('_CssRuleList')
  @Creates('_CssRuleList')
  final List<CssRule> cssRules;

  @DomName('CSSSupportsRule.deleteRule')
  @DocsEditable()
  void deleteRule(int index) native;

  @DomName('CSSSupportsRule.insertRule')
  @DocsEditable()
  int insertRule(String rule, int index) native;
}
// 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.


@DocsEditable()
@DomName('CSSViewportRule')
@Experimental() // untriaged
class CssViewportRule extends CssRule native "CSSViewportRule" {
  // To suppress missing implicit constructor warnings.
  factory CssViewportRule._() { throw new UnsupportedError("Not supported"); }

  @DomName('CSSViewportRule.style')
  @DocsEditable()
  @Experimental() // untriaged
  final CssStyleDeclaration style;
}
// 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.


@DomName('CustomEvent')
class CustomEvent extends Event native "CustomEvent" {
    @Creates('Null')  // Set from Dart code; does not instantiate a native type.
  var _dartDetail;

  factory CustomEvent(String type,
      {bool canBubble: true, bool cancelable: true, Object detail}) {

    final CustomEvent e = document._createEvent('CustomEvent');

    e._dartDetail = detail;

    // Only try setting the detail if it's one of these types to avoid
    // first-chance exceptions. Can expand this list in the future as needed.
    if (detail is List || detail is Map || detail is String || detail is num) {
      try {
        detail = convertDartToNative_SerializedScriptValue(detail);
        e._initCustomEvent(type, canBubble, cancelable, detail);
      } catch(_) {
        e._initCustomEvent(type, canBubble, cancelable, null);
      }
    } else {
      e._initCustomEvent(type, canBubble, cancelable, null);
    }

    return e;
  }

  @DomName('CustomEvent.detail')
  get detail {
    if (_dartDetail != null) {
      return _dartDetail;
    }
    return _detail;
  }
  // To suppress missing implicit constructor warnings.
  factory CustomEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('CustomEvent._detail')
  @DocsEditable()
  @Experimental() // untriaged
  dynamic get _detail => convertNativeToDart_SerializedScriptValue(this._get__detail);
  @JSName('detail')
  @DomName('CustomEvent._detail')
  @DocsEditable()
  @Experimental() // untriaged
  @Creates('Null')
  final dynamic _get__detail;

  @JSName('initCustomEvent')
  @DomName('CustomEvent.initCustomEvent')
  @DocsEditable()
  void _initCustomEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Object detailArg) native;

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


@DocsEditable()
@DomName('HTMLDListElement')
class DListElement extends HtmlElement native "HTMLDListElement" {
  // To suppress missing implicit constructor warnings.
  factory DListElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLDListElement.HTMLDListElement')
  @DocsEditable()
  factory DListElement() => document.createElement("dl");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DListElement.created() : super.created();
}
// 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.


@DocsEditable()
@DomName('HTMLDataListElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
class DataListElement extends HtmlElement native "HTMLDataListElement" {
  // To suppress missing implicit constructor warnings.
  factory DataListElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLDataListElement.HTMLDataListElement')
  @DocsEditable()
  factory DataListElement() => document.createElement("datalist");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DataListElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('datalist');

  @DomName('HTMLDataListElement.options')
  @DocsEditable()
  @Returns('HtmlCollection')
  @Creates('HtmlCollection')
  final List<Node> options;
}
// 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.


@DocsEditable()
@DomName('Clipboard')
class DataTransfer extends Interceptor native "Clipboard,DataTransfer" {
  // To suppress missing implicit constructor warnings.
  factory DataTransfer._() { throw new UnsupportedError("Not supported"); }

  @DomName('Clipboard.dropEffect')
  @DocsEditable()
  String dropEffect;

  @DomName('Clipboard.effectAllowed')
  @DocsEditable()
  String effectAllowed;

  @DomName('Clipboard.files')
  @DocsEditable()
  @Returns('FileList')
  @Creates('FileList')
  final List<File> files;

  @DomName('Clipboard.items')
  @DocsEditable()
  final DataTransferItemList items;

  @DomName('Clipboard.types')
  @DocsEditable()
  final List<String> types;

  @DomName('Clipboard.clearData')
  @DocsEditable()
  void clearData([String type]) native;

  /**
   * Gets the data for the specified type.
   *
   * The data is only available from within a drop operation (such as an
   * [Element.onDrop] event) and will return null before the event is
   * triggered.
   *
   * Data transfer is prohibited across domains. If a drag originates
   * from content from another domain or protocol (HTTP vs HTTPS) then the
   * data cannot be accessed.
   *
   * The [type] can have values such as:
   *
   * * `'Text'`
   * * `'URL'`
   */
  @DomName('Clipboard.getData')
  @DocsEditable()
  String getData(String type) native;

  @DomName('Clipboard.setData')
  @DocsEditable()
  bool setData(String type, String data) native;

  @DomName('Clipboard.setDragImage')
  @DocsEditable()
  void setDragImage(Element image, int x, int y) native;
}
// 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.


@DocsEditable()
@DomName('DataTransferItem')
// http://www.w3.org/TR/2011/WD-html5-20110113/dnd.html#the-datatransferitem-interface
@Experimental()
class DataTransferItem extends Interceptor native "DataTransferItem" {
  // To suppress missing implicit constructor warnings.
  factory DataTransferItem._() { throw new UnsupportedError("Not supported"); }

  @DomName('DataTransferItem.kind')
  @DocsEditable()
  final String kind;

  @DomName('DataTransferItem.type')
  @DocsEditable()
  final String type;

  @DomName('DataTransferItem.getAsFile')
  @DocsEditable()
  Blob getAsFile() native;

  @JSName('getAsString')
  @DomName('DataTransferItem.getAsString')
  @DocsEditable()
  void _getAsString(_StringCallback callback) native;

  @JSName('getAsString')
  @DomName('DataTransferItem.getAsString')
  @DocsEditable()
  Future<String> getAsString() {
    var completer = new Completer<String>();
    _getAsString(
        (value) { completer.complete(value); });
    return completer.future;
  }

  @JSName('webkitGetAsEntry')
  @DomName('DataTransferItem.webkitGetAsEntry')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  Entry getAsEntry() native;
}
// 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.


@DocsEditable()
@DomName('DataTransferItemList')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#the-datatransferitemlist-interface
@Experimental()
class DataTransferItemList extends Interceptor native "DataTransferItemList" {
  // To suppress missing implicit constructor warnings.
  factory DataTransferItemList._() { throw new UnsupportedError("Not supported"); }

  @DomName('DataTransferItemList.length')
  @DocsEditable()
  final int length;

  @DomName('DataTransferItemList.__getter__')
  @DocsEditable()
  @Experimental() // untriaged
  DataTransferItem __getter__(int index) native;

  @DomName('DataTransferItemList.add')
  @DocsEditable()
  DataTransferItem add(data_OR_file, [String type]) native;

  @JSName('add')
  @DomName('DataTransferItemList.add')
  @DocsEditable()
  DataTransferItem addData(String data, String type) native;

  @JSName('add')
  @DomName('DataTransferItemList.add')
  @DocsEditable()
  DataTransferItem addFile(File file) native;

  @DomName('DataTransferItemList.clear')
  @DocsEditable()
  void clear() native;

  @DomName('DataTransferItemList.remove')
  @DocsEditable()
  @Experimental() // untriaged
  void remove(int index) native;


  DataTransferItem operator[] (int index) {
    return JS('DataTransferItem', '#[#]', this, index);
  }

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


@DomName('DatabaseCallback')
// http://www.w3.org/TR/webdatabase/#databasecallback
@Experimental() // deprecated
typedef void DatabaseCallback(database);
// 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.


@DocsEditable()
@DomName('DedicatedWorkerGlobalScope')
@Experimental() // untriaged
class DedicatedWorkerGlobalScope extends WorkerGlobalScope native "DedicatedWorkerGlobalScope" {
  // To suppress missing implicit constructor warnings.
  factory DedicatedWorkerGlobalScope._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [DedicatedWorkerGlobalScope].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('DedicatedWorkerGlobalScope.messageEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');

  @DomName('DedicatedWorkerGlobalScope.postMessage')
  @DocsEditable()
  @Experimental() // untriaged
  void postMessage(Object message, [List<MessagePort> messagePorts]) native;

  /// Stream of `message` events handled by this [DedicatedWorkerGlobalScope].
  @DomName('DedicatedWorkerGlobalScope.onmessage')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
}
// 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.


@DocsEditable()
@DomName('DeprecatedStorageInfo')
@Experimental() // untriaged
class DeprecatedStorageInfo extends Interceptor native "DeprecatedStorageInfo" {
  // To suppress missing implicit constructor warnings.
  factory DeprecatedStorageInfo._() { throw new UnsupportedError("Not supported"); }

  @DomName('DeprecatedStorageInfo.PERSISTENT')
  @DocsEditable()
  @Experimental() // untriaged
  static const int PERSISTENT = 1;

  @DomName('DeprecatedStorageInfo.TEMPORARY')
  @DocsEditable()
  @Experimental() // untriaged
  static const int TEMPORARY = 0;

  @DomName('DeprecatedStorageInfo.queryUsageAndQuota')
  @DocsEditable()
  @Experimental() // untriaged
  void queryUsageAndQuota(int storageType, [StorageUsageCallback usageCallback, StorageErrorCallback errorCallback]) native;

  @DomName('DeprecatedStorageInfo.requestQuota')
  @DocsEditable()
  @Experimental() // untriaged
  void requestQuota(int storageType, int newQuotaInBytes, [StorageQuotaCallback quotaCallback, StorageErrorCallback errorCallback]) native;
}
// 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.


@DocsEditable()
@DomName('DeprecatedStorageQuota')
@Experimental() // untriaged
class DeprecatedStorageQuota extends Interceptor native "DeprecatedStorageQuota" {
  // To suppress missing implicit constructor warnings.
  factory DeprecatedStorageQuota._() { throw new UnsupportedError("Not supported"); }

  @DomName('DeprecatedStorageQuota.queryUsageAndQuota')
  @DocsEditable()
  @Experimental() // untriaged
  void queryUsageAndQuota(StorageUsageCallback usageCallback, [StorageErrorCallback errorCallback]) native;

  @DomName('DeprecatedStorageQuota.requestQuota')
  @DocsEditable()
  @Experimental() // untriaged
  void requestQuota(int newQuotaInBytes, [StorageQuotaCallback quotaCallback, StorageErrorCallback errorCallback]) native;
}
// 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.


@DocsEditable()
@DomName('HTMLDetailsElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
class DetailsElement extends HtmlElement native "HTMLDetailsElement" {
  // To suppress missing implicit constructor warnings.
  factory DetailsElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLDetailsElement.HTMLDetailsElement')
  @DocsEditable()
  factory DetailsElement() => document.createElement("details");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DetailsElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('details');

  @DomName('HTMLDetailsElement.open')
  @DocsEditable()
  bool open;
}
// 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.


@DocsEditable()
@DomName('DeviceAcceleration')
// http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
@Experimental()
class DeviceAcceleration extends Interceptor native "DeviceAcceleration" {
  // To suppress missing implicit constructor warnings.
  factory DeviceAcceleration._() { throw new UnsupportedError("Not supported"); }

  @DomName('DeviceAcceleration.x')
  @DocsEditable()
  final double x;

  @DomName('DeviceAcceleration.y')
  @DocsEditable()
  final double y;

  @DomName('DeviceAcceleration.z')
  @DocsEditable()
  final double z;
}
// 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.


@DocsEditable()
@DomName('DeviceMotionEvent')
// http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
@Experimental()
class DeviceMotionEvent extends Event native "DeviceMotionEvent" {
  // To suppress missing implicit constructor warnings.
  factory DeviceMotionEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('DeviceMotionEvent.acceleration')
  @DocsEditable()
  final DeviceAcceleration acceleration;

  @DomName('DeviceMotionEvent.accelerationIncludingGravity')
  @DocsEditable()
  final DeviceAcceleration accelerationIncludingGravity;

  @DomName('DeviceMotionEvent.interval')
  @DocsEditable()
  final double interval;

  @DomName('DeviceMotionEvent.rotationRate')
  @DocsEditable()
  final DeviceRotationRate rotationRate;

  @DomName('DeviceMotionEvent.initDeviceMotionEvent')
  @DocsEditable()
  @Experimental() // untriaged
  void initDeviceMotionEvent(String type, bool bubbles, bool cancelable, DeviceAcceleration acceleration, DeviceAcceleration accelerationIncludingGravity, DeviceRotationRate rotationRate, num interval) native;
}
// 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.

// WARNING: Do not edit - generated code.

@DomName('DeviceOrientationEvent')
// http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
@Experimental()
class DeviceOrientationEvent extends Event native "DeviceOrientationEvent" {
  factory DeviceOrientationEvent(String type,
      {bool canBubble: true, bool cancelable: true, num alpha: 0, num beta: 0,
      num gamma: 0, bool absolute: false}) {
    var e = document._createEvent("DeviceOrientationEvent");
    e._initDeviceOrientationEvent(type, canBubble, cancelable, alpha, beta,
        gamma, absolute);
    return e;
  }
  // To suppress missing implicit constructor warnings.
  factory DeviceOrientationEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('DeviceOrientationEvent.absolute')
  @DocsEditable()
  final bool absolute;

  @DomName('DeviceOrientationEvent.alpha')
  @DocsEditable()
  final double alpha;

  @DomName('DeviceOrientationEvent.beta')
  @DocsEditable()
  final double beta;

  @DomName('DeviceOrientationEvent.gamma')
  @DocsEditable()
  final double gamma;

  @JSName('initDeviceOrientationEvent')
  @DomName('DeviceOrientationEvent.initDeviceOrientationEvent')
  @DocsEditable()
  void _initDeviceOrientationEvent(String type, bool bubbles, bool cancelable, num alpha, num beta, num gamma, bool absolute) native;

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


@DocsEditable()
@DomName('DeviceRotationRate')
// http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
@Experimental()
class DeviceRotationRate extends Interceptor native "DeviceRotationRate" {
  // To suppress missing implicit constructor warnings.
  factory DeviceRotationRate._() { throw new UnsupportedError("Not supported"); }

  @DomName('DeviceRotationRate.alpha')
  @DocsEditable()
  final double alpha;

  @DomName('DeviceRotationRate.beta')
  @DocsEditable()
  final double beta;

  @DomName('DeviceRotationRate.gamma')
  @DocsEditable()
  final double gamma;
}
// 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.


@DocsEditable()
@DomName('HTMLDialogElement')
@Unstable()
class DialogElement extends HtmlElement native "HTMLDialogElement" {
  // To suppress missing implicit constructor warnings.
  factory DialogElement._() { throw new UnsupportedError("Not supported"); }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DialogElement.created() : super.created();

  @DomName('HTMLDialogElement.open')
  @DocsEditable()
  bool open;

  @DomName('HTMLDialogElement.returnValue')
  @DocsEditable()
  @Experimental() // untriaged
  String returnValue;

  @DomName('HTMLDialogElement.close')
  @DocsEditable()
  void close(String returnValue) native;

  @DomName('HTMLDialogElement.show')
  @DocsEditable()
  void show() native;

  @DomName('HTMLDialogElement.showModal')
  @DocsEditable()
  void showModal() native;
}
// 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.


@DomName('DirectoryEntry')
// http://www.w3.org/TR/file-system-api/#the-directoryentry-interface
@Experimental()
class DirectoryEntry extends Entry native "DirectoryEntry" {

  /**
   * Create a new directory with the specified `path`. If `exclusive` is true,
   * the returned Future will complete with an error if a directory already
   * exists with the specified `path`.
   */
  Future<Entry> createDirectory(String path, {bool exclusive: false}) {
    return _getDirectory(path, options:
        {'create': true, 'exclusive': exclusive});
  }

  /**
   * Retrieve an already existing directory entry. The returned future will
   * result in an error if a directory at `path` does not exist or if the item
   * at `path` is not a directory.
   */
  Future<Entry> getDirectory(String path) {
    return _getDirectory(path);
  }

  /**
   * Create a new file with the specified `path`. If `exclusive` is true,
   * the returned Future will complete with an error if a file already
   * exists at the specified `path`.
   */
  Future<Entry> createFile(String path, {bool exclusive: false}) {
    return _getFile(path, options: {'create': true, 'exclusive': exclusive});
  }

  /**
   * Retrieve an already existing file entry. The returned future will
   * result in an error if a file at `path` does not exist or if the item at
   * `path` is not a file.
   */
  Future<Entry> getFile(String path) {
    return _getFile(path);
  }
  // To suppress missing implicit constructor warnings.
  factory DirectoryEntry._() { throw new UnsupportedError("Not supported"); }

  @DomName('DirectoryEntry.createReader')
  @DocsEditable()
  DirectoryReader createReader() native;

  @DomName('DirectoryEntry.getDirectory')
  @DocsEditable()
  void __getDirectory(String path, {Map options, _EntryCallback successCallback, _ErrorCallback errorCallback}) {
    if (errorCallback != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      __getDirectory_1(path, options_1, successCallback, errorCallback);
      return;
    }
    if (successCallback != null) {
      var options_2 = convertDartToNative_Dictionary(options);
      __getDirectory_2(path, options_2, successCallback);
      return;
    }
    if (options != null) {
      var options_3 = convertDartToNative_Dictionary(options);
      __getDirectory_3(path, options_3);
      return;
    }
    __getDirectory_4(path);
    return;
  }
  @JSName('getDirectory')
  @DomName('DirectoryEntry.getDirectory')
  @DocsEditable()
  void __getDirectory_1(path, options, _EntryCallback successCallback, _ErrorCallback errorCallback) native;
  @JSName('getDirectory')
  @DomName('DirectoryEntry.getDirectory')
  @DocsEditable()
  void __getDirectory_2(path, options, _EntryCallback successCallback) native;
  @JSName('getDirectory')
  @DomName('DirectoryEntry.getDirectory')
  @DocsEditable()
  void __getDirectory_3(path, options) native;
  @JSName('getDirectory')
  @DomName('DirectoryEntry.getDirectory')
  @DocsEditable()
  void __getDirectory_4(path) native;

  @JSName('getDirectory')
  @DomName('DirectoryEntry.getDirectory')
  @DocsEditable()
  Future<Entry> _getDirectory(String path, {Map options}) {
    var completer = new Completer<Entry>();
    __getDirectory(path, options : options,
        successCallback : (value) { completer.complete(value); },
        errorCallback : (error) { completer.completeError(error); });
    return completer.future;
  }

  @DomName('DirectoryEntry.getFile')
  @DocsEditable()
  void __getFile(String path, {Map options, _EntryCallback successCallback, _ErrorCallback errorCallback}) {
    if (errorCallback != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      __getFile_1(path, options_1, successCallback, errorCallback);
      return;
    }
    if (successCallback != null) {
      var options_2 = convertDartToNative_Dictionary(options);
      __getFile_2(path, options_2, successCallback);
      return;
    }
    if (options != null) {
      var options_3 = convertDartToNative_Dictionary(options);
      __getFile_3(path, options_3);
      return;
    }
    __getFile_4(path);
    return;
  }
  @JSName('getFile')
  @DomName('DirectoryEntry.getFile')
  @DocsEditable()
  void __getFile_1(path, options, _EntryCallback successCallback, _ErrorCallback errorCallback) native;
  @JSName('getFile')
  @DomName('DirectoryEntry.getFile')
  @DocsEditable()
  void __getFile_2(path, options, _EntryCallback successCallback) native;
  @JSName('getFile')
  @DomName('DirectoryEntry.getFile')
  @DocsEditable()
  void __getFile_3(path, options) native;
  @JSName('getFile')
  @DomName('DirectoryEntry.getFile')
  @DocsEditable()
  void __getFile_4(path) native;

  @JSName('getFile')
  @DomName('DirectoryEntry.getFile')
  @DocsEditable()
  Future<Entry> _getFile(String path, {Map options}) {
    var completer = new Completer<Entry>();
    __getFile(path, options : options,
        successCallback : (value) { completer.complete(value); },
        errorCallback : (error) { completer.completeError(error); });
    return completer.future;
  }

  @JSName('removeRecursively')
  @DomName('DirectoryEntry.removeRecursively')
  @DocsEditable()
  void _removeRecursively(VoidCallback successCallback, [_ErrorCallback errorCallback]) native;

  @JSName('removeRecursively')
  @DomName('DirectoryEntry.removeRecursively')
  @DocsEditable()
  Future removeRecursively() {
    var completer = new Completer();
    _removeRecursively(
        () { completer.complete(); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

}

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


@DocsEditable()
@DomName('DirectoryReader')
// http://www.w3.org/TR/file-system-api/#the-directoryreader-interface
@Experimental()
class DirectoryReader extends Interceptor native "DirectoryReader" {
  // To suppress missing implicit constructor warnings.
  factory DirectoryReader._() { throw new UnsupportedError("Not supported"); }

  @JSName('readEntries')
  @DomName('DirectoryReader.readEntries')
  @DocsEditable()
  void _readEntries(_EntriesCallback successCallback, [_ErrorCallback errorCallback]) native;

  @JSName('readEntries')
  @DomName('DirectoryReader.readEntries')
  @DocsEditable()
  Future<List<Entry>> readEntries() {
    var completer = new Completer<List<Entry>>();
    _readEntries(
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); });
    return completer.future;
  }
}
// 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.


@DocsEditable()
/**
 * A generic container for content on an HTML page;
 * corresponds to the &lt;div&gt; tag.
 *
 * The [DivElement] is a generic container and does not have any semantic
 * significance. It is functionally similar to [SpanElement].
 *
 * The [DivElement] is a block-level element, as opposed to [SpanElement],
 * which is an inline-level element.
 *
 * Example usage:
 *
 *     DivElement div = new DivElement();
 *     div.text = 'Here's my new DivElem
 *     document.body.elements.add(elem);
 *
 * See also:
 *
 * * [HTML <div> element](http://www.w3.org/TR/html-markup/div.html) from W3C.
 * * [Block-level element](http://www.w3.org/TR/CSS2/visuren.html#block-boxes) from W3C.
 * * [Inline-level element](http://www.w3.org/TR/CSS2/visuren.html#inline-boxes) from W3C.
 */
@DomName('HTMLDivElement')
class DivElement extends HtmlElement native "HTMLDivElement" {
  // To suppress missing implicit constructor warnings.
  factory DivElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLDivElement.HTMLDivElement')
  @DocsEditable()
  factory DivElement() => document.createElement("div");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DivElement.created() : super.created();
}
// 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.


@DocsEditable()
/**
 * The base class for all documents.
 *
 * Each web page loaded in the browser has its own [Document] object, which is
 * typically an [HtmlDocument].
 *
 * If you aren't comfortable with DOM concepts, see the Dart tutorial
 * [Target 2: Connect Dart & HTML](http://www.dartlang.org/docs/tutorials/connect-dart-html/).
 */
@DomName('Document')
class Document extends Node  native "Document"
{

  // To suppress missing implicit constructor warnings.
  factory Document._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `readystatechange` events to event
   * handlers that are not necessarily instances of [Document].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Document.readystatechangeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> readyStateChangeEvent = const EventStreamProvider<Event>('readystatechange');

  /**
   * Static factory designed to expose `securitypolicyviolation` events to event
   * handlers that are not necessarily instances of [Document].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Document.securitypolicyviolationEvent')
  @DocsEditable()
  // https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#widl-Document-onsecuritypolicyviolation
  @Experimental()
  static const EventStreamProvider<SecurityPolicyViolationEvent> securityPolicyViolationEvent = const EventStreamProvider<SecurityPolicyViolationEvent>('securitypolicyviolation');

  /**
   * Static factory designed to expose `selectionchange` events to event
   * handlers that are not necessarily instances of [Document].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Document.selectionchangeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> selectionChangeEvent = const EventStreamProvider<Event>('selectionchange');

  /**
   * Static factory designed to expose `pointerlockchange` events to event
   * handlers that are not necessarily instances of [Document].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Document.webkitpointerlockchangeEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html#widl-Document-onpointerlockchange
  static const EventStreamProvider<Event> pointerLockChangeEvent = const EventStreamProvider<Event>('webkitpointerlockchange');

  /**
   * Static factory designed to expose `pointerlockerror` events to event
   * handlers that are not necessarily instances of [Document].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Document.webkitpointerlockerrorEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html#widl-Document-onpointerlockerror
  static const EventStreamProvider<Event> pointerLockErrorEvent = const EventStreamProvider<Event>('webkitpointerlockerror');

  @DomName('Document.activeElement')
  @DocsEditable()
  @Experimental() // untriaged
  final Element activeElement;

  @JSName('body')
  @DomName('Document.body')
  @DocsEditable()
  HtmlElement _body;

  @DomName('Document.cookie')
  @DocsEditable()
  String cookie;

  @DomName('Document.currentScript')
  @DocsEditable()
  @Experimental() // untriaged
  final ScriptElement currentScript;

  @DomName('Document.window')
  @DocsEditable()
  @Experimental() // untriaged
  WindowBase get window => _convertNativeToDart_Window(this._get_window);
  @JSName('defaultView')
  @DomName('Document.window')
  @DocsEditable()
  @Experimental() // untriaged
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  @Creates('Window|=Object|Null')
  @Returns('Window|=Object|Null')
  final dynamic _get_window;

  @DomName('Document.documentElement')
  @DocsEditable()
  final Element documentElement;

  @DomName('Document.domain')
  @DocsEditable()
  final String domain;

  @DomName('Document.fonts')
  @DocsEditable()
  @Experimental() // untriaged
  final FontFaceSet fonts;

  @JSName('head')
  @DomName('Document.head')
  @DocsEditable()
  final HeadElement _head;

  @DomName('Document.hidden')
  @DocsEditable()
  @Experimental() // untriaged
  final bool hidden;

  @DomName('Document.implementation')
  @DocsEditable()
  final DomImplementation implementation;

  @JSName('lastModified')
  @DomName('Document.lastModified')
  @DocsEditable()
  final String _lastModified;

  @JSName('preferredStylesheetSet')
  @DomName('Document.preferredStylesheetSet')
  @DocsEditable()
  final String _preferredStylesheetSet;

  @DomName('Document.readyState')
  @DocsEditable()
  final String readyState;

  @JSName('referrer')
  @DomName('Document.referrer')
  @DocsEditable()
  final String _referrer;

  @DomName('Document.rootElement')
  @DocsEditable()
  @Experimental() // untriaged
  final SvgSvgElement rootElement;

  @JSName('selectedStylesheetSet')
  @DomName('Document.selectedStylesheetSet')
  @DocsEditable()
  String _selectedStylesheetSet;

  @JSName('styleSheets')
  @DomName('Document.styleSheets')
  @DocsEditable()
  @Returns('_StyleSheetList')
  @Creates('_StyleSheetList')
  final List<StyleSheet> _styleSheets;

  @DomName('Document.timeline')
  @DocsEditable()
  @Experimental() // untriaged
  final Timeline timeline;

  @JSName('title')
  @DomName('Document.title')
  @DocsEditable()
  String _title;

  @DomName('Document.visibilityState')
  @DocsEditable()
  @Experimental() // untriaged
  final String visibilityState;

  @JSName('webkitFullscreenElement')
  @DomName('Document.webkitFullscreenElement')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#dom-document-fullscreenelement
  final Element _webkitFullscreenElement;

  @JSName('webkitFullscreenEnabled')
  @DomName('Document.webkitFullscreenEnabled')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#dom-document-fullscreenenabled
  final bool _webkitFullscreenEnabled;

  @JSName('webkitHidden')
  @DomName('Document.webkitHidden')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/PageVisibility/Overview.html#document
  final bool _webkitHidden;

  @JSName('webkitPointerLockElement')
  @DomName('Document.webkitPointerLockElement')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html#widl-Document-pointerLockElement
  final Element _webkitPointerLockElement;

  @JSName('webkitVisibilityState')
  @DomName('Document.webkitVisibilityState')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/PageVisibility/Overview.html#dom-document-visibilitystate
  final String _webkitVisibilityState;

  @DomName('Document.adoptNode')
  @DocsEditable()
  Node adoptNode(Node node) native;

  @JSName('caretRangeFromPoint')
  @DomName('Document.caretRangeFromPoint')
  @DocsEditable()
  // http://www.w3.org/TR/2009/WD-cssom-view-20090804/#dom-documentview-caretrangefrompoint
  @Experimental()
  Range _caretRangeFromPoint(int x, int y) native;

  @DomName('Document.createDocumentFragment')
  @DocsEditable()
  DocumentFragment createDocumentFragment() native;

  @JSName('createElement')
  @DomName('Document.createElement')
  @DocsEditable()
  Element _createElement(String localName_OR_tagName, [String typeExtension]) native;

  @DomName('Document.createElementNS')
  @DocsEditable()
  Element createElementNS(String namespaceURI, String qualifiedName, [String typeExtension]) native;

  @JSName('createEvent')
  @DomName('Document.createEvent')
  @DocsEditable()
  Event _createEvent([String eventType]) native;

  @DomName('Document.createRange')
  @DocsEditable()
  Range createRange() native;

  @JSName('createTextNode')
  @DomName('Document.createTextNode')
  @DocsEditable()
  Text _createTextNode(String data) native;

  @DomName('Document.createTouch')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Touch _createTouch(Window window, EventTarget target, int identifier, int pageX, int pageY, int screenX, int screenY, int webkitRadiusX, int webkitRadiusY, num webkitRotationAngle, num webkitForce) {
    var target_1 = _convertDartToNative_EventTarget(target);
    return _createTouch_1(window, target_1, identifier, pageX, pageY, screenX, screenY, webkitRadiusX, webkitRadiusY, webkitRotationAngle, webkitForce);
  }
  @JSName('createTouch')
  @DomName('Document.createTouch')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Touch _createTouch_1(Window window, target, identifier, pageX, pageY, screenX, screenY, webkitRadiusX, webkitRadiusY, webkitRotationAngle, webkitForce) native;

  @JSName('elementFromPoint')
  @DomName('Document.elementFromPoint')
  @DocsEditable()
  Element _elementFromPoint(int x, int y) native;

  @DomName('Document.execCommand')
  @DocsEditable()
  bool execCommand(String command, bool userInterface, String value) native;

  @JSName('getCSSCanvasContext')
  @DomName('Document.getCSSCanvasContext')
  @DocsEditable()
  // https://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariCSSRef/Articles/Functions.html
  @Experimental() // non-standard
  CanvasRenderingContext _getCssCanvasContext(String contextId, String name, int width, int height) native;

  @DomName('Document.getElementById')
  @DocsEditable()
  Element getElementById(String elementId) native;

  @DomName('Document.getElementsByClassName')
  @DocsEditable()
  @Creates('NodeList|HtmlCollection')
  @Returns('NodeList|HtmlCollection')
  List<Node> getElementsByClassName(String classNames) native;

  @DomName('Document.getElementsByName')
  @DocsEditable()
  @Returns('NodeList')
  @Creates('NodeList')
  List<Node> getElementsByName(String elementName) native;

  @DomName('Document.getElementsByTagName')
  @DocsEditable()
  @Creates('NodeList|HtmlCollection')
  @Returns('NodeList|HtmlCollection')
  List<Node> getElementsByTagName(String localName) native;

  @DomName('Document.importNode')
  @DocsEditable()
  Node importNode(Node node, [bool deep]) native;

  @DomName('Document.queryCommandEnabled')
  @DocsEditable()
  bool queryCommandEnabled(String command) native;

  @DomName('Document.queryCommandIndeterm')
  @DocsEditable()
  bool queryCommandIndeterm(String command) native;

  @DomName('Document.queryCommandState')
  @DocsEditable()
  bool queryCommandState(String command) native;

  @DomName('Document.queryCommandSupported')
  @DocsEditable()
  bool queryCommandSupported(String command) native;

  @DomName('Document.queryCommandValue')
  @DocsEditable()
  String queryCommandValue(String command) native;

  /**
   * Finds the first descendant element of this document that matches the
   * specified group of selectors.
   *
   * Unless your webpage contains multiple documents, the top-level
   * [querySelector]
   * 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 element1 = document.querySelector('.className');
   *     var element2 = document.querySelector('#id');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  @DomName('Document.querySelector')
  @DocsEditable()
  Element querySelector(String selectors) native;

  @JSName('querySelectorAll')
  @DomName('Document.querySelectorAll')
  @DocsEditable()
  @Returns('NodeList')
  @Creates('NodeList')
  List<Node> _querySelectorAll(String selectors) native;

  @JSName('webkitExitFullscreen')
  @DomName('Document.webkitExitFullscreen')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#dom-document-exitfullscreen
  void _webkitExitFullscreen() native;

  @JSName('webkitExitPointerLock')
  @DomName('Document.webkitExitPointerLock')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html#widl-Document-exitPointerLock-void
  void _webkitExitPointerLock() native;

  // From ParentNode

  @JSName('childElementCount')
  @DomName('Document.childElementCount')
  @DocsEditable()
  final int _childElementCount;

  @JSName('children')
  @DomName('Document.children')
  @DocsEditable()
  @Returns('HtmlCollection')
  @Creates('HtmlCollection')
  final List<Node> _children;

  @JSName('firstElementChild')
  @DomName('Document.firstElementChild')
  @DocsEditable()
  final Element _firstElementChild;

  @JSName('lastElementChild')
  @DomName('Document.lastElementChild')
  @DocsEditable()
  final Element _lastElementChild;

  /// Stream of `abort` events handled by this [Document].
  @DomName('Document.onabort')
  @DocsEditable()
  Stream<Event> get onAbort => Element.abortEvent.forTarget(this);

  /// Stream of `beforecopy` events handled by this [Document].
  @DomName('Document.onbeforecopy')
  @DocsEditable()
  Stream<Event> get onBeforeCopy => Element.beforeCopyEvent.forTarget(this);

  /// Stream of `beforecut` events handled by this [Document].
  @DomName('Document.onbeforecut')
  @DocsEditable()
  Stream<Event> get onBeforeCut => Element.beforeCutEvent.forTarget(this);

  /// Stream of `beforepaste` events handled by this [Document].
  @DomName('Document.onbeforepaste')
  @DocsEditable()
  Stream<Event> get onBeforePaste => Element.beforePasteEvent.forTarget(this);

  /// Stream of `blur` events handled by this [Document].
  @DomName('Document.onblur')
  @DocsEditable()
  Stream<Event> get onBlur => Element.blurEvent.forTarget(this);

  /// Stream of `change` events handled by this [Document].
  @DomName('Document.onchange')
  @DocsEditable()
  Stream<Event> get onChange => Element.changeEvent.forTarget(this);

  /// Stream of `click` events handled by this [Document].
  @DomName('Document.onclick')
  @DocsEditable()
  Stream<MouseEvent> get onClick => Element.clickEvent.forTarget(this);

  /// Stream of `contextmenu` events handled by this [Document].
  @DomName('Document.oncontextmenu')
  @DocsEditable()
  Stream<MouseEvent> get onContextMenu => Element.contextMenuEvent.forTarget(this);

  /// Stream of `copy` events handled by this [Document].
  @DomName('Document.oncopy')
  @DocsEditable()
  Stream<Event> get onCopy => Element.copyEvent.forTarget(this);

  /// Stream of `cut` events handled by this [Document].
  @DomName('Document.oncut')
  @DocsEditable()
  Stream<Event> get onCut => Element.cutEvent.forTarget(this);

  /// Stream of `doubleclick` events handled by this [Document].
  @DomName('Document.ondblclick')
  @DocsEditable()
  Stream<Event> get onDoubleClick => Element.doubleClickEvent.forTarget(this);

  /// Stream of `drag` events handled by this [Document].
  @DomName('Document.ondrag')
  @DocsEditable()
  Stream<MouseEvent> get onDrag => Element.dragEvent.forTarget(this);

  /// Stream of `dragend` events handled by this [Document].
  @DomName('Document.ondragend')
  @DocsEditable()
  Stream<MouseEvent> get onDragEnd => Element.dragEndEvent.forTarget(this);

  /// Stream of `dragenter` events handled by this [Document].
  @DomName('Document.ondragenter')
  @DocsEditable()
  Stream<MouseEvent> get onDragEnter => Element.dragEnterEvent.forTarget(this);

  /// Stream of `dragleave` events handled by this [Document].
  @DomName('Document.ondragleave')
  @DocsEditable()
  Stream<MouseEvent> get onDragLeave => Element.dragLeaveEvent.forTarget(this);

  /// Stream of `dragover` events handled by this [Document].
  @DomName('Document.ondragover')
  @DocsEditable()
  Stream<MouseEvent> get onDragOver => Element.dragOverEvent.forTarget(this);

  /// Stream of `dragstart` events handled by this [Document].
  @DomName('Document.ondragstart')
  @DocsEditable()
  Stream<MouseEvent> get onDragStart => Element.dragStartEvent.forTarget(this);

  /// Stream of `drop` events handled by this [Document].
  @DomName('Document.ondrop')
  @DocsEditable()
  Stream<MouseEvent> get onDrop => Element.dropEvent.forTarget(this);

  /// Stream of `error` events handled by this [Document].
  @DomName('Document.onerror')
  @DocsEditable()
  Stream<Event> get onError => Element.errorEvent.forTarget(this);

  /// Stream of `focus` events handled by this [Document].
  @DomName('Document.onfocus')
  @DocsEditable()
  Stream<Event> get onFocus => Element.focusEvent.forTarget(this);

  /// Stream of `input` events handled by this [Document].
  @DomName('Document.oninput')
  @DocsEditable()
  Stream<Event> get onInput => Element.inputEvent.forTarget(this);

  /// Stream of `invalid` events handled by this [Document].
  @DomName('Document.oninvalid')
  @DocsEditable()
  Stream<Event> get onInvalid => Element.invalidEvent.forTarget(this);

  /// Stream of `keydown` events handled by this [Document].
  @DomName('Document.onkeydown')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyDown => Element.keyDownEvent.forTarget(this);

  /// Stream of `keypress` events handled by this [Document].
  @DomName('Document.onkeypress')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyPress => Element.keyPressEvent.forTarget(this);

  /// Stream of `keyup` events handled by this [Document].
  @DomName('Document.onkeyup')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyUp => Element.keyUpEvent.forTarget(this);

  /// Stream of `load` events handled by this [Document].
  @DomName('Document.onload')
  @DocsEditable()
  Stream<Event> get onLoad => Element.loadEvent.forTarget(this);

  /// Stream of `mousedown` events handled by this [Document].
  @DomName('Document.onmousedown')
  @DocsEditable()
  Stream<MouseEvent> get onMouseDown => Element.mouseDownEvent.forTarget(this);

  /// Stream of `mouseenter` events handled by this [Document].
  @DomName('Document.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseEnter => Element.mouseEnterEvent.forTarget(this);

  /// Stream of `mouseleave` events handled by this [Document].
  @DomName('Document.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseLeave => Element.mouseLeaveEvent.forTarget(this);

  /// Stream of `mousemove` events handled by this [Document].
  @DomName('Document.onmousemove')
  @DocsEditable()
  Stream<MouseEvent> get onMouseMove => Element.mouseMoveEvent.forTarget(this);

  /// Stream of `mouseout` events handled by this [Document].
  @DomName('Document.onmouseout')
  @DocsEditable()
  Stream<MouseEvent> get onMouseOut => Element.mouseOutEvent.forTarget(this);

  /// Stream of `mouseover` events handled by this [Document].
  @DomName('Document.onmouseover')
  @DocsEditable()
  Stream<MouseEvent> get onMouseOver => Element.mouseOverEvent.forTarget(this);

  /// Stream of `mouseup` events handled by this [Document].
  @DomName('Document.onmouseup')
  @DocsEditable()
  Stream<MouseEvent> get onMouseUp => Element.mouseUpEvent.forTarget(this);

  /// Stream of `mousewheel` events handled by this [Document].
  @DomName('Document.onmousewheel')
  @DocsEditable()
  Stream<WheelEvent> get onMouseWheel => Element.mouseWheelEvent.forTarget(this);

  /// Stream of `paste` events handled by this [Document].
  @DomName('Document.onpaste')
  @DocsEditable()
  Stream<Event> get onPaste => Element.pasteEvent.forTarget(this);

  /// Stream of `readystatechange` events handled by this [Document].
  @DomName('Document.onreadystatechange')
  @DocsEditable()
  Stream<Event> get onReadyStateChange => readyStateChangeEvent.forTarget(this);

  /// Stream of `reset` events handled by this [Document].
  @DomName('Document.onreset')
  @DocsEditable()
  Stream<Event> get onReset => Element.resetEvent.forTarget(this);

  @DomName('Document.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onResize => Element.resizeEvent.forTarget(this);

  /// Stream of `scroll` events handled by this [Document].
  @DomName('Document.onscroll')
  @DocsEditable()
  Stream<Event> get onScroll => Element.scrollEvent.forTarget(this);

  /// Stream of `search` events handled by this [Document].
  @DomName('Document.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  Stream<Event> get onSearch => Element.searchEvent.forTarget(this);

  /// Stream of `securitypolicyviolation` events handled by this [Document].
  @DomName('Document.onsecuritypolicyviolation')
  @DocsEditable()
  // https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#widl-Document-onsecuritypolicyviolation
  @Experimental()
  Stream<SecurityPolicyViolationEvent> get onSecurityPolicyViolation => securityPolicyViolationEvent.forTarget(this);

  /// Stream of `select` events handled by this [Document].
  @DomName('Document.onselect')
  @DocsEditable()
  Stream<Event> get onSelect => Element.selectEvent.forTarget(this);

  /// Stream of `selectionchange` events handled by this [Document].
  @DomName('Document.onselectionchange')
  @DocsEditable()
  Stream<Event> get onSelectionChange => selectionChangeEvent.forTarget(this);

  /// Stream of `selectstart` events handled by this [Document].
  @DomName('Document.onselectstart')
  @DocsEditable()
  Stream<Event> get onSelectStart => Element.selectStartEvent.forTarget(this);

  /// Stream of `submit` events handled by this [Document].
  @DomName('Document.onsubmit')
  @DocsEditable()
  Stream<Event> get onSubmit => Element.submitEvent.forTarget(this);

  /// Stream of `touchcancel` events handled by this [Document].
  @DomName('Document.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchCancel => Element.touchCancelEvent.forTarget(this);

  /// Stream of `touchend` events handled by this [Document].
  @DomName('Document.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchEnd => Element.touchEndEvent.forTarget(this);

  /// Stream of `touchmove` events handled by this [Document].
  @DomName('Document.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchMove => Element.touchMoveEvent.forTarget(this);

  /// Stream of `touchstart` events handled by this [Document].
  @DomName('Document.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchStart => Element.touchStartEvent.forTarget(this);

  /// Stream of `fullscreenchange` events handled by this [Document].
  @DomName('Document.onwebkitfullscreenchange')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  Stream<Event> get onFullscreenChange => Element.fullscreenChangeEvent.forTarget(this);

  /// Stream of `fullscreenerror` events handled by this [Document].
  @DomName('Document.onwebkitfullscreenerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  Stream<Event> get onFullscreenError => Element.fullscreenErrorEvent.forTarget(this);

  /// Stream of `pointerlockchange` events handled by this [Document].
  @DomName('Document.onwebkitpointerlockchange')
  @DocsEditable()
  // https://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html#widl-Document-onpointerlockchange
  @Experimental()
  Stream<Event> get onPointerLockChange => pointerLockChangeEvent.forTarget(this);

  /// Stream of `pointerlockerror` events handled by this [Document].
  @DomName('Document.onwebkitpointerlockerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html#widl-Document-onpointerlockerror
  @Experimental()
  Stream<Event> get onPointerLockError => pointerLockErrorEvent.forTarget(this);

  /**
   * 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 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 queryAll(String relativeSelectors) =>
      querySelectorAll(relativeSelectors);

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

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

  @DomName('Document.createElement')
  Element createElement(String tagName, [String typeExtension]) {
    return _createElement(tagName, typeExtension);
  }

  @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);
}
// 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.


@DomName('DocumentFragment')
class DocumentFragment extends Node implements ParentNode native "DocumentFragment" {
  factory DocumentFragment() => document.createDocumentFragment();

  factory DocumentFragment.html(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {

    return document.body.createFragment(html,
      validator: validator, treeSanitizer: treeSanitizer);
  }

  factory DocumentFragment.svg(String svgContent,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {

    return new svg.SvgSvgElement().createFragment(svgContent,
        validator: validator, treeSanitizer: treeSanitizer);
  }

  HtmlCollection get _children => throw new UnimplementedError(
      'Use _docChildren instead');

  // Native field is used only by Dart code so does not lead to instantiation
  // of native classes
  @Creates('Null')
  List<Element> _docChildren;

  List<Element> get children {
    if (_docChildren == null) {
      _docChildren = new FilteredElementList(this);
    }
    return _docChildren;
  }

  void set children(List<Element> value) {
    // Copy list first since we don't want liveness during iteration.
    List copy = new List.from(value);
    var children = this.children;
    children.clear();
    children.addAll(copy);
  }

  /**
   * Finds all descendant elements of this document fragment that match the
   * specified group of selectors.
   *
   * [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 querySelectorAll(String selectors) =>
    new _FrozenElementList._wrap(_querySelectorAll(selectors));



  String get innerHtml {
    final e = new Element.tag("div");
    e.append(this.clone(true));
    return e.innerHtml;
  }

  void set innerHtml(String value) {
    this.setInnerHtml(value);
  }

  void setInnerHtml(String html,
    {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {

    this.nodes.clear();
    append(document.body.createFragment(
        html, validator: validator, treeSanitizer: treeSanitizer));
  }

  /**
   * Adds the specified text as a text node after the last child of this
   * document fragment.
   */
  void appendText(String text) {
    this.append(new Text(text));
  }


  /**
   * Parses the specified text as HTML and adds the resulting node after the
   * last child of this document fragment.
   */
  void appendHtml(String text) {
    this.append(new DocumentFragment.html(text));
  }

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

  /** 
   * Alias for [querySelectorAll]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @Experimental()
  @DomName('DocumentFragment.querySelectorAll')
  ElementList queryAll(String relativeSelectors) {
    return querySelectorAll(relativeSelectors);
  }
  // To suppress missing implicit constructor warnings.
  factory DocumentFragment._() { throw new UnsupportedError("Not supported"); }

  /**
   * Finds the first descendant element of this document fragment that matches
   * the specified group of selectors.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var element1 = fragment.querySelector('.className');
   *     var element2 = fragment.querySelector('#id');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  @DomName('DocumentFragment.querySelector')
  @DocsEditable()
  Element querySelector(String selectors) native;

  @JSName('querySelectorAll')
  @DomName('DocumentFragment.querySelectorAll')
  @DocsEditable()
  @Returns('NodeList')
  @Creates('NodeList')
  List<Node> _querySelectorAll(String selectors) native;

  // From ParentNode

  @JSName('childElementCount')
  @DomName('DocumentFragment.childElementCount')
  @DocsEditable()
  final int _childElementCount;

  @JSName('firstElementChild')
  @DomName('DocumentFragment.firstElementChild')
  @DocsEditable()
  final Element _firstElementChild;

  @JSName('lastElementChild')
  @DomName('DocumentFragment.lastElementChild')
  @DocsEditable()
  final Element _lastElementChild;

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


@DocsEditable()
@DomName('DOMError')
class DomError extends Interceptor native "DOMError" {
  // To suppress missing implicit constructor warnings.
  factory DomError._() { throw new UnsupportedError("Not supported"); }

  @DomName('DOMError.message')
  @DocsEditable()
  @Experimental() // untriaged
  final String message;

  @DomName('DOMError.name')
  @DocsEditable()
  final String name;
}
// 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.


@DomName('DOMException')
@Unstable()
class DomException extends Interceptor native "DOMException" {

  static const String INDEX_SIZE = 'IndexSizeError';
  static const String HIERARCHY_REQUEST = 'HierarchyRequestError';
  static const String WRONG_DOCUMENT = 'WrongDocumentError';
  static const String INVALID_CHARACTER = 'InvalidCharacterError';
  static const String NO_MODIFICATION_ALLOWED = 'NoModificationAllowedError';
  static const String NOT_FOUND = 'NotFoundError';
  static const String NOT_SUPPORTED = 'NotSupportedError';
  static const String INVALID_STATE = 'InvalidStateError';
  static const String SYNTAX = 'SyntaxError';
  static const String INVALID_MODIFICATION = 'InvalidModificationError';
  static const String NAMESPACE = 'NamespaceError';
  static const String INVALID_ACCESS = 'InvalidAccessError';
  static const String TYPE_MISMATCH = 'TypeMismatchError';
  static const String SECURITY = 'SecurityError';
  static const String NETWORK = 'NetworkError';
  static const String ABORT = 'AbortError';
  static const String URL_MISMATCH = 'URLMismatchError';
  static const String QUOTA_EXCEEDED = 'QuotaExceededError';
  static const String TIMEOUT = 'TimeoutError';
  static const String INVALID_NODE_TYPE = 'InvalidNodeTypeError';
  static const String DATA_CLONE = 'DataCloneError';

  String get name {
    var errorName = JS('String', '#.name', this);
    // Although Safari nightly has updated the name to SecurityError, Safari 5
    // and 6 still return SECURITY_ERR.
    if (Device.isWebKit && errorName == 'SECURITY_ERR') return 'SecurityError';
    // Chrome release still uses old string, remove this line when Chrome stable
    // also prints out SyntaxError.
    if (Device.isWebKit && errorName == 'SYNTAX_ERR') return 'SyntaxError';
    return errorName;
  }
  // To suppress missing implicit constructor warnings.
  factory DomException._() { throw new UnsupportedError("Not supported"); }

  @DomName('DOMException.message')
  @DocsEditable()
  final String message;

  @DomName('DOMException.toString')
  @DocsEditable()
  String toString() native;

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


@DocsEditable()
@DomName('DOMImplementation')
class DomImplementation extends Interceptor native "DOMImplementation" {
  // To suppress missing implicit constructor warnings.
  factory DomImplementation._() { throw new UnsupportedError("Not supported"); }

  @JSName('createCSSStyleSheet')
  @DomName('DOMImplementation.createCSSStyleSheet')
  @DocsEditable()
  @Experimental() // non-standard
  CssStyleSheet createCssStyleSheet(String title, String media) native;

  @DomName('DOMImplementation.createDocument')
  @DocsEditable()
  XmlDocument createDocument(String namespaceURI, String qualifiedName, _DocumentType doctype) native;

  @DomName('DOMImplementation.createDocumentType')
  @DocsEditable()
  _DocumentType createDocumentType(String qualifiedName, String publicId, String systemId) native;

  @JSName('createHTMLDocument')
  @DomName('DOMImplementation.createHTMLDocument')
  @DocsEditable()
  HtmlDocument createHtmlDocument(String title) native;

  @DomName('DOMImplementation.hasFeature')
  @DocsEditable()
  bool hasFeature(String feature, String version) native;
}
// 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.


@DocsEditable()
@DomName('DOMParser')
class DomParser extends Interceptor native "DOMParser" {
  // To suppress missing implicit constructor warnings.
  factory DomParser._() { throw new UnsupportedError("Not supported"); }

  @DomName('DOMParser.DOMParser')
  @DocsEditable()
  factory DomParser() {
    return DomParser._create_1();
  }
  static DomParser _create_1() => JS('DomParser', 'new DOMParser()');

  @DomName('DOMParser.parseFromString')
  @DocsEditable()
  Document parseFromString(String str, String contentType) native;
}
// 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.


@DocsEditable()
@DomName('DOMSettableTokenList')
class DomSettableTokenList extends DomTokenList native "DOMSettableTokenList" {
  // To suppress missing implicit constructor warnings.
  factory DomSettableTokenList._() { throw new UnsupportedError("Not supported"); }

  @DomName('DOMSettableTokenList.value')
  @DocsEditable()
  String value;

  @DomName('DOMSettableTokenList.__getter__')
  @DocsEditable()
  String __getter__(int index) native;
}
// 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.


@DocsEditable()
@DomName('DOMStringList')
class DomStringList extends Interceptor with ListMixin<String>, ImmutableListMixin<String> implements JavaScriptIndexingBehavior, List<String> native "DOMStringList" {
  // To suppress missing implicit constructor warnings.
  factory DomStringList._() { throw new UnsupportedError("Not supported"); }

  @DomName('DOMStringList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  String operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("String", "#[#]", this, index);
  }
  void operator[]=(int index, String value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<String> mixins.
  // String is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  String get first {
    if (this.length > 0) {
      return JS('String', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  String get last {
    int len = this.length;
    if (len > 0) {
      return JS('String', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  String get single {
    int len = this.length;
    if (len == 1) {
      return JS('String', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  String elementAt(int index) => this[index];
  // -- end List<String> mixins.

  @DomName('DOMStringList.contains')
  @DocsEditable()
  bool contains(String string) native;

  @DomName('DOMStringList.item')
  @DocsEditable()
  String item(int index) native;
}
// 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.


@DocsEditable()
@DomName('DOMStringMap')
abstract class DomStringMap extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomStringMap._() { throw new UnsupportedError("Not supported"); }

  bool __delete__(index_OR_name);

  String __getter__(index_OR_name);

  void __setter__(index_OR_name, String value);
}
// 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.


@DocsEditable()
@DomName('DOMTokenList')
class DomTokenList extends Interceptor native "DOMTokenList" {
  // To suppress missing implicit constructor warnings.
  factory DomTokenList._() { throw new UnsupportedError("Not supported"); }

  @DomName('DOMTokenList.length')
  @DocsEditable()
  final int length;

  @DomName('DOMTokenList.contains')
  @DocsEditable()
  bool contains(String token) native;

  @DomName('DOMTokenList.item')
  @DocsEditable()
  String item(int index) native;

  @DomName('DOMTokenList.toString')
  @DocsEditable()
  String toString() native;

  @DomName('DOMTokenList.toggle')
  @DocsEditable()
  bool toggle(String token, [bool force]) native;
}
// 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.


class _ChildrenElementList extends ListBase<Element>
    implements NodeListWrapper {
  // Raw Element.
  final Element _element;
  final HtmlCollection _childElements;

  _ChildrenElementList._wrap(Element element)
    : _childElements = element._children,
      _element = element;

  bool contains(Object element) => _childElements.contains(element);


  bool get isEmpty {
    return _element._firstElementChild == null;
  }

  int get length {
    return _childElements.length;
  }

  Element operator [](int index) {
    return _childElements[index];
  }

  void operator []=(int index, Element value) {
    _element._replaceChild(value, _childElements[index]);
  }

  void set length(int newLength) {
    // TODO(jacobr): remove children when length is reduced.
    throw new UnsupportedError('Cannot resize element lists');
  }

  Element add(Element value) {
    _element.append(value);
    return value;
  }

  Iterator<Element> get iterator => toList().iterator;

  void addAll(Iterable<Element> iterable) {
    if (iterable is _ChildNodeListLazy) {
      iterable = new List.from(iterable);
    }

    for (Element element in iterable) {
      _element.append(element);
    }
  }

  void sort([int compare(Element a, Element b)]) {
    throw new UnsupportedError('Cannot sort element lists');
  }

  void shuffle([Random random]) {
    throw new UnsupportedError('Cannot shuffle element lists');
  }

  void removeWhere(bool test(Element element)) {
    _filter(test, false);
  }

  void retainWhere(bool test(Element element)) {
    _filter(test, true);
  }

  void _filter(bool test(var element), bool retainMatching) {
    var removed;
    if (retainMatching) {
      removed = _element.children.where((e) => !test(e));
    } else {
      removed = _element.children.where(test);
    }
    for (var e in removed) e.remove();
  }

  void setRange(int start, int end, Iterable<Element> iterable,
                [int skipCount = 0]) {
    throw new UnimplementedError();
  }

  void replaceRange(int start, int end, Iterable<Element> iterable) {
    throw new UnimplementedError();
  }

  void fillRange(int start, int end, [Element fillValue]) {
    throw new UnimplementedError();
  }

  bool remove(Object object) {
    if (object is Element) {
      Element element = object;
      if (identical(element.parentNode, _element)) {
        _element._removeChild(element);
        return true;
      }
    }
    return false;
  }

  void insert(int index, Element element) {
    if (index < 0 || index > length) {
      throw new RangeError.range(index, 0, length);
    }
    if (index == length) {
      _element.append(element);
    } else {
      _element.insertBefore(element, this[index]);
    }
  }

  void setAll(int index, Iterable<Element> iterable) {
    throw new UnimplementedError();
  }

  void clear() {
    _element._clearChildren();
  }

  Element removeAt(int index) {
    final result = this[index];
    if (result != null) {
      _element._removeChild(result);
    }
    return result;
  }

  Element removeLast() {
    final result = this.last;
    if (result != null) {
      _element._removeChild(result);
    }
    return result;
  }

  Element get first {
    Element result = _element._firstElementChild;
    if (result == null) throw new StateError("No elements");
    return result;
  }


  Element get last {
    Element result = _element._lastElementChild;
    if (result == null) throw new StateError("No elements");
    return result;
  }

  Element get single {
    if (length > 1) throw new StateError("More than one element");
    return first;
  }

  List<Node> get rawList => _childElements;
}

/**
 * An immutable list containing HTML elements. This list contains some
 * additional methods when compared to regular lists for ease of CSS
 * manipulation on a group of elements.
 */
abstract class ElementList<T extends Element> extends ListBase<T> {
  /**
   * The union of all CSS classes applied to the elements in this list.
   *
   * This set makes it easy to add, remove or toggle (add if not present, remove
   * if present) the classes applied to a collection of elements.
   *
   *     htmlList.classes.add('selected');
   *     htmlList.classes.toggle('isOnline');
   *     htmlList.classes.remove('selected');
   */
  CssClassSet get classes;

  /** Replace the classes with `value` for every element in this list. */
  set classes(Iterable<String> value);

  /**
   * Access the union of all [CssStyleDeclaration]s that are associated with an
   * [ElementList].
   *
   * Grouping the style objects all together provides easy editing of specific
   * properties of a collection of elements. Setting a specific property value
   * will set that property in all [Element]s in the [ElementList]. Getting a
   * specific property value will return the value of the property of the first
   * element in the [ElementList].
   */
  CssStyleDeclarationBase get style;

  /**
   * Access dimensions and position of the Elements in this list.
   *
   * Setting the height or width properties will set the height or width
   * property for all elements in the list. This returns a rectangle with the
   * dimenions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Getting the height or width returns the height or width of the
   * first Element in this list.
   *
   * Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not.
   */
  @Experimental()
  CssRect get contentEdge;

  /**
   * Access dimensions and position of the first Element's content + padding box
   * in this list.
   *
   * This returns a rectangle with the dimenions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's `innerHeight` value for an element. This
   * is also a rectangle equalling the dimensions of clientHeight and
   * clientWidth.
   */
  @Experimental()
  CssRect get paddingEdge;

  /**
   * Access dimensions and position of the first Element's content + padding +
   * border box in this list.
   *
   * This returns a rectangle with the dimenions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's `outerHeight` value for an element.
   */
  @Experimental()
  CssRect get borderEdge;

  /**
   * Access dimensions and position of the first Element's content + padding +
   * border + margin box in this list.
   *
   * This returns a rectangle with the dimenions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's `outerHeight` value for an element.
   */
  @Experimental()
  CssRect get marginEdge;

  /// Stream of `abort` events handled by this [Element].
  @DomName('Element.onabort')
  @DocsEditable()
  ElementStream<Event> get onAbort;

  /// Stream of `beforecopy` events handled by this [Element].
  @DomName('Element.onbeforecopy')
  @DocsEditable()
  ElementStream<Event> get onBeforeCopy;

  /// Stream of `beforecut` events handled by this [Element].
  @DomName('Element.onbeforecut')
  @DocsEditable()
  ElementStream<Event> get onBeforeCut;

  /// Stream of `beforepaste` events handled by this [Element].
  @DomName('Element.onbeforepaste')
  @DocsEditable()
  ElementStream<Event> get onBeforePaste;

  /// Stream of `blur` events handled by this [Element].
  @DomName('Element.onblur')
  @DocsEditable()
  ElementStream<Event> get onBlur;

  /// Stream of `change` events handled by this [Element].
  @DomName('Element.onchange')
  @DocsEditable()
  ElementStream<Event> get onChange;

  /// Stream of `click` events handled by this [Element].
  @DomName('Element.onclick')
  @DocsEditable()
  ElementStream<MouseEvent> get onClick;

  /// Stream of `contextmenu` events handled by this [Element].
  @DomName('Element.oncontextmenu')
  @DocsEditable()
  ElementStream<MouseEvent> get onContextMenu;

  /// Stream of `copy` events handled by this [Element].
  @DomName('Element.oncopy')
  @DocsEditable()
  ElementStream<Event> get onCopy;

  /// Stream of `cut` events handled by this [Element].
  @DomName('Element.oncut')
  @DocsEditable()
  ElementStream<Event> get onCut;

  /// Stream of `doubleclick` events handled by this [Element].
  @DomName('Element.ondblclick')
  @DocsEditable()
  ElementStream<Event> get onDoubleClick;

  /**
   * A stream of `drag` events fired when this element currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondrag')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrag;

  /**
   * A stream of `dragend` events fired when this element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragend')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnd;

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragenter')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnter;

  /**
   * A stream of `dragleave` events fired when an object being dragged over this
   * element leaves this element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragleave')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragLeave;

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragover')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragOver;

  /**
   * A stream of `dragstart` events fired when this element starts being
   * dragged.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragstart')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragStart;

  /**
   * A stream of `drop` events fired when a dragged object is dropped on this
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondrop')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrop;

  /// Stream of `error` events handled by this [Element].
  @DomName('Element.onerror')
  @DocsEditable()
  ElementStream<Event> get onError;

  /// Stream of `focus` events handled by this [Element].
  @DomName('Element.onfocus')
  @DocsEditable()
  ElementStream<Event> get onFocus;

  /// Stream of `input` events handled by this [Element].
  @DomName('Element.oninput')
  @DocsEditable()
  ElementStream<Event> get onInput;

  /// Stream of `invalid` events handled by this [Element].
  @DomName('Element.oninvalid')
  @DocsEditable()
  ElementStream<Event> get onInvalid;

  /// Stream of `keydown` events handled by this [Element].
  @DomName('Element.onkeydown')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyDown;

  /// Stream of `keypress` events handled by this [Element].
  @DomName('Element.onkeypress')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyPress;

  /// Stream of `keyup` events handled by this [Element].
  @DomName('Element.onkeyup')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyUp;

  /// Stream of `load` events handled by this [Element].
  @DomName('Element.onload')
  @DocsEditable()
  ElementStream<Event> get onLoad;

  /// Stream of `mousedown` events handled by this [Element].
  @DomName('Element.onmousedown')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseDown;

  /// Stream of `mouseenter` events handled by this [Element].
  @DomName('Element.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseEnter;

  /// Stream of `mouseleave` events handled by this [Element].
  @DomName('Element.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseLeave;

  /// Stream of `mousemove` events handled by this [Element].
  @DomName('Element.onmousemove')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseMove;

  /// Stream of `mouseout` events handled by this [Element].
  @DomName('Element.onmouseout')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOut;

  /// Stream of `mouseover` events handled by this [Element].
  @DomName('Element.onmouseover')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOver;

  /// Stream of `mouseup` events handled by this [Element].
  @DomName('Element.onmouseup')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseUp;

  /// Stream of `mousewheel` events handled by this [Element].
  @DomName('Element.onmousewheel')
  @DocsEditable()
  // http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents
  @Experimental() // non-standard
  ElementStream<WheelEvent> get onMouseWheel;

  /// Stream of `paste` events handled by this [Element].
  @DomName('Element.onpaste')
  @DocsEditable()
  ElementStream<Event> get onPaste;

  /// Stream of `reset` events handled by this [Element].
  @DomName('Element.onreset')
  @DocsEditable()
  ElementStream<Event> get onReset;

  @DomName('Element.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onResize;

  /// Stream of `scroll` events handled by this [Element].
  @DomName('Element.onscroll')
  @DocsEditable()
  ElementStream<Event> get onScroll;

  /// Stream of `search` events handled by this [Element].
  @DomName('Element.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  ElementStream<Event> get onSearch;

  /// Stream of `select` events handled by this [Element].
  @DomName('Element.onselect')
  @DocsEditable()
  ElementStream<Event> get onSelect;

  /// Stream of `selectstart` events handled by this [Element].
  @DomName('Element.onselectstart')
  @DocsEditable()
  @Experimental() // nonstandard
  ElementStream<Event> get onSelectStart;

  /// Stream of `submit` events handled by this [Element].
  @DomName('Element.onsubmit')
  @DocsEditable()
  ElementStream<Event> get onSubmit;

  /// Stream of `touchcancel` events handled by this [Element].
  @DomName('Element.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchCancel;

  /// Stream of `touchend` events handled by this [Element].
  @DomName('Element.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnd;

  /// Stream of `touchenter` events handled by this [Element].
  @DomName('Element.ontouchenter')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnter;

  /// Stream of `touchleave` events handled by this [Element].
  @DomName('Element.ontouchleave')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchLeave;

  /// Stream of `touchmove` events handled by this [Element].
  @DomName('Element.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchMove;

  /// Stream of `touchstart` events handled by this [Element].
  @DomName('Element.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchStart;

  /// Stream of `transitionend` events handled by this [Element].
  @DomName('Element.ontransitionend')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  ElementStream<TransitionEvent> get onTransitionEnd;

  /// Stream of `fullscreenchange` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenchange')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenChange;

  /// Stream of `fullscreenerror` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenError;

}

// TODO(jacobr): this is an inefficient implementation but it is hard to see
// a better option given that we cannot quite force NodeList to be an
// ElementList as there are valid cases where a NodeList JavaScript object
// contains Node objects that are not Elements.
class _FrozenElementList<T extends Element> extends ListBase<T>
    implements ElementList<T>, NodeListWrapper {
  final List<Node> _nodeList;
  // The subset of _nodeList that are Elements.
  List<Element> _elementList;

  _FrozenElementList._wrap(this._nodeList) {
    _elementList = _nodeList.where((e) => e is Element).toList();
  }

  int get length => _nodeList.length;

  Element operator [](int index) => _nodeList[index];

  void operator []=(int index, Element value) {
    throw new UnsupportedError('Cannot modify list');
  }

  void set length(int newLength) {
    throw new UnsupportedError('Cannot modify list');
  }

  void sort([Comparator<Element> compare]) {
    throw new UnsupportedError('Cannot sort list');
  }

  void shuffle([Random random]) {
    throw new UnsupportedError('Cannot shuffle list');
  }

  Element get first => _nodeList.first;

  Element get last => _nodeList.last;

  Element get single => _nodeList.single;

  CssClassSet get classes => new _MultiElementCssClassSet(_elementList);

  CssStyleDeclarationBase get style =>
      new _CssStyleDeclarationSet(_elementList);

  void set classes(Iterable<String> value) {
    _elementList.forEach((e) => e.classes = value);
  }

  CssRect get contentEdge => new _ContentCssListRect(_elementList);

  CssRect get paddingEdge => _elementList.first.paddingEdge;

  CssRect get borderEdge => _elementList.first.borderEdge;

  CssRect get marginEdge => _elementList.first.marginEdge;

  List<Node> get rawList => _nodeList;


  /// Stream of `abort` events handled by this [Element].
  @DomName('Element.onabort')
  @DocsEditable()
  ElementStream<Event> get onAbort => Element.abortEvent._forElementList(this);

  /// Stream of `beforecopy` events handled by this [Element].
  @DomName('Element.onbeforecopy')
  @DocsEditable()
  ElementStream<Event> get onBeforeCopy => Element.beforeCopyEvent._forElementList(this);

  /// Stream of `beforecut` events handled by this [Element].
  @DomName('Element.onbeforecut')
  @DocsEditable()
  ElementStream<Event> get onBeforeCut => Element.beforeCutEvent._forElementList(this);

  /// Stream of `beforepaste` events handled by this [Element].
  @DomName('Element.onbeforepaste')
  @DocsEditable()
  ElementStream<Event> get onBeforePaste => Element.beforePasteEvent._forElementList(this);

  /// Stream of `blur` events handled by this [Element].
  @DomName('Element.onblur')
  @DocsEditable()
  ElementStream<Event> get onBlur => Element.blurEvent._forElementList(this);

  /// Stream of `change` events handled by this [Element].
  @DomName('Element.onchange')
  @DocsEditable()
  ElementStream<Event> get onChange => Element.changeEvent._forElementList(this);

  /// Stream of `click` events handled by this [Element].
  @DomName('Element.onclick')
  @DocsEditable()
  ElementStream<MouseEvent> get onClick => Element.clickEvent._forElementList(this);

  /// Stream of `contextmenu` events handled by this [Element].
  @DomName('Element.oncontextmenu')
  @DocsEditable()
  ElementStream<MouseEvent> get onContextMenu => Element.contextMenuEvent._forElementList(this);

  /// Stream of `copy` events handled by this [Element].
  @DomName('Element.oncopy')
  @DocsEditable()
  ElementStream<Event> get onCopy => Element.copyEvent._forElementList(this);

  /// Stream of `cut` events handled by this [Element].
  @DomName('Element.oncut')
  @DocsEditable()
  ElementStream<Event> get onCut => Element.cutEvent._forElementList(this);

  /// Stream of `doubleclick` events handled by this [Element].
  @DomName('Element.ondblclick')
  @DocsEditable()
  ElementStream<Event> get onDoubleClick => Element.doubleClickEvent._forElementList(this);

  /**
   * A stream of `drag` events fired when this element currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondrag')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrag => Element.dragEvent._forElementList(this);

  /**
   * A stream of `dragend` events fired when this element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragend')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnd => Element.dragEndEvent._forElementList(this);

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragenter')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnter => Element.dragEnterEvent._forElementList(this);

  /**
   * A stream of `dragleave` events fired when an object being dragged over this
   * element leaves this element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragleave')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragLeave => Element.dragLeaveEvent._forElementList(this);

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragover')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragOver => Element.dragOverEvent._forElementList(this);

  /**
   * A stream of `dragstart` events fired when this element starts being
   * dragged.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragstart')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragStart => Element.dragStartEvent._forElementList(this);

  /**
   * A stream of `drop` events fired when a dragged object is dropped on this
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondrop')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrop => Element.dropEvent._forElementList(this);

  /// Stream of `error` events handled by this [Element].
  @DomName('Element.onerror')
  @DocsEditable()
  ElementStream<Event> get onError => Element.errorEvent._forElementList(this);

  /// Stream of `focus` events handled by this [Element].
  @DomName('Element.onfocus')
  @DocsEditable()
  ElementStream<Event> get onFocus => Element.focusEvent._forElementList(this);

  /// Stream of `input` events handled by this [Element].
  @DomName('Element.oninput')
  @DocsEditable()
  ElementStream<Event> get onInput => Element.inputEvent._forElementList(this);

  /// Stream of `invalid` events handled by this [Element].
  @DomName('Element.oninvalid')
  @DocsEditable()
  ElementStream<Event> get onInvalid => Element.invalidEvent._forElementList(this);

  /// Stream of `keydown` events handled by this [Element].
  @DomName('Element.onkeydown')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyDown => Element.keyDownEvent._forElementList(this);

  /// Stream of `keypress` events handled by this [Element].
  @DomName('Element.onkeypress')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyPress => Element.keyPressEvent._forElementList(this);

  /// Stream of `keyup` events handled by this [Element].
  @DomName('Element.onkeyup')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyUp => Element.keyUpEvent._forElementList(this);

  /// Stream of `load` events handled by this [Element].
  @DomName('Element.onload')
  @DocsEditable()
  ElementStream<Event> get onLoad => Element.loadEvent._forElementList(this);

  /// Stream of `mousedown` events handled by this [Element].
  @DomName('Element.onmousedown')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseDown => Element.mouseDownEvent._forElementList(this);

  /// Stream of `mouseenter` events handled by this [Element].
  @DomName('Element.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseEnter => Element.mouseEnterEvent._forElementList(this);

  /// Stream of `mouseleave` events handled by this [Element].
  @DomName('Element.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseLeave => Element.mouseLeaveEvent._forElementList(this);

  /// Stream of `mousemove` events handled by this [Element].
  @DomName('Element.onmousemove')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseMove => Element.mouseMoveEvent._forElementList(this);

  /// Stream of `mouseout` events handled by this [Element].
  @DomName('Element.onmouseout')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOut => Element.mouseOutEvent._forElementList(this);

  /// Stream of `mouseover` events handled by this [Element].
  @DomName('Element.onmouseover')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOver => Element.mouseOverEvent._forElementList(this);

  /// Stream of `mouseup` events handled by this [Element].
  @DomName('Element.onmouseup')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseUp => Element.mouseUpEvent._forElementList(this);

  /// Stream of `mousewheel` events handled by this [Element].
  @DomName('Element.onmousewheel')
  @DocsEditable()
  // http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents
  @Experimental() // non-standard
  ElementStream<WheelEvent> get onMouseWheel => Element.mouseWheelEvent._forElementList(this);

  /// Stream of `paste` events handled by this [Element].
  @DomName('Element.onpaste')
  @DocsEditable()
  ElementStream<Event> get onPaste => Element.pasteEvent._forElementList(this);

  /// Stream of `reset` events handled by this [Element].
  @DomName('Element.onreset')
  @DocsEditable()
  ElementStream<Event> get onReset => Element.resetEvent._forElementList(this);

  @DomName('Element.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onResize => Element.resizeEvent._forElementList(this);

  /// Stream of `scroll` events handled by this [Element].
  @DomName('Element.onscroll')
  @DocsEditable()
  ElementStream<Event> get onScroll => Element.scrollEvent._forElementList(this);

  /// Stream of `search` events handled by this [Element].
  @DomName('Element.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  ElementStream<Event> get onSearch => Element.searchEvent._forElementList(this);

  /// Stream of `select` events handled by this [Element].
  @DomName('Element.onselect')
  @DocsEditable()
  ElementStream<Event> get onSelect => Element.selectEvent._forElementList(this);

  /// Stream of `selectstart` events handled by this [Element].
  @DomName('Element.onselectstart')
  @DocsEditable()
  @Experimental() // nonstandard
  ElementStream<Event> get onSelectStart => Element.selectStartEvent._forElementList(this);

  /// Stream of `submit` events handled by this [Element].
  @DomName('Element.onsubmit')
  @DocsEditable()
  ElementStream<Event> get onSubmit => Element.submitEvent._forElementList(this);

  /// Stream of `touchcancel` events handled by this [Element].
  @DomName('Element.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchCancel => Element.touchCancelEvent._forElementList(this);

  /// Stream of `touchend` events handled by this [Element].
  @DomName('Element.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnd => Element.touchEndEvent._forElementList(this);

  /// Stream of `touchenter` events handled by this [Element].
  @DomName('Element.ontouchenter')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnter => Element.touchEnterEvent._forElementList(this);

  /// Stream of `touchleave` events handled by this [Element].
  @DomName('Element.ontouchleave')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchLeave => Element.touchLeaveEvent._forElementList(this);

  /// Stream of `touchmove` events handled by this [Element].
  @DomName('Element.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchMove => Element.touchMoveEvent._forElementList(this);

  /// Stream of `touchstart` events handled by this [Element].
  @DomName('Element.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchStart => Element.touchStartEvent._forElementList(this);

  /// Stream of `transitionend` events handled by this [Element].
  @DomName('Element.ontransitionend')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  ElementStream<TransitionEvent> get onTransitionEnd => Element.transitionEndEvent._forElementList(this);

  /// Stream of `fullscreenchange` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenchange')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenChange => Element.fullscreenChangeEvent._forElementList(this);

  /// Stream of `fullscreenerror` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenError => Element.fullscreenErrorEvent._forElementList(this);

}

@DocsEditable()
/**
 * An abstract class, which all HTML elements extend.
 */
@DomName('Element')
abstract class Element extends Node implements GlobalEventHandlers, ParentNode, ChildNode native "Element" {

  /**
   * Creates an HTML element from a valid fragment of HTML.
   *
   *     var element = new Element.html('<div class="foo">content</div>');
   *
   * The HTML fragment should contain only one single root element, any
   * leading or trailing text nodes will be removed.
   *
   * The HTML fragment is parsed as if it occurred within the context of a
   * `<body>` tag, this means that special elements such as `<caption>` which
   * must be parsed within the scope of a `<table>` element will be dropped. Use
   * [createFragment] to parse contextual HTML fragments.
   *
   * Unless a validator is provided this will perform the default validation
   * and remove all scriptable elements and attributes.
   *
   * See also:
   *
   * * [NodeValidator]
   *
   */
  factory Element.html(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    var fragment = document.body.createFragment(html, validator: validator,
        treeSanitizer: treeSanitizer);

    return fragment.nodes.where((e) => e is Element).single;
  }

  /**
   * Custom element creation constructor.
   *
   * This constructor is used by the DOM when a custom element has been
   * created. It can only be invoked by subclasses of Element from
   * that classes created constructor.
   *
   *     class CustomElement extends Element {
   *       factory CustomElement() => new Element.tag('x-custom');
   *
   *       CustomElement.created() : super.created() {
   *          // Perform any element initialization.
   *       }
   *     }
   *     document.registerElement('x-custom', CustomElement);
   */
  Element.created() : super._created() {
    // Validate that this is a custom element & perform any additional
    // initialization.
    _initializeCustomElement(this);
  }

  /**
   * Creates the HTML element specified by the tag name.
   *
   * This is similar to [Document.createElement].
   * [tag] should be a valid HTML tag name. If [tag] is an unknown tag then
   * this will create an [UnknownElement].
   *
   *     var divElement = new Element.tag('div');
   *     print(divElement is DivElement); // 'true'
   *     var myElement = new Element.tag('unknownTag');
   *     print(myElement is UnknownElement); // 'true'
   *
   * For standard elements it is more preferable to use the type constructors:
   *     var element = new DivElement();
   *
   * See also:
   *
   * * [isTagSupported]
   */
  factory Element.tag(String tag, [String typeExtention]) =>
      _ElementFactoryProvider.createElement_tag(tag, typeExtention);

  /// Creates a new `<a>` element.
  ///
  /// This is identical to calling `new Element.tag('a')`.
  factory Element.a() => new Element.tag('a');

  /// Creates a new `<article>` element.
  ///
  /// This is identical to calling `new Element.tag('article')`.
  factory Element.article() => new Element.tag('article');

  /// Creates a new `<aside>` element.
  ///
  /// This is identical to calling `new Element.tag('aside')`.
  factory Element.aside() => new Element.tag('aside');

  /// Creates a new `<audio>` element.
  ///
  /// This is identical to calling `new Element.tag('audio')`.
  factory Element.audio() => new Element.tag('audio');

  /// Creates a new `<br>` element.
  ///
  /// This is identical to calling `new Element.tag('br')`.
  factory Element.br() => new Element.tag('br');

  /// Creates a new `<canvas>` element.
  ///
  /// This is identical to calling `new Element.tag('canvas')`.
  factory Element.canvas() => new Element.tag('canvas');

  /// Creates a new `<div>` element.
  ///
  /// This is identical to calling `new Element.tag('div')`.
  factory Element.div() => new Element.tag('div');

  /// Creates a new `<footer>` element.
  ///
  /// This is identical to calling `new Element.tag('footer')`.
  factory Element.footer() => new Element.tag('footer');

  /// Creates a new `<header>` element.
  ///
  /// This is identical to calling `new Element.tag('header')`.
  factory Element.header() => new Element.tag('header');

  /// Creates a new `<hr>` element.
  ///
  /// This is identical to calling `new Element.tag('hr')`.
  factory Element.hr() => new Element.tag('hr');

  /// Creates a new `<iframe>` element.
  ///
  /// This is identical to calling `new Element.tag('iframe')`.
  factory Element.iframe() => new Element.tag('iframe');

  /// Creates a new `<img>` element.
  ///
  /// This is identical to calling `new Element.tag('img')`.
  factory Element.img() => new Element.tag('img');

  /// Creates a new `<li>` element.
  ///
  /// This is identical to calling `new Element.tag('li')`.
  factory Element.li() => new Element.tag('li');

  /// Creates a new `<nav>` element.
  ///
  /// This is identical to calling `new Element.tag('nav')`.
  factory Element.nav() => new Element.tag('nav');

  /// Creates a new `<ol>` element.
  ///
  /// This is identical to calling `new Element.tag('ol')`.
  factory Element.ol() => new Element.tag('ol');

  /// Creates a new `<option>` element.
  ///
  /// This is identical to calling `new Element.tag('option')`.
  factory Element.option() => new Element.tag('option');

  /// Creates a new `<p>` element.
  ///
  /// This is identical to calling `new Element.tag('p')`.
  factory Element.p() => new Element.tag('p');

  /// Creates a new `<pre>` element.
  ///
  /// This is identical to calling `new Element.tag('pre')`.
  factory Element.pre() => new Element.tag('pre');

  /// Creates a new `<section>` element.
  ///
  /// This is identical to calling `new Element.tag('section')`.
  factory Element.section() => new Element.tag('section');

  /// Creates a new `<select>` element.
  ///
  /// This is identical to calling `new Element.tag('select')`.
  factory Element.select() => new Element.tag('select');

  /// Creates a new `<span>` element.
  ///
  /// This is identical to calling `new Element.tag('span')`.
  factory Element.span() => new Element.tag('span');

  /// Creates a new `<svg>` element.
  ///
  /// This is identical to calling `new Element.tag('svg')`.
  factory Element.svg() => new Element.tag('svg');

  /// Creates a new `<table>` element.
  ///
  /// This is identical to calling `new Element.tag('table')`.
  factory Element.table() => new Element.tag('table');

  /// Creates a new `<td>` element.
  ///
  /// This is identical to calling `new Element.tag('td')`.
  factory Element.td() => new Element.tag('td');

  /// Creates a new `<textarea>` element.
  ///
  /// This is identical to calling `new Element.tag('textarea')`.
  factory Element.textarea() => new Element.tag('textarea');

  /// Creates a new `<th>` element.
  ///
  /// This is identical to calling `new Element.tag('th')`.
  factory Element.th() => new Element.tag('th');

  /// Creates a new `<tr>` element.
  ///
  /// This is identical to calling `new Element.tag('tr')`.
  factory Element.tr() => new Element.tag('tr');

  /// Creates a new `<ul>` element.
  ///
  /// This is identical to calling `new Element.tag('ul')`.
  factory Element.ul() => new Element.tag('ul');

  /// Creates a new `<video>` element.
  ///
  /// This is identical to calling `new Element.tag('video')`.
  factory Element.video() => new Element.tag('video');

  /**
   * All attributes on this element.
   *
   * Any modifications to the attribute map will automatically be applied to
   * this element.
   *
   * This only includes attributes which are not in a namespace
   * (such as 'xlink:href'), additional attributes can be accessed via
   * [getNamespacedAttributes].
   */
  Map<String, String> get attributes => new _ElementAttributeMap(this);

  void set attributes(Map<String, String> value) {
    Map<String, String> attributes = this.attributes;
    attributes.clear();
    for (String key in value.keys) {
      attributes[key] = value[key];
    }
  }

  /**
   * List of the direct children of this element.
   *
   * This collection can be used to add and remove elements from the document.
   *
   *     var item = new DivElement();
   *     item.text = 'Something';
   *     document.body.children.add(item) // Item is now displayed on the page.
   *     for (var element in document.body.children) {
   *       element.style.background = 'red'; // Turns every child of body red.
   *     }
   */
  List<Element> get children => new _ChildrenElementList._wrap(this);

  void set children(List<Element> value) {
    // Copy list first since we don't want liveness during iteration.
    List copy = new List.from(value);
    var children = this.children;
    children.clear();
    children.addAll(copy);
  }

  /**
   * Finds all descendent elements of this element that match the specified
   * group of selectors.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var items = element.querySelectorAll('.itemClassName');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  @DomName('Element.querySelectorAll')
  ElementList querySelectorAll(String selectors) =>
    new _FrozenElementList._wrap(_querySelectorAll(selectors));

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

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

  /**
   * The set of CSS classes applied to this element.
   *
   * This set makes it easy to add, remove or toggle the classes applied to
   * this element.
   *
   *     element.classes.add('selected');
   *     element.classes.toggle('isOnline');
   *     element.classes.remove('selected');
   */
  CssClassSet get classes => new _ElementCssClassSet(this);

  void set classes(Iterable<String> value) {
    CssClassSet classSet = classes;
    classSet.clear();
    classSet.addAll(value);
  }

  /**
   * Allows access to all custom data attributes (data-*) set on this element.
   *
   * The keys for the map must follow these rules:
   *
   * * The name must not begin with 'xml'.
   * * The name cannot contain a semi-colon (';').
   * * The name cannot contain any capital letters.
   *
   * Any keys from markup will be converted to camel-cased keys in the map.
   *
   * For example, HTML specified as:
   *
   *     <div data-my-random-value='value'></div>
   *
   * Would be accessed in Dart as:
   *
   *     var value = element.dataset['myRandomValue'];
   *
   * See also:
   *
   * * [Custom data attributes](http://www.w3.org/TR/html5/global-attributes.html#custom-data-attribute)
   */
  Map<String, String> get dataset =>
    new _DataAttributeMap(attributes);

  void set dataset(Map<String, String> value) {
    final data = this.dataset;
    data.clear();
    for (String key in value.keys) {
      data[key] = value[key];
    }
  }

  /**
   * Gets a map for manipulating the attributes of a particular namespace.
   *
   * This is primarily useful for SVG attributes such as xref:link.
   */
  Map<String, String> getNamespacedAttributes(String namespace) {
    return new _NamespacedAttributeMap(this, namespace);
  }

  /**
   * The set of all CSS values applied to this element, including inherited
   * and default values.
   *
   * The computedStyle contains values that are inherited from other
   * sources, such as parent elements or stylesheets. This differs from the
   * [style] property, which contains only the values specified directly on this
   * element.
   *
   * PseudoElement can be values such as `::after`, `::before`, `::marker`,
   * `::line-marker`.
   *
   * See also:
   *
   * * [CSS Inheritance and Cascade](http://docs.webplatform.org/wiki/tutorials/inheritance_and_cascade)
   * * [Pseudo-elements](http://docs.webplatform.org/wiki/css/selectors/pseudo-elements)
   */
  CssStyleDeclaration getComputedStyle([String pseudoElement]) {
    if (pseudoElement == null) {
      pseudoElement = '';
    }
    // TODO(jacobr): last param should be null, see b/5045788
    return window._getComputedStyle(this, pseudoElement);
  }

  /**
   * Gets the position of this element relative to the client area of the page.
   */
  Rectangle get client => new Rectangle(clientLeft, clientTop, clientWidth,
      clientHeight);

  /**
   * Gets the offset of this element relative to its offsetParent.
   */
  Rectangle get offset => new Rectangle(offsetLeft, offsetTop, offsetWidth,
      offsetHeight);

  /**
   * Adds the specified text after the last child of this element.
   */
  void appendText(String text) {
    this.insertAdjacentText('beforeend', text);
  }

  /**
   * Parses the specified text as HTML and adds the resulting node after the
   * last child of this element.
   */
  void appendHtml(String text) {
    this.insertAdjacentHtml('beforeend', text);
  }

  /**
   * Checks to see if the tag name is supported by the current platform.
   *
   * The tag should be a valid HTML tag name.
   */
  static bool isTagSupported(String tag) {
    var e = _ElementFactoryProvider.createElement_tag(tag, null);
    return e is Element && !(e is UnknownElement);
  }

  /**
   * Called by the DOM when this element has been inserted into the live
   * document.
   *
   * More information can be found in the
   * [Custom Elements](http://w3c.github.io/webcomponents/spec/custom/#dfn-attached-callback)
   * draft specification.
   */
  @Experimental()
  void attached() {
    // For the deprecation period, call the old callback.
    enteredView();
  }

  /**
   * Called by the DOM when this element has been removed from the live
   * document.
   *
   * More information can be found in the
   * [Custom Elements](http://w3c.github.io/webcomponents/spec/custom/#dfn-detached-callback)
   * draft specification.
   */
  @Experimental()
  void detached() {
    // For the deprecation period, call the old callback.
    leftView();
  }

  /** *Deprecated*: override [attached] instead. */
  @Experimental()
  @deprecated
  void enteredView() {}

  /** *Deprecated*: override [detached] instead. */
  @Experimental()
  @deprecated
  void leftView() {}

  /**
   * Called by the DOM whenever an attribute on this has been changed.
   */
  void attributeChanged(String name, String oldValue, String newValue) {}

  // Hooks to support custom WebComponents.

  @Creates('Null')  // Set from Dart code; does not instantiate a native type.
  Element _xtag;

  /**
   * Experimental support for [web components][wc]. This field stores a
   * reference to the component implementation. It was inspired by Mozilla's
   * [x-tags][] project. Please note: in the future it may be possible to
   * `extend Element` from your class, in which case this field will be
   * deprecated.
   *
   * If xtag has not been set, it will simply return `this` [Element].
   *
   * [wc]: http://dvcs.w3.org/hg/webcomponents/raw-file/tip/explainer/index.html
   * [x-tags]: http://x-tags.org/
   */
  // Note: return type is `dynamic` for convenience to suppress warnings when
  // members of the component are used. The actual type is a subtype of Element.
  get xtag => _xtag != null ? _xtag : this;

  void set xtag(Element value) {
    _xtag = value;
  }

  @DomName('Element.localName')
  @DocsEditable()
  String get localName => _localName;

  /**
   * A URI that identifies the XML namespace of this element.
   *
   * `null` if no namespace URI is specified.
   *
   * ## Other resources
   *
   * * [Node.namespaceURI]
   * (http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-NodeNSname) from W3C.
   */
  @DomName('Element.namespaceUri')
  String get namespaceUri => _namespaceUri;

  /**
   * The string representation of this element.
   *
   * This is equivalent to reading the [localName] property.
   */
  String toString() => localName;

  /**
   * Scrolls this element into view.
   *
   * Only one of of the alignment options may be specified at a time.
   *
   * If no options are specified then this will attempt to scroll the minimum
   * amount needed to bring the element into view.
   *
   * Note that alignCenter is currently only supported on WebKit platforms. If
   * alignCenter is specified but not supported then this will fall back to
   * alignTop.
   *
   * See also:
   *
   * * [scrollIntoView](http://docs.webplatform.org/wiki/dom/methods/scrollIntoView)
   * * [scrollIntoViewIfNeeded](http://docs.webplatform.org/wiki/dom/methods/scrollIntoViewIfNeeded)
   */
  void scrollIntoView([ScrollAlignment alignment]) {
    var hasScrollIntoViewIfNeeded = true;
    hasScrollIntoViewIfNeeded =
        JS('bool', '!!(#.scrollIntoViewIfNeeded)', this);
    if (alignment == ScrollAlignment.TOP) {
      this._scrollIntoView(true);
    } else if (alignment == ScrollAlignment.BOTTOM) {
      this._scrollIntoView(false);
    } else if (hasScrollIntoViewIfNeeded) {
      if (alignment == ScrollAlignment.CENTER) {
        this._scrollIntoViewIfNeeded(true);
      } else {
        this._scrollIntoViewIfNeeded();
      }
    } else {
      this._scrollIntoView();
    }
  }

  /**
   * Static factory designed to expose `mousewheel` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mouseWheelEvent')
  static const EventStreamProvider<WheelEvent> mouseWheelEvent =
      const _CustomEventStreamProvider<WheelEvent>(
        Element._determineMouseWheelEventType);

  static String _determineMouseWheelEventType(EventTarget e) {
    if (JS('bool', '#.onwheel !== undefined', e)) {
      // W3C spec, and should be IE9+, but IE has a bug exposing onwheel.
      return 'wheel';
    } else if (JS('bool', '#.onmousewheel !== undefined', e)) {
      // Chrome & IE
      return 'mousewheel';
    } else {
      // Firefox
      return 'DOMMouseScroll';
    }
  }

  /**
   * Static factory designed to expose `transitionend` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.transitionEndEvent')
  static const EventStreamProvider<TransitionEvent> transitionEndEvent =
      const _CustomEventStreamProvider<TransitionEvent>(
        Element._determineTransitionEventType);

  static String _determineTransitionEventType(EventTarget e) {
    // Unfortunately the normal 'ontransitionend' style checks don't work here.
    if (Device.isWebKit) {
      return 'webkitTransitionEnd';
    } else if (Device.isOpera) {
      return 'oTransitionEnd';
    }
    return 'transitionend';
  }
  /**
   * Inserts text into the DOM at the specified location.
   *
   * To see the possible values for [where], read the doc for
   * [insertAdjacentHtml].
   *
   * See also:
   *
   * * [insertAdjacentHtml]
   */
  void insertAdjacentText(String where, String text) {
    if (JS('bool', '!!#.insertAdjacentText', this)) {
      _insertAdjacentText(where, text);
    } else {
      _insertAdjacentNode(where, new Text(text));
    }
  }

  @JSName('insertAdjacentText')
  void _insertAdjacentText(String where, String text) native;

  /**
   * Parses text as an HTML fragment and inserts it into the DOM at the
   * specified location.
   *
   * The [where] parameter indicates where to insert the HTML fragment:
   *
   * * 'beforeBegin': Immediately before this element.
   * * 'afterBegin': As the first child of this element.
   * * 'beforeEnd': As the last child of this element.
   * * 'afterEnd': Immediately after this element.
   *
   *     var html = '<div class="something">content</div>';
   *     // Inserts as the first child
   *     document.body.insertAdjacentHtml('afterBegin', html);
   *     var createdElement = document.body.children[0];
   *     print(createdElement.classes[0]); // Prints 'something'
   *
   * See also:
   *
   * * [insertAdjacentText]
   * * [insertAdjacentElement]
   */
  void insertAdjacentHtml(String where, String html) {
    if (JS('bool', '!!#.insertAdjacentHTML', this)) {
      _insertAdjacentHtml(where, html);
    } else {
      _insertAdjacentNode(where, new DocumentFragment.html(html));
    }
  }

  @JSName('insertAdjacentHTML')
  void _insertAdjacentHtml(String where, String text) native;

  /**
   * Inserts [element] into the DOM at the specified location.
   *
   * To see the possible values for [where], read the doc for
   * [insertAdjacentHtml].
   *
   * See also:
   *
   * * [insertAdjacentHtml]
   */
  Element insertAdjacentElement(String where, Element element) {
    if (JS('bool', '!!#.insertAdjacentElement', this)) {
      _insertAdjacentElement(where, element);
    } else {
      _insertAdjacentNode(where, element);
    }
    return element;
  }

  @JSName('insertAdjacentElement')
  void _insertAdjacentElement(String where, Element element) native;

  void _insertAdjacentNode(String where, Node node) {
    switch (where.toLowerCase()) {
      case 'beforebegin':
        this.parentNode.insertBefore(node, this);
        break;
      case 'afterbegin':
        var first = this.nodes.length > 0 ? this.nodes[0] : null;
        this.insertBefore(node, first);
        break;
      case 'beforeend':
        this.append(node);
        break;
      case 'afterend':
        this.parentNode.insertBefore(node, this.nextNode);
        break;
      default:
        throw new ArgumentError("Invalid position ${where}");
    }
  }

  /**
   * Checks if this element matches the CSS selectors.
   */
  @Experimental()
  bool matches(String selectors) {
    if (JS('bool', '!!#.matches', this)) {
      return JS('bool', '#.matches(#)', this, selectors);
    } else if (JS('bool', '!!#.webkitMatchesSelector', this)) {
      return JS('bool', '#.webkitMatchesSelector(#)', this, selectors);
    } else if (JS('bool', '!!#.mozMatchesSelector', this)) {
      return JS('bool', '#.mozMatchesSelector(#)', this, selectors);
    } else if (JS('bool', '!!#.msMatchesSelector', this)) {
      return JS('bool', '#.msMatchesSelector(#)', this, selectors);
    } else if (JS('bool', '!!#.oMatchesSelector', this)) {
      return JS('bool', '#.oMatchesSelector(#)', this, selectors);
    } else {
      throw new UnsupportedError("Not supported on this platform");
    }
  }

  /** Checks if this element or any of its parents match the CSS selectors. */
  @Experimental()
  bool matchesWithAncestors(String selectors) {
    var elem = this;
    do {
      if (elem.matches(selectors)) return true;
      elem = elem.parent;
    } while(elem != null);
    return false;
  }

  /**
   * Creates a new shadow root for this shadow host.
   *
   * ## Other resources
   *
   * * [Shadow DOM 101]
   * (http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
   * from HTML5Rocks.
   * * [Shadow DOM specification]
   * (http://www.w3.org/TR/shadow-dom/) from W3C.
   */
  @DomName('Element.createShadowRoot')
  @SupportedBrowser(SupportedBrowser.CHROME, '25')
  @Experimental()
  ShadowRoot createShadowRoot() {
    return JS('ShadowRoot',
      '(#.createShadowRoot || #.webkitCreateShadowRoot).call(#)',
      this, this, this);
  }

  /**
   * The shadow root of this shadow host.
   *
   * ## Other resources
   *
   * * [Shadow DOM 101]
   * (http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
   * from HTML5Rocks.
   * * [Shadow DOM specification]
   * (http://www.w3.org/TR/shadow-dom/) from W3C.
   */
  @DomName('Element.shadowRoot')
  @SupportedBrowser(SupportedBrowser.CHROME, '25')
  @Experimental()
  ShadowRoot get shadowRoot =>
      JS('ShadowRoot|Null', '#.shadowRoot || #.webkitShadowRoot', this, this);

  /**
   * Access this element's content position.
   *
   * This returns a rectangle with the dimenions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not.
   *
   * _Important_ _note_: use of this method _will_ perform CSS calculations that
   * can trigger a browser reflow. Therefore, use of this property _during_ an
   * animation frame is discouraged. See also:
   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
   */
  @Experimental()
  CssRect get contentEdge => new _ContentCssRect(this);

  /**
   * Access the dimensions and position of this element's content + padding box.
   *
   * This returns a rectangle with the dimenions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's
   * [innerHeight](http://api.jquery.com/innerHeight/) value for an element.
   * This is also a rectangle equalling the dimensions of clientHeight and
   * clientWidth.
   *
   * _Important_ _note_: use of this method _will_ perform CSS calculations that
   * can trigger a browser reflow. Therefore, use of this property _during_ an
   * animation frame is discouraged. See also:
   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
   */
  @Experimental()
  CssRect get paddingEdge => new _PaddingCssRect(this);

  /**
   * Access the dimensions and position of this element's content + padding +
   * border box.
   *
   * This returns a rectangle with the dimenions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's
   * [outerHeight](http://api.jquery.com/outerHeight/) value for an element.
   *
   * _Important_ _note_: use of this method _will_ perform CSS calculations that
   * can trigger a browser reflow. Therefore, use of this property _during_ an
   * animation frame is discouraged. See also:
   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
   */
  @Experimental()
  CssRect get borderEdge => new _BorderCssRect(this);

  /**
   * Access the dimensions and position of this element's content + padding +
   * border + margin box.
   *
   * This returns a rectangle with the dimenions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's
   * [outerHeight](http://api.jquery.com/outerHeight/) value for an element.
   *
   * _Important_ _note_: use of this method will perform CSS calculations that
   * can trigger a browser reflow. Therefore, use of this property _during_ an
   * animation frame is discouraged. See also:
   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
   */
  @Experimental()
  CssRect get marginEdge => new _MarginCssRect(this);

  /**
   * Provides the coordinates of the element relative to the top of the
   * document.
   *
   * This method is the Dart equivalent to jQuery's
   * [offset](http://api.jquery.com/offset/) method.
   */
  @Experimental()
  Point get documentOffset => offsetTo(document.documentElement);

  /**
   * Provides the offset of this element's [borderEdge] relative to the
   * specified [parent].
   *
   * This is the Dart equivalent of jQuery's
   * [position](http://api.jquery.com/position/) method. Unlike jQuery's
   * position, however, [parent] can be any parent element of `this`,
   * rather than only `this`'s immediate [offsetParent]. If the specified
   * element is _not_ an offset parent or transitive offset parent to this
   * element, an [ArgumentError] is thrown.
   */
  @Experimental()
  Point offsetTo(Element parent) {
    return Element._offsetToHelper(this, parent);
  }

  static Point _offsetToHelper(Element current, Element parent) {
    // We're hopping from _offsetParent_ to offsetParent (not just parent), so
    // offsetParent, "tops out" at BODY. But people could conceivably pass in
    // the document.documentElement and I want it to return an absolute offset,
    // so we have the special case checking for HTML.
    bool foundAsParent = identical(current, parent) || parent.tagName == 'HTML';
    if (current == null || identical(current, parent)) {
      if (foundAsParent) return new Point(0, 0);
      throw new ArgumentError("Specified element is not a transitive offset "
          "parent of this element.");
    }
    Element parentOffset = current.offsetParent;
    Point p = Element._offsetToHelper(parentOffset, parent);
    return new Point(p.x + current.offsetLeft, p.y + current.offsetTop);
  }

  static HtmlDocument _parseDocument;
  static Range _parseRange;
  static NodeValidatorBuilder _defaultValidator;
  static _ValidatingTreeSanitizer _defaultSanitizer;

  /**
   * Create a DocumentFragment from the HTML fragment and ensure that it follows
   * the sanitization rules specified by the validator or treeSanitizer.
   *
   * If the default validation behavior is too restrictive then a new
   * NodeValidator should be created, either extending or wrapping a default
   * validator and overriding the validation APIs.
   *
   * The treeSanitizer is used to walk the generated node tree and sanitize it.
   * A custom treeSanitizer can also be provided to perform special validation
   * rules but since the API is more complex to implement this is discouraged.
   *
   * The returned tree is guaranteed to only contain nodes and attributes which
   * are allowed by the provided validator.
   *
   * See also:
   *
   * * [NodeValidator]
   * * [NodeTreeSanitizer]
   */
  DocumentFragment createFragment(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    if (treeSanitizer == null) {
      if (validator == null) {
        if (_defaultValidator == null) {
          _defaultValidator = new NodeValidatorBuilder.common();
        }
        validator = _defaultValidator;
      }
      if (_defaultSanitizer == null) {
        _defaultSanitizer = new _ValidatingTreeSanitizer(validator);
      } else {
        _defaultSanitizer.validator = validator;
      }
      treeSanitizer = _defaultSanitizer;
    } else if (validator != null) {
      throw new ArgumentError(
          'validator can only be passed if treeSanitizer is null');
    }

    if (_parseDocument == null) {
      _parseDocument = document.implementation.createHtmlDocument('');
      _parseRange = _parseDocument.createRange();

      // Workaround for Chrome bug 229142- URIs are not resolved in new doc.
      var base = _parseDocument.createElement('base');
      base.href = document.baseUri;
      _parseDocument.head.append(base);
    }
    var contextElement;
    if (this is BodyElement) {
      contextElement = _parseDocument.body;
    } else {
      contextElement = _parseDocument.createElement(tagName);
      _parseDocument.body.append(contextElement);
    }
    var fragment;
    if (Range.supportsCreateContextualFragment) {
      _parseRange.selectNodeContents(contextElement);
      fragment = _parseRange.createContextualFragment(html);
    } else {
      contextElement._innerHtml = html;

      fragment = _parseDocument.createDocumentFragment();
      while (contextElement.firstChild != null) {
        fragment.append(contextElement.firstChild);
      }
    }
    if (contextElement != _parseDocument.body) {
      contextElement.remove();
    }

    treeSanitizer.sanitizeTree(fragment);
    // Copy the fragment over to the main document (fix for 14184)
    document.adoptNode(fragment);

    return fragment;
  }

  /**
   * Parses the HTML fragment and sets it as the contents of this element.
   *
   * This uses the default sanitization behavior to sanitize the HTML fragment,
   * use [setInnerHtml] to override the default behavior.
   */
  void set innerHtml(String html) {
    this.setInnerHtml(html);
  }

  /**
   * Parses the HTML fragment and sets it as the contents of this element.
   * This ensures that the generated content follows the sanitization rules
   * specified by the validator or treeSanitizer.
   *
   * If the default validation behavior is too restrictive then a new
   * NodeValidator should be created, either extending or wrapping a default
   * validator and overriding the validation APIs.
   *
   * The treeSanitizer is used to walk the generated node tree and sanitize it.
   * A custom treeSanitizer can also be provided to perform special validation
   * rules but since the API is more complex to implement this is discouraged.
   *
   * The resulting tree is guaranteed to only contain nodes and attributes which
   * are allowed by the provided validator.
   *
   * See also:
   *
   * * [NodeValidator]
   * * [NodeTreeSanitizer]
   */
  void setInnerHtml(String html,
    {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    text = null;
    append(createFragment(
        html, validator: validator, treeSanitizer: treeSanitizer));
  }
  String get innerHtml => _innerHtml;

  /**
   * This is an ease-of-use accessor for event streams which should only be
   * used when an explicit accessor is not available.
   */
  ElementEvents get on => new ElementEvents(this);

  // To suppress missing implicit constructor warnings.
  factory Element._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `abort` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.abortEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> abortEvent = const EventStreamProvider<Event>('abort');

  /**
   * Static factory designed to expose `beforecopy` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.beforecopyEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> beforeCopyEvent = const EventStreamProvider<Event>('beforecopy');

  /**
   * Static factory designed to expose `beforecut` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.beforecutEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> beforeCutEvent = const EventStreamProvider<Event>('beforecut');

  /**
   * Static factory designed to expose `beforepaste` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.beforepasteEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> beforePasteEvent = const EventStreamProvider<Event>('beforepaste');

  /**
   * Static factory designed to expose `blur` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.blurEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> blurEvent = const EventStreamProvider<Event>('blur');

  /**
   * Static factory designed to expose `change` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.changeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> changeEvent = const EventStreamProvider<Event>('change');

  /**
   * Static factory designed to expose `click` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.clickEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> clickEvent = const EventStreamProvider<MouseEvent>('click');

  /**
   * Static factory designed to expose `contextmenu` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.contextmenuEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> contextMenuEvent = const EventStreamProvider<MouseEvent>('contextmenu');

  /**
   * Static factory designed to expose `copy` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.copyEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> copyEvent = const EventStreamProvider<Event>('copy');

  /**
   * Static factory designed to expose `cut` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.cutEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> cutEvent = const EventStreamProvider<Event>('cut');

  /**
   * Static factory designed to expose `doubleclick` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.dblclickEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> doubleClickEvent = const EventStreamProvider<Event>('dblclick');

  /**
   * A stream of `drag` events fired when an element is currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dragEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragEvent = const EventStreamProvider<MouseEvent>('drag');

  /**
   * A stream of `dragend` events fired when an element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dragendEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragEndEvent = const EventStreamProvider<MouseEvent>('dragend');

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over an element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dragenterEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragEnterEvent = const EventStreamProvider<MouseEvent>('dragenter');

  /**
   * A stream of `dragleave` events fired when an object being dragged over an
   * element leaves the element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dragleaveEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragLeaveEvent = const EventStreamProvider<MouseEvent>('dragleave');

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over an element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dragoverEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragOverEvent = const EventStreamProvider<MouseEvent>('dragover');

  /**
   * A stream of `dragstart` events for a dragged element whose drag has begun.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dragstartEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragStartEvent = const EventStreamProvider<MouseEvent>('dragstart');

  /**
   * A stream of `drop` events fired when a dragged object is dropped on an
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dropEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dropEvent = const EventStreamProvider<MouseEvent>('drop');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `focus` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.focusEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> focusEvent = const EventStreamProvider<Event>('focus');

  /**
   * Static factory designed to expose `input` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.inputEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> inputEvent = const EventStreamProvider<Event>('input');

  /**
   * Static factory designed to expose `invalid` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.invalidEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> invalidEvent = const EventStreamProvider<Event>('invalid');

  /**
   * Static factory designed to expose `keydown` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.keydownEvent')
  @DocsEditable()
  static const EventStreamProvider<KeyboardEvent> keyDownEvent = const EventStreamProvider<KeyboardEvent>('keydown');

  /**
   * Static factory designed to expose `keypress` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.keypressEvent')
  @DocsEditable()
  static const EventStreamProvider<KeyboardEvent> keyPressEvent = const EventStreamProvider<KeyboardEvent>('keypress');

  /**
   * Static factory designed to expose `keyup` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.keyupEvent')
  @DocsEditable()
  static const EventStreamProvider<KeyboardEvent> keyUpEvent = const EventStreamProvider<KeyboardEvent>('keyup');

  /**
   * Static factory designed to expose `load` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.loadEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> loadEvent = const EventStreamProvider<Event>('load');

  /**
   * Static factory designed to expose `mousedown` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mousedownEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> mouseDownEvent = const EventStreamProvider<MouseEvent>('mousedown');

  /**
   * Static factory designed to expose `mouseenter` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mouseenterEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseEnterEvent = const EventStreamProvider<MouseEvent>('mouseenter');

  /**
   * Static factory designed to expose `mouseleave` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mouseleaveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseLeaveEvent = const EventStreamProvider<MouseEvent>('mouseleave');

  /**
   * Static factory designed to expose `mousemove` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mousemoveEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> mouseMoveEvent = const EventStreamProvider<MouseEvent>('mousemove');

  /**
   * Static factory designed to expose `mouseout` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mouseoutEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> mouseOutEvent = const EventStreamProvider<MouseEvent>('mouseout');

  /**
   * Static factory designed to expose `mouseover` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mouseoverEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> mouseOverEvent = const EventStreamProvider<MouseEvent>('mouseover');

  /**
   * Static factory designed to expose `mouseup` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mouseupEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> mouseUpEvent = const EventStreamProvider<MouseEvent>('mouseup');

  /**
   * Static factory designed to expose `paste` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.pasteEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> pasteEvent = const EventStreamProvider<Event>('paste');

  /**
   * Static factory designed to expose `reset` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.resetEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> resetEvent = const EventStreamProvider<Event>('reset');

  @DomName('Element.resizeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> resizeEvent = const EventStreamProvider<Event>('resize');

  /**
   * Static factory designed to expose `scroll` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.scrollEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> scrollEvent = const EventStreamProvider<Event>('scroll');

  /**
   * Static factory designed to expose `search` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.searchEvent')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  static const EventStreamProvider<Event> searchEvent = const EventStreamProvider<Event>('search');

  /**
   * Static factory designed to expose `select` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.selectEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> selectEvent = const EventStreamProvider<Event>('select');

  /**
   * Static factory designed to expose `selectstart` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.selectstartEvent')
  @DocsEditable()
  @Experimental() // nonstandard
  static const EventStreamProvider<Event> selectStartEvent = const EventStreamProvider<Event>('selectstart');

  /**
   * Static factory designed to expose `submit` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.submitEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> submitEvent = const EventStreamProvider<Event>('submit');

  /**
   * Static factory designed to expose `touchcancel` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchcancelEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchCancelEvent = const EventStreamProvider<TouchEvent>('touchcancel');

  /**
   * Static factory designed to expose `touchend` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchendEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchEndEvent = const EventStreamProvider<TouchEvent>('touchend');

  /**
   * Static factory designed to expose `touchenter` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchenterEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchEnterEvent = const EventStreamProvider<TouchEvent>('touchenter');

  /**
   * Static factory designed to expose `touchleave` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchleaveEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchLeaveEvent = const EventStreamProvider<TouchEvent>('touchleave');

  /**
   * Static factory designed to expose `touchmove` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchmoveEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchMoveEvent = const EventStreamProvider<TouchEvent>('touchmove');

  /**
   * Static factory designed to expose `touchstart` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchstartEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchStartEvent = const EventStreamProvider<TouchEvent>('touchstart');

  /**
   * Static factory designed to expose `fullscreenchange` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.webkitfullscreenchangeEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  static const EventStreamProvider<Event> fullscreenChangeEvent = const EventStreamProvider<Event>('webkitfullscreenchange');

  /**
   * Static factory designed to expose `fullscreenerror` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.webkitfullscreenerrorEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  static const EventStreamProvider<Event> fullscreenErrorEvent = const EventStreamProvider<Event>('webkitfullscreenerror');

  @DomName('Element.contentEditable')
  @DocsEditable()
  String contentEditable;

  @DomName('Element.dir')
  @DocsEditable()
  String dir;

  /**
   * Indicates whether the element can be dragged and dropped.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.draggable')
  @DocsEditable()
  bool draggable;

  /**
   * Indicates whether the element is not relevant to the page's current state.
   *
   * ## Other resources
   *
   * * [Hidden attribute specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#the-hidden-attribute)
   * from WHATWG.
   */
  @DomName('Element.hidden')
  @DocsEditable()
  bool hidden;

  @DomName('Element.isContentEditable')
  @DocsEditable()
  final bool isContentEditable;

  @DomName('Element.lang')
  @DocsEditable()
  String lang;

  @DomName('Element.spellcheck')
  @DocsEditable()
  // http://blog.whatwg.org/the-road-to-html-5-spellchecking
  @Experimental() // nonstandard
  bool spellcheck;

  @DomName('Element.tabIndex')
  @DocsEditable()
  int tabIndex;

  @DomName('Element.title')
  @DocsEditable()
  String title;

  /**
   * Specifies whether this element's text content changes when the page is
   * localized.
   *
   * ## Other resources
   *
   * * [The translate attribute]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#the-translate-attribute)
   * from WHATWG.
   */
  @DomName('Element.translate')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#the-translate-attribute
  @Experimental()
  bool translate;

  @JSName('webkitdropzone')
  /**
   * A set of space-separated keywords that specify what kind of data this
   * Element accepts on drop and what to do with that data.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.webkitdropzone')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#the-dropzone-attribute
  String dropzone;

  @DomName('Element.click')
  @DocsEditable()
  void click() native;

  @JSName('attributes')
  @DomName('Element.attributes')
  @DocsEditable()
  final _NamedNodeMap _attributes;

  @DomName('Element.className')
  @DocsEditable()
  String className;

  @DomName('Element.clientHeight')
  @DocsEditable()
  final int clientHeight;

  @DomName('Element.clientLeft')
  @DocsEditable()
  final int clientLeft;

  @DomName('Element.clientTop')
  @DocsEditable()
  final int clientTop;

  @DomName('Element.clientWidth')
  @DocsEditable()
  final int clientWidth;

  @DomName('Element.id')
  @DocsEditable()
  String id;

  @JSName('innerHTML')
  @DomName('Element.innerHTML')
  @DocsEditable()
  String _innerHtml;

  // Use implementation from Node.
  // final String _localName;

  // Use implementation from Node.
  // final String _namespaceUri;

  @DomName('Element.offsetHeight')
  @DocsEditable()
  final int offsetHeight;

  @DomName('Element.offsetLeft')
  @DocsEditable()
  final int offsetLeft;

  @DomName('Element.offsetParent')
  @DocsEditable()
  final Element offsetParent;

  @DomName('Element.offsetTop')
  @DocsEditable()
  final int offsetTop;

  @DomName('Element.offsetWidth')
  @DocsEditable()
  final int offsetWidth;

  @JSName('outerHTML')
  @DomName('Element.outerHTML')
  @DocsEditable()
  final String outerHtml;

  @DomName('Element.scrollHeight')
  @DocsEditable()
  final int scrollHeight;

  @DomName('Element.scrollLeft')
  @DocsEditable()
  int scrollLeft;

  @DomName('Element.scrollTop')
  @DocsEditable()
  int scrollTop;

  @DomName('Element.scrollWidth')
  @DocsEditable()
  final int scrollWidth;

  @DomName('Element.style')
  @DocsEditable()
  final CssStyleDeclaration style;

  @DomName('Element.tagName')
  @DocsEditable()
  final String tagName;

  @DomName('Element.animate')
  @DocsEditable()
  @Experimental() // untriaged
  Animation animate(List<Map> keyframes, [timingInput]) {
    if ((timingInput is Map || timingInput == null)) {
      var timingInput_1 = convertDartToNative_Dictionary(timingInput);
      return _animate_1(keyframes, timingInput_1);
    }
    if ((timingInput is num || timingInput == null)) {
      return _animate_2(keyframes, timingInput);
    }
    if (timingInput == null) {
      return _animate_3(keyframes);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  @JSName('animate')
  @DomName('Element.animate')
  @DocsEditable()
  @Experimental() // untriaged
  Animation _animate_1(List<Map> keyframes, timingInput) native;
  @JSName('animate')
  @DomName('Element.animate')
  @DocsEditable()
  @Experimental() // untriaged
  Animation _animate_2(List<Map> keyframes, num timingInput) native;
  @JSName('animate')
  @DomName('Element.animate')
  @DocsEditable()
  @Experimental() // untriaged
  Animation _animate_3(List<Map> keyframes) native;

  @DomName('Element.blur')
  @DocsEditable()
  void blur() native;

  @DomName('Element.focus')
  @DocsEditable()
  void focus() native;

  @DomName('Element.getAttribute')
  @DocsEditable()
  @Experimental() // untriaged
  String getAttribute(String name) native;

  @DomName('Element.getAttributeNS')
  @DocsEditable()
  @Experimental() // untriaged
  String getAttributeNS(String namespaceURI, String localName) native;

  /**
   * Returns the smallest bounding rectangle that encompasses this element's
   * padding, scrollbar, and border.
   *
   * ## Other resources
   *
   * * [Element.getBoundingClientRect]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect)
   * from MDN.
   * * [The getBoundingClientRect() method]
   * (http://www.w3.org/TR/cssom-view/#the-getclientrects-and-getboundingclientrect-methods)
   * from W3C.
   */
  @DomName('Element.getBoundingClientRect')
  @DocsEditable()
  Rectangle getBoundingClientRect() native;

  /**
   * Returns a list of bounding rectangles for each box associated with this
   * element.
   *
   * ## Other resources
   *
   * * [Element.getClientRects]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Element.getClientRects)
   * from MDN.
   * * [The getClientRects() method]
   * (http://www.w3.org/TR/cssom-view/#the-getclientrects-and-getboundingclientrect-methods)
   * from W3C.
   */
  @DomName('Element.getClientRects')
  @DocsEditable()
  @Returns('_ClientRectList')
  @Creates('_ClientRectList')
  List<Rectangle> getClientRects() native;

  /**
   * Returns a list of shadow DOM insertion points to which this element is
   * distributed.
   *
   * ## Other resources
   *
   * * [Shadow DOM specification]
   * (https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html)
   * from W3C.
   */
  @DomName('Element.getDestinationInsertionPoints')
  @DocsEditable()
  @Experimental() // untriaged
  @Returns('NodeList')
  @Creates('NodeList')
  List<Node> getDestinationInsertionPoints() native;

  /**
   * Returns a list of nodes with the given class name inside this element.
   *
   * ## Other resources
   *
   * * [getElementsByClassName]
   * (https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByClassName)
   * from MDN.
   * * [DOM specification]
   * (http://www.w3.org/TR/domcore/) from W3C.
   */
  @DomName('Element.getElementsByClassName')
  @DocsEditable()
  @Creates('NodeList|HtmlCollection')
  @Returns('NodeList|HtmlCollection')
  List<Node> getElementsByClassName(String classNames) native;

  @JSName('getElementsByTagName')
  @DomName('Element.getElementsByTagName')
  @DocsEditable()
  @Creates('NodeList|HtmlCollection')
  @Returns('NodeList|HtmlCollection')
  List<Node> _getElementsByTagName(String name) native;

  @JSName('hasAttribute')
  @DomName('Element.hasAttribute')
  @DocsEditable()
  bool _hasAttribute(String name) native;

  @JSName('hasAttributeNS')
  @DomName('Element.hasAttributeNS')
  @DocsEditable()
  bool _hasAttributeNS(String namespaceURI, String localName) native;

  /**
   * Finds the first descendant element of this element that matches the
   * specified group of selectors.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     // Gets the first descendant with the class 'classname'
   *     var element = element.querySelector('.className');
   *     // Gets the element with id 'id'
   *     var element = element.querySelector('#id');
   *     // Gets the first descendant [ImageElement]
   *     var img = element.querySelector('img');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  @DomName('Element.querySelector')
  @DocsEditable()
  Element querySelector(String selectors) native;

  @JSName('querySelectorAll')
  @DomName('Element.querySelectorAll')
  @DocsEditable()
  @Returns('NodeList')
  @Creates('NodeList')
  List<Node> _querySelectorAll(String selectors) native;

  @JSName('removeAttribute')
  @DomName('Element.removeAttribute')
  @DocsEditable()
  void _removeAttribute(String name) native;

  @JSName('removeAttributeNS')
  @DomName('Element.removeAttributeNS')
  @DocsEditable()
  void _removeAttributeNS(String namespaceURI, String localName) native;

  /**
   * Scrolls the element by a number of lines.
   *
   * ## Other resources
   *
   * * [scrollByLines]
   * (http://docs.webplatform.org/wiki/dom/methods/scrollByLines) from WebPlatform.org.
   */
  @DomName('Element.scrollByLines')
  @DocsEditable()
  void scrollByLines(int lines) native;

  /**
   * Scrolls the element by a number of pages.
   *
   * ## Other resources
   *
   * * [scrollByPages]
   * (http://docs.webplatform.org/wiki/dom/methods/scrollByPages) from WebPlatform.org.
   */
  @DomName('Element.scrollByPages')
  @DocsEditable()
  void scrollByPages(int pages) native;

  @JSName('scrollIntoView')
  @DomName('Element.scrollIntoView')
  @DocsEditable()
  void _scrollIntoView([bool alignWithTop]) native;

  @JSName('scrollIntoViewIfNeeded')
  @DomName('Element.scrollIntoViewIfNeeded')
  @DocsEditable()
  // http://docs.webplatform.org/wiki/dom/methods/scrollIntoViewIfNeeded
  @Experimental() // non-standard
  void _scrollIntoViewIfNeeded([bool centerIfNeeded]) native;

  @DomName('Element.setAttribute')
  @DocsEditable()
  void setAttribute(String name, String value) native;

  @DomName('Element.setAttributeNS')
  @DocsEditable()
  void setAttributeNS(String namespaceURI, String qualifiedName, String value) native;

  @JSName('webkitRequestFullscreen')
  /**
   * Displays this element fullscreen.
   *
   * ## Other resources
   *
   * * [Using the fullscreen API]
   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)
   * tutorial from WebPlatform.org.
   * * [Fullscreen specification]
   * (http://www.w3.org/TR/fullscreen/) from W3C.
   */
  @DomName('Element.webkitRequestFullscreen')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#dom-element-requestfullscreen
  void requestFullscreen() native;

  @JSName('webkitRequestPointerLock')
  /**
   * Locks the mouse pointer to this element.
   *
   * ## Other resources
   *
   * * [Pointer lock and first person shooter controls]
   * (http://www.html5rocks.com/en/tutorials/pointerlock/intro/) tutorial from
   * HTML5Rocks.
   *
   * * [Pointer lock specification]
   * (http://www.w3.org/TR/pointerlock/) from W3C.
   */
  @DomName('Element.webkitRequestPointerLock')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html#widl-Element-requestPointerLock-void
  void requestPointerLock() native;

  // From ChildNode

  @DomName('Element.nextElementSibling')
  @DocsEditable()
  final Element nextElementSibling;

  @DomName('Element.previousElementSibling')
  @DocsEditable()
  final Element previousElementSibling;

  // From ParentNode

  @JSName('childElementCount')
  @DomName('Element.childElementCount')
  @DocsEditable()
  final int _childElementCount;

  @JSName('children')
  @DomName('Element.children')
  @DocsEditable()
  @Returns('HtmlCollection')
  @Creates('HtmlCollection')
  final List<Node> _children;

  @JSName('firstElementChild')
  @DomName('Element.firstElementChild')
  @DocsEditable()
  final Element _firstElementChild;

  @JSName('lastElementChild')
  @DomName('Element.lastElementChild')
  @DocsEditable()
  final Element _lastElementChild;

  /// Stream of `abort` events handled by this [Element].
  @DomName('Element.onabort')
  @DocsEditable()
  ElementStream<Event> get onAbort => abortEvent.forElement(this);

  /// Stream of `beforecopy` events handled by this [Element].
  @DomName('Element.onbeforecopy')
  @DocsEditable()
  ElementStream<Event> get onBeforeCopy => beforeCopyEvent.forElement(this);

  /// Stream of `beforecut` events handled by this [Element].
  @DomName('Element.onbeforecut')
  @DocsEditable()
  ElementStream<Event> get onBeforeCut => beforeCutEvent.forElement(this);

  /// Stream of `beforepaste` events handled by this [Element].
  @DomName('Element.onbeforepaste')
  @DocsEditable()
  ElementStream<Event> get onBeforePaste => beforePasteEvent.forElement(this);

  /// Stream of `blur` events handled by this [Element].
  @DomName('Element.onblur')
  @DocsEditable()
  ElementStream<Event> get onBlur => blurEvent.forElement(this);

  /// Stream of `change` events handled by this [Element].
  @DomName('Element.onchange')
  @DocsEditable()
  ElementStream<Event> get onChange => changeEvent.forElement(this);

  /// Stream of `click` events handled by this [Element].
  @DomName('Element.onclick')
  @DocsEditable()
  ElementStream<MouseEvent> get onClick => clickEvent.forElement(this);

  /// Stream of `contextmenu` events handled by this [Element].
  @DomName('Element.oncontextmenu')
  @DocsEditable()
  ElementStream<MouseEvent> get onContextMenu => contextMenuEvent.forElement(this);

  /// Stream of `copy` events handled by this [Element].
  @DomName('Element.oncopy')
  @DocsEditable()
  ElementStream<Event> get onCopy => copyEvent.forElement(this);

  /// Stream of `cut` events handled by this [Element].
  @DomName('Element.oncut')
  @DocsEditable()
  ElementStream<Event> get onCut => cutEvent.forElement(this);

  /// Stream of `doubleclick` events handled by this [Element].
  @DomName('Element.ondblclick')
  @DocsEditable()
  ElementStream<Event> get onDoubleClick => doubleClickEvent.forElement(this);

  /**
   * A stream of `drag` events fired when this element currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondrag')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrag => dragEvent.forElement(this);

  /**
   * A stream of `dragend` events fired when this element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragend')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnd => dragEndEvent.forElement(this);

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragenter')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnter => dragEnterEvent.forElement(this);

  /**
   * A stream of `dragleave` events fired when an object being dragged over this
   * element leaves this element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragleave')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragLeave => dragLeaveEvent.forElement(this);

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragover')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragOver => dragOverEvent.forElement(this);

  /**
   * A stream of `dragstart` events fired when this element starts being
   * dragged.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragstart')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragStart => dragStartEvent.forElement(this);

  /**
   * A stream of `drop` events fired when a dragged object is dropped on this
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondrop')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrop => dropEvent.forElement(this);

  /// Stream of `error` events handled by this [Element].
  @DomName('Element.onerror')
  @DocsEditable()
  ElementStream<Event> get onError => errorEvent.forElement(this);

  /// Stream of `focus` events handled by this [Element].
  @DomName('Element.onfocus')
  @DocsEditable()
  ElementStream<Event> get onFocus => focusEvent.forElement(this);

  /// Stream of `input` events handled by this [Element].
  @DomName('Element.oninput')
  @DocsEditable()
  ElementStream<Event> get onInput => inputEvent.forElement(this);

  /// Stream of `invalid` events handled by this [Element].
  @DomName('Element.oninvalid')
  @DocsEditable()
  ElementStream<Event> get onInvalid => invalidEvent.forElement(this);

  /// Stream of `keydown` events handled by this [Element].
  @DomName('Element.onkeydown')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyDown => keyDownEvent.forElement(this);

  /// Stream of `keypress` events handled by this [Element].
  @DomName('Element.onkeypress')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyPress => keyPressEvent.forElement(this);

  /// Stream of `keyup` events handled by this [Element].
  @DomName('Element.onkeyup')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyUp => keyUpEvent.forElement(this);

  /// Stream of `load` events handled by this [Element].
  @DomName('Element.onload')
  @DocsEditable()
  ElementStream<Event> get onLoad => loadEvent.forElement(this);

  /// Stream of `mousedown` events handled by this [Element].
  @DomName('Element.onmousedown')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseDown => mouseDownEvent.forElement(this);

  /// Stream of `mouseenter` events handled by this [Element].
  @DomName('Element.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseEnter => mouseEnterEvent.forElement(this);

  /// Stream of `mouseleave` events handled by this [Element].
  @DomName('Element.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseLeave => mouseLeaveEvent.forElement(this);

  /// Stream of `mousemove` events handled by this [Element].
  @DomName('Element.onmousemove')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseMove => mouseMoveEvent.forElement(this);

  /// Stream of `mouseout` events handled by this [Element].
  @DomName('Element.onmouseout')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOut => mouseOutEvent.forElement(this);

  /// Stream of `mouseover` events handled by this [Element].
  @DomName('Element.onmouseover')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOver => mouseOverEvent.forElement(this);

  /// Stream of `mouseup` events handled by this [Element].
  @DomName('Element.onmouseup')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseUp => mouseUpEvent.forElement(this);

  /// Stream of `mousewheel` events handled by this [Element].
  @DomName('Element.onmousewheel')
  @DocsEditable()
  // http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents
  @Experimental() // non-standard
  ElementStream<WheelEvent> get onMouseWheel => mouseWheelEvent.forElement(this);

  /// Stream of `paste` events handled by this [Element].
  @DomName('Element.onpaste')
  @DocsEditable()
  ElementStream<Event> get onPaste => pasteEvent.forElement(this);

  /// Stream of `reset` events handled by this [Element].
  @DomName('Element.onreset')
  @DocsEditable()
  ElementStream<Event> get onReset => resetEvent.forElement(this);

  @DomName('Element.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onResize => resizeEvent.forElement(this);

  /// Stream of `scroll` events handled by this [Element].
  @DomName('Element.onscroll')
  @DocsEditable()
  ElementStream<Event> get onScroll => scrollEvent.forElement(this);

  /// Stream of `search` events handled by this [Element].
  @DomName('Element.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  ElementStream<Event> get onSearch => searchEvent.forElement(this);

  /// Stream of `select` events handled by this [Element].
  @DomName('Element.onselect')
  @DocsEditable()
  ElementStream<Event> get onSelect => selectEvent.forElement(this);

  /// Stream of `selectstart` events handled by this [Element].
  @DomName('Element.onselectstart')
  @DocsEditable()
  @Experimental() // nonstandard
  ElementStream<Event> get onSelectStart => selectStartEvent.forElement(this);

  /// Stream of `submit` events handled by this [Element].
  @DomName('Element.onsubmit')
  @DocsEditable()
  ElementStream<Event> get onSubmit => submitEvent.forElement(this);

  /// Stream of `touchcancel` events handled by this [Element].
  @DomName('Element.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchCancel => touchCancelEvent.forElement(this);

  /// Stream of `touchend` events handled by this [Element].
  @DomName('Element.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnd => touchEndEvent.forElement(this);

  /// Stream of `touchenter` events handled by this [Element].
  @DomName('Element.ontouchenter')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnter => touchEnterEvent.forElement(this);

  /// Stream of `touchleave` events handled by this [Element].
  @DomName('Element.ontouchleave')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchLeave => touchLeaveEvent.forElement(this);

  /// Stream of `touchmove` events handled by this [Element].
  @DomName('Element.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchMove => touchMoveEvent.forElement(this);

  /// Stream of `touchstart` events handled by this [Element].
  @DomName('Element.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchStart => touchStartEvent.forElement(this);

  /// Stream of `transitionend` events handled by this [Element].
  @DomName('Element.ontransitionend')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  ElementStream<TransitionEvent> get onTransitionEnd => transitionEndEvent.forElement(this);

  /// Stream of `fullscreenchange` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenchange')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenChange => fullscreenChangeEvent.forElement(this);

  /// Stream of `fullscreenerror` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenError => fullscreenErrorEvent.forElement(this);

}


class _ElementFactoryProvider {

  @DomName('Document.createElement')
  // Optimization to improve performance until the dart2js compiler inlines this
  // method.
  static dynamic createElement_tag(String tag, String typeExtension) {
    // Firefox may return a JS function for some types (Embed, Object).
    if (typeExtension != null) {
      return JS('Element|=Object', 'document.createElement(#, #)',
          tag, typeExtension);
    }
    // Should be able to eliminate this and just call the two-arg version above
    // with null typeExtension, but Chrome treats the tag as case-sensitive if
    // typeExtension is null.
    // https://code.google.com/p/chromium/issues/detail?id=282467
    return JS('Element|=Object', 'document.createElement(#)', tag);
  }

}


/**
 * Options for Element.scrollIntoView.
 */
class ScrollAlignment {
  final _value;
  const ScrollAlignment._internal(this._value);
  toString() => 'ScrollAlignment.$_value';

  /// Attempt to align the element to the top of the scrollable area.
  static const TOP = const ScrollAlignment._internal('TOP');
  /// Attempt to center the element in the scrollable area.
  static const CENTER = const ScrollAlignment._internal('CENTER');
  /// Attempt to align the element to the bottom of the scrollable area.
  static const BOTTOM = const ScrollAlignment._internal('BOTTOM');
}
// 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.


@DocsEditable()
@DomName('HTMLEmbedElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
class EmbedElement extends HtmlElement native "HTMLEmbedElement" {
  // To suppress missing implicit constructor warnings.
  factory EmbedElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLEmbedElement.HTMLEmbedElement')
  @DocsEditable()
  factory EmbedElement() => document.createElement("embed");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  EmbedElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('embed');

  @DomName('HTMLEmbedElement.height')
  @DocsEditable()
  String height;

  @DomName('HTMLEmbedElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLEmbedElement.src')
  @DocsEditable()
  String src;

  @DomName('HTMLEmbedElement.type')
  @DocsEditable()
  String type;

  @DomName('HTMLEmbedElement.width')
  @DocsEditable()
  String width;

  @DomName('HTMLEmbedElement.__getter__')
  @DocsEditable()
  bool __getter__(index_OR_name) native;

  @DomName('HTMLEmbedElement.__setter__')
  @DocsEditable()
  void __setter__(index_OR_name, Node value) native;
}
// 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.


@DomName('EntriesCallback')
// http://www.w3.org/TR/file-system-api/#the-entriescallback-interface
@Experimental()
typedef void _EntriesCallback(List<Entry> entries);
// 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.


@DocsEditable()
@DomName('Entry')
// http://www.w3.org/TR/file-system-api/#the-entry-interface
@Experimental()
class Entry extends Interceptor native "Entry" {
  // To suppress missing implicit constructor warnings.
  factory Entry._() { throw new UnsupportedError("Not supported"); }

  @DomName('Entry.filesystem')
  @DocsEditable()
  final FileSystem filesystem;

  @DomName('Entry.fullPath')
  @DocsEditable()
  final String fullPath;

  @DomName('Entry.isDirectory')
  @DocsEditable()
  final bool isDirectory;

  @DomName('Entry.isFile')
  @DocsEditable()
  final bool isFile;

  @DomName('Entry.name')
  @DocsEditable()
  final String name;

  @JSName('copyTo')
  @DomName('Entry.copyTo')
  @DocsEditable()
  void _copyTo(DirectoryEntry parent, {String name, _EntryCallback successCallback, _ErrorCallback errorCallback}) native;

  @JSName('copyTo')
  @DomName('Entry.copyTo')
  @DocsEditable()
  Future<Entry> copyTo(DirectoryEntry parent, {String name}) {
    var completer = new Completer<Entry>();
    _copyTo(parent, name : name,
        successCallback : (value) { completer.complete(value); },
        errorCallback : (error) { completer.completeError(error); });
    return completer.future;
  }

  @JSName('getMetadata')
  @DomName('Entry.getMetadata')
  @DocsEditable()
  void _getMetadata(MetadataCallback successCallback, [_ErrorCallback errorCallback]) native;

  @JSName('getMetadata')
  @DomName('Entry.getMetadata')
  @DocsEditable()
  Future<Metadata> getMetadata() {
    var completer = new Completer<Metadata>();
    _getMetadata(
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  @JSName('getParent')
  @DomName('Entry.getParent')
  @DocsEditable()
  void _getParent([_EntryCallback successCallback, _ErrorCallback errorCallback]) native;

  @JSName('getParent')
  @DomName('Entry.getParent')
  @DocsEditable()
  Future<Entry> getParent() {
    var completer = new Completer<Entry>();
    _getParent(
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  @JSName('moveTo')
  @DomName('Entry.moveTo')
  @DocsEditable()
  void _moveTo(DirectoryEntry parent, {String name, _EntryCallback successCallback, _ErrorCallback errorCallback}) native;

  @JSName('moveTo')
  @DomName('Entry.moveTo')
  @DocsEditable()
  Future<Entry> moveTo(DirectoryEntry parent, {String name}) {
    var completer = new Completer<Entry>();
    _moveTo(parent, name : name,
        successCallback : (value) { completer.complete(value); },
        errorCallback : (error) { completer.completeError(error); });
    return completer.future;
  }

  @JSName('remove')
  @DomName('Entry.remove')
  @DocsEditable()
  void _remove(VoidCallback successCallback, [_ErrorCallback errorCallback]) native;

  @JSName('remove')
  @DomName('Entry.remove')
  @DocsEditable()
  Future remove() {
    var completer = new Completer();
    _remove(
        () { completer.complete(); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  @JSName('toURL')
  @DomName('Entry.toURL')
  @DocsEditable()
  String toUrl() native;
}
// 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.


@DomName('EntryCallback')
// http://www.w3.org/TR/file-system-api/#the-entrycallback-interface
@Experimental()
typedef void _EntryCallback(Entry entry);
// 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.


@DomName('ErrorCallback')
// http://www.w3.org/TR/file-system-api/#the-errorcallback-interface
@Experimental()
typedef void _ErrorCallback(FileError error);
// 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.


@DocsEditable()
@DomName('ErrorEvent')
@Unstable()
class ErrorEvent extends Event native "ErrorEvent" {
  // To suppress missing implicit constructor warnings.
  factory ErrorEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('ErrorEvent.colno')
  @DocsEditable()
  @Experimental() // untriaged
  final int colno;

  @DomName('ErrorEvent.error')
  @DocsEditable()
  @Experimental() // untriaged
  @Creates('Null')
  final Object error;

  @DomName('ErrorEvent.filename')
  @DocsEditable()
  final String filename;

  @DomName('ErrorEvent.lineno')
  @DocsEditable()
  final int lineno;

  @DomName('ErrorEvent.message')
  @DocsEditable()
  final String message;
}
// 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.


@DomName('Event')
class Event extends Interceptor native "Event" {
  // In JS, canBubble and cancelable are technically required parameters to
  // init*Event. In practice, though, if they aren't provided they simply
  // default to false (since that's Boolean(undefined)).
  //
  // Contrary to JS, we default canBubble and cancelable to true, since that's
  // what people want most of the time anyway.
  factory Event(String type,
      {bool canBubble: true, bool cancelable: true}) {
    return new Event.eventType('Event', type, canBubble: canBubble,
        cancelable: cancelable);
  }

  /**
   * Creates a new Event object of the specified type.
   *
   * This is analogous to document.createEvent.
   * Normally events should be created via their constructors, if available.
   *
   *     var e = new Event.type('MouseEvent', 'mousedown', true, true);
   */
  factory Event.eventType(String type, String name, {bool canBubble: true,
      bool cancelable: true}) {
    final Event e = document._createEvent(type);
    e._initEvent(name, canBubble, cancelable);
    return e;
  }
  
  /** The CSS selector involved with event delegation. */
  String _selector;

  /**
   * A pointer to the element whose CSS selector matched within which an event
   * was fired. If this Event was not associated with any Event delegation,
   * accessing this value will throw an [UnsupportedError].
   */
  Element get matchingTarget {
    if (_selector == null) {
      throw new UnsupportedError('Cannot call matchingTarget if this Event did'
          ' not arise as a result of event delegation.');
    }
    var currentTarget = this.currentTarget;
    var target = this.target;
    var matchedTarget;
    do {
      if (target.matches(_selector)) return target;
      target = target.parent;
    } while (target != null && target != currentTarget.parent);
    throw new StateError('No selector matched for populating matchedTarget.');
  }
  // To suppress missing implicit constructor warnings.
  factory Event._() { throw new UnsupportedError("Not supported"); }

  /**
   * This event is being handled by the event target.
   *
   * ## Other resources
   *
   * * [Target phase] (http://www.w3.org/TR/DOM-Level-3-Events/#target-phase)
   * from W3C.
   */
  @DomName('Event.AT_TARGET')
  @DocsEditable()
  static const int AT_TARGET = 2;

  /**
   * This event is bubbling up through the target's ancestors.
   *
   * ## Other resources
   *
   * * [Bubble phase] (http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
   * from W3C.
   */
  @DomName('Event.BUBBLING_PHASE')
  @DocsEditable()
  static const int BUBBLING_PHASE = 3;

  /**
   * This event is propagating through the target's ancestors, starting from the
   * document.
   *
   * ## Other resources
   *
   * * [Bubble phase] (http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
   * from W3C.
   */
  @DomName('Event.CAPTURING_PHASE')
  @DocsEditable()
  static const int CAPTURING_PHASE = 1;

  @DomName('Event.bubbles')
  @DocsEditable()
  final bool bubbles;

  @DomName('Event.cancelable')
  @DocsEditable()
  final bool cancelable;

  /**
   * Access to the system's clipboard data during copy, cut, and paste events.
   *
   * ## Other resources
   *
   * * [clipboardData specification]
   * (http://www.w3.org/TR/clipboard-apis/#attributes) from W3C.
   */
  @DomName('Event.clipboardData')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // Part of copy/paste
  @Experimental() // nonstandard
  final DataTransfer clipboardData;

  @DomName('Event.currentTarget')
  @DocsEditable()
  EventTarget get currentTarget => _convertNativeToDart_EventTarget(this._get_currentTarget);
  @JSName('currentTarget')
  @DomName('Event.currentTarget')
  @DocsEditable()
  @Creates('Null')
  @Returns('EventTarget|=Object')
  final dynamic _get_currentTarget;

  @DomName('Event.defaultPrevented')
  @DocsEditable()
  final bool defaultPrevented;

  @DomName('Event.eventPhase')
  @DocsEditable()
  final int eventPhase;

  /**
   * This event's path, taking into account shadow DOM.
   *
   * ## Other resources
   *
   * * [Shadow DOM extensions to Event]
   * (http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event) from
   * W3C.
   */
  @DomName('Event.path')
  @DocsEditable()
  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#extensions-to-event
  @Experimental()
  @Returns('NodeList')
  @Creates('NodeList')
  final List<Node> path;

  @DomName('Event.target')
  @DocsEditable()
  EventTarget get target => _convertNativeToDart_EventTarget(this._get_target);
  @JSName('target')
  @DomName('Event.target')
  @DocsEditable()
  @Creates('Node')
  @Returns('EventTarget|=Object')
  final dynamic _get_target;

  @DomName('Event.timeStamp')
  @DocsEditable()
  final int timeStamp;

  @DomName('Event.type')
  @DocsEditable()
  final String type;

  @JSName('initEvent')
  @DomName('Event.initEvent')
  @DocsEditable()
  void _initEvent(String eventTypeArg, bool canBubbleArg, bool cancelableArg) native;

  @DomName('Event.preventDefault')
  @DocsEditable()
  void preventDefault() native;

  @DomName('Event.stopImmediatePropagation')
  @DocsEditable()
  void stopImmediatePropagation() native;

  @DomName('Event.stopPropagation')
  @DocsEditable()
  void stopPropagation() native;

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


@DomName('EventSource')
// http://www.w3.org/TR/eventsource/#the-eventsource-interface
@Experimental() // stable
class EventSource extends EventTarget native "EventSource" {
  factory EventSource(String title, {withCredentials: false}) {
    var parsedOptions = {
      'withCredentials': withCredentials,
    };
    return EventSource._factoryEventSource(title, parsedOptions);
  }
  // To suppress missing implicit constructor warnings.
  factory EventSource._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [EventSource].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('EventSource.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [EventSource].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('EventSource.messageEvent')
  @DocsEditable()
  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');

  /**
   * Static factory designed to expose `open` events to event
   * handlers that are not necessarily instances of [EventSource].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('EventSource.openEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> openEvent = const EventStreamProvider<Event>('open');

  @DomName('EventSource.EventSource')
  @DocsEditable()
  static EventSource _factoryEventSource(String url, [Map eventSourceInit]) {
    if (eventSourceInit != null) {
      return EventSource._create_1(url, eventSourceInit);
    }
    return EventSource._create_2(url);
  }
  static EventSource _create_1(url, eventSourceInit) => JS('EventSource', 'new EventSource(#,#)', url, eventSourceInit);
  static EventSource _create_2(url) => JS('EventSource', 'new EventSource(#)', url);

  @DomName('EventSource.CLOSED')
  @DocsEditable()
  static const int CLOSED = 2;

  @DomName('EventSource.CONNECTING')
  @DocsEditable()
  static const int CONNECTING = 0;

  @DomName('EventSource.OPEN')
  @DocsEditable()
  static const int OPEN = 1;

  @DomName('EventSource.readyState')
  @DocsEditable()
  final int readyState;

  @DomName('EventSource.url')
  @DocsEditable()
  final String url;

  @DomName('EventSource.withCredentials')
  @DocsEditable()
  final bool withCredentials;

  @DomName('EventSource.close')
  @DocsEditable()
  void close() native;

  /// Stream of `error` events handled by this [EventSource].
  @DomName('EventSource.onerror')
  @DocsEditable()
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `message` events handled by this [EventSource].
  @DomName('EventSource.onmessage')
  @DocsEditable()
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  /// Stream of `open` events handled by this [EventSource].
  @DomName('EventSource.onopen')
  @DocsEditable()
  Stream<Event> get onOpen => openEvent.forTarget(this);

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


/**
 * Base class that supports listening for and dispatching browser events.
 *
 * Normally events are accessed via the Stream getter:
 *
 *     element.onMouseOver.listen((e) => print('Mouse over!'));
 *
 * To access bubbling events which are declared on one element, but may bubble
 * up to another element type (common for MediaElement events):
 *
 *     MediaElement.pauseEvent.forTarget(document.body).listen(...);
 *
 * To useCapture on events:
 *
 *     Element.keyDownEvent.forTarget(element, useCapture: true).listen(...);
 *
 * Custom events can be declared as:
 *
 *    class DataGenerator {
 *      static EventStreamProvider<Event> dataEvent =
 *          new EventStreamProvider('data');
 *    }
 *
 * Then listeners should access the event with:
 *
 *     DataGenerator.dataEvent.forTarget(element).listen(...);
 *
 * Custom events can also be accessed as:
 *
 *     element.on['some_event'].listen(...);
 *
 * This approach is generally discouraged as it loses the event typing and
 * some DOM events may have multiple platform-dependent event names under the
 * covers. By using the standard Stream getters you will get the platform
 * specific event name automatically.
 */
class Events {
  /* Raw event target. */
  final EventTarget _ptr;

  Events(this._ptr);

  Stream operator [](String type) {
    return new _EventStream(_ptr, type, false);
  }
}

class ElementEvents extends Events {
  /* Raw event target. */
  final Element _ptr;
  static final webkitEvents = {
    'animationend' : 'webkitAnimationEnd', 
    'animationiteration' : 'webkitAnimationIteration', 
    'animationstart' : 'webkitAnimationStart', 
    'fullscreenchange' : 'webkitfullscreenchange', 
    'fullscreenerror' : 'webkitfullscreenerror',
    'keyadded' : 'webkitkeyadded', 
    'keyerror' : 'webkitkeyerror', 
    'keymessage' : 'webkitkeymessage', 
    'needkey' : 'webkitneedkey', 
    'pointerlockchange' : 'webkitpointerlockchange', 
    'pointerlockerror' : 'webkitpointerlockerror', 
    'resourcetimingbufferfull' : 'webkitresourcetimingbufferfull', 
    'transitionend': 'webkitTransitionEnd',
    'speechchange' : 'webkitSpeechChange'
  };

  ElementEvents(Element ptr) : this._ptr = ptr, super(ptr);

  Stream operator [](String type) {
    if (webkitEvents.keys.contains(type.toLowerCase())) {
      if (Device.isWebKit) {
        return new _ElementEventStreamImpl(
            _ptr, webkitEvents[type.toLowerCase()], false);
      }
    }
    return new _ElementEventStreamImpl(_ptr, type, false);
  }
}

/**
 * Base class for all browser objects that support events.
 *
 * Use the [on] property to add, and remove events
 * for compile-time type checks and a more concise API.
 */
@DomName('EventTarget')
class EventTarget extends Interceptor native "EventTarget" {

  // Custom element created callback.
  EventTarget._created();

  /**
   * This is an ease-of-use accessor for event streams which should only be
   * used when an explicit accessor is not available.
   */
  Events get on => new Events(this);
  // To suppress missing implicit constructor warnings.
  factory EventTarget._() { throw new UnsupportedError("Not supported"); }

  @DomName('EventTarget.addEventListener')
  @DocsEditable()
  void addEventListener(String type, EventListener listener, [bool useCapture]) native;

  @DomName('EventTarget.dispatchEvent')
  @DocsEditable()
  bool dispatchEvent(Event event) native;

  @DomName('EventTarget.removeEventListener')
  @DocsEditable()
  void removeEventListener(String type, EventListener listener, [bool useCapture]) native;

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


@DocsEditable()
@DomName('HTMLFieldSetElement')
@Unstable()
class FieldSetElement extends HtmlElement native "HTMLFieldSetElement" {
  // To suppress missing implicit constructor warnings.
  factory FieldSetElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLFieldSetElement.HTMLFieldSetElement')
  @DocsEditable()
  factory FieldSetElement() => document.createElement("fieldset");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  FieldSetElement.created() : super.created();

  @DomName('HTMLFieldSetElement.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('HTMLFieldSetElement.elements')
  @DocsEditable()
  @Returns('HtmlCollection')
  @Creates('HtmlCollection')
  final List<Node> elements;

  @DomName('HTMLFieldSetElement.form')
  @DocsEditable()
  final FormElement form;

  @DomName('HTMLFieldSetElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLFieldSetElement.type')
  @DocsEditable()
  final String type;

  @DomName('HTMLFieldSetElement.validationMessage')
  @DocsEditable()
  final String validationMessage;

  @DomName('HTMLFieldSetElement.validity')
  @DocsEditable()
  final ValidityState validity;

  @DomName('HTMLFieldSetElement.willValidate')
  @DocsEditable()
  final bool willValidate;

  @DomName('HTMLFieldSetElement.checkValidity')
  @DocsEditable()
  bool checkValidity() native;

  @DomName('HTMLFieldSetElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) native;
}
// 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.


@DocsEditable()
@DomName('File')
class File extends Blob native "File" {
  // To suppress missing implicit constructor warnings.
  factory File._() { throw new UnsupportedError("Not supported"); }

  @DomName('File.lastModified')
  @DocsEditable()
  @Experimental() // untriaged
  final int lastModified;

  @DomName('File.lastModifiedDate')
  @DocsEditable()
  DateTime get lastModifiedDate => convertNativeToDart_DateTime(this._get_lastModifiedDate);
  @JSName('lastModifiedDate')
  @DomName('File.lastModifiedDate')
  @DocsEditable()
  @Creates('Null')
  final dynamic _get_lastModifiedDate;

  @DomName('File.name')
  @DocsEditable()
  final String name;

  @JSName('webkitRelativePath')
  @DomName('File.webkitRelativePath')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://plus.sandbox.google.com/+AddyOsmani/posts/Dk5UhZ6zfF3
  final String relativePath;
}
// 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.


@DomName('FileCallback')
// http://www.w3.org/TR/file-system-api/#the-filecallback-interface
@Experimental()
typedef void _FileCallback(File file);
// 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.


@DocsEditable()
@DomName('FileEntry')
// http://www.w3.org/TR/file-system-api/#the-fileentry-interface
@Experimental()
class FileEntry extends Entry native "FileEntry" {
  // To suppress missing implicit constructor warnings.
  factory FileEntry._() { throw new UnsupportedError("Not supported"); }

  @JSName('createWriter')
  @DomName('FileEntry.createWriter')
  @DocsEditable()
  void _createWriter(_FileWriterCallback successCallback, [_ErrorCallback errorCallback]) native;

  @JSName('createWriter')
  @DomName('FileEntry.createWriter')
  @DocsEditable()
  Future<FileWriter> createWriter() {
    var completer = new Completer<FileWriter>();
    _createWriter(
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  @JSName('file')
  @DomName('FileEntry.file')
  @DocsEditable()
  void _file(_FileCallback successCallback, [_ErrorCallback errorCallback]) native;

  @JSName('file')
  @DomName('FileEntry.file')
  @DocsEditable()
  Future<File> file() {
    var completer = new Completer<File>();
    _file(
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); });
    return completer.future;
  }
}
// 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.


@DocsEditable()
@DomName('FileError')
// http://dev.w3.org/2009/dap/file-system/pub/FileSystem/
@Experimental()
class FileError extends DomError native "FileError" {
  // To suppress missing implicit constructor warnings.
  factory FileError._() { throw new UnsupportedError("Not supported"); }

  @DomName('FileError.ABORT_ERR')
  @DocsEditable()
  static const int ABORT_ERR = 3;

  @DomName('FileError.ENCODING_ERR')
  @DocsEditable()
  static const int ENCODING_ERR = 5;

  @DomName('FileError.INVALID_MODIFICATION_ERR')
  @DocsEditable()
  static const int INVALID_MODIFICATION_ERR = 9;

  @DomName('FileError.INVALID_STATE_ERR')
  @DocsEditable()
  static const int INVALID_STATE_ERR = 7;

  @DomName('FileError.NOT_FOUND_ERR')
  @DocsEditable()
  static const int NOT_FOUND_ERR = 1;

  @DomName('FileError.NOT_READABLE_ERR')
  @DocsEditable()
  static const int NOT_READABLE_ERR = 4;

  @DomName('FileError.NO_MODIFICATION_ALLOWED_ERR')
  @DocsEditable()
  static const int NO_MODIFICATION_ALLOWED_ERR = 6;

  @DomName('FileError.PATH_EXISTS_ERR')
  @DocsEditable()
  static const int PATH_EXISTS_ERR = 12;

  @DomName('FileError.QUOTA_EXCEEDED_ERR')
  @DocsEditable()
  static const int QUOTA_EXCEEDED_ERR = 10;

  @DomName('FileError.SECURITY_ERR')
  @DocsEditable()
  static const int SECURITY_ERR = 2;

  @DomName('FileError.SYNTAX_ERR')
  @DocsEditable()
  static const int SYNTAX_ERR = 8;

  @DomName('FileError.TYPE_MISMATCH_ERR')
  @DocsEditable()
  static const int TYPE_MISMATCH_ERR = 11;

  @DomName('FileError.code')
  @DocsEditable()
  final int code;
}
// 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.


@DocsEditable()
@DomName('FileList')
class FileList extends Interceptor with ListMixin<File>, ImmutableListMixin<File> implements JavaScriptIndexingBehavior, List<File> native "FileList" {
  // To suppress missing implicit constructor warnings.
  factory FileList._() { throw new UnsupportedError("Not supported"); }

  @DomName('FileList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  File operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("File", "#[#]", this, index);
  }
  void operator[]=(int index, File value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<File> mixins.
  // File is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  File get first {
    if (this.length > 0) {
      return JS('File', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  File get last {
    int len = this.length;
    if (len > 0) {
      return JS('File', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  File get single {
    int len = this.length;
    if (len == 1) {
      return JS('File', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  File elementAt(int index) => this[index];
  // -- end List<File> mixins.

  @DomName('FileList.item')
  @DocsEditable()
  File item(int index) native;
}
// Copyright (c) 2014, 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.


@DocsEditable()
@DomName('FileReader')
class FileReader extends EventTarget native "FileReader" {

  @DomName('FileReader.result')
  @DocsEditable()
  Object get result {
    var res = JS('Null|String|NativeByteBuffer', '#.result', this);
    if (res is ByteBuffer) {
      return new Uint8List.view(res);
    }
    return res;
  }

  // To suppress missing implicit constructor warnings.
  factory FileReader._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `abort` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileReader.abortEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> abortEvent = const EventStreamProvider<ProgressEvent>('abort');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileReader.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `load` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileReader.loadEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> loadEvent = const EventStreamProvider<ProgressEvent>('load');

  /**
   * Static factory designed to expose `loadend` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileReader.loadendEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> loadEndEvent = const EventStreamProvider<ProgressEvent>('loadend');

  /**
   * Static factory designed to expose `loadstart` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileReader.loadstartEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> loadStartEvent = const EventStreamProvider<ProgressEvent>('loadstart');

  /**
   * Static factory designed to expose `progress` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileReader.progressEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> progressEvent = const EventStreamProvider<ProgressEvent>('progress');

  @DomName('FileReader.FileReader')
  @DocsEditable()
  factory FileReader() {
    return FileReader._create_1();
  }
  static FileReader _create_1() => JS('FileReader', 'new FileReader()');

  @DomName('FileReader.DONE')
  @DocsEditable()
  static const int DONE = 2;

  @DomName('FileReader.EMPTY')
  @DocsEditable()
  static const int EMPTY = 0;

  @DomName('FileReader.LOADING')
  @DocsEditable()
  static const int LOADING = 1;

  @DomName('FileReader.error')
  @DocsEditable()
  final FileError error;

  @DomName('FileReader.readyState')
  @DocsEditable()
  final int readyState;

  @DomName('FileReader.abort')
  @DocsEditable()
  void abort() native;

  @DomName('FileReader.readAsArrayBuffer')
  @DocsEditable()
  void readAsArrayBuffer(Blob blob) native;

  @JSName('readAsDataURL')
  @DomName('FileReader.readAsDataURL')
  @DocsEditable()
  void readAsDataUrl(Blob blob) native;

  @DomName('FileReader.readAsText')
  @DocsEditable()
  void readAsText(Blob blob, [String encoding]) native;

  /// Stream of `abort` events handled by this [FileReader].
  @DomName('FileReader.onabort')
  @DocsEditable()
  Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);

  /// Stream of `error` events handled by this [FileReader].
  @DomName('FileReader.onerror')
  @DocsEditable()
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `load` events handled by this [FileReader].
  @DomName('FileReader.onload')
  @DocsEditable()
  Stream<ProgressEvent> get onLoad => loadEvent.forTarget(this);

  /// Stream of `loadend` events handled by this [FileReader].
  @DomName('FileReader.onloadend')
  @DocsEditable()
  Stream<ProgressEvent> get onLoadEnd => loadEndEvent.forTarget(this);

  /// Stream of `loadstart` events handled by this [FileReader].
  @DomName('FileReader.onloadstart')
  @DocsEditable()
  Stream<ProgressEvent> get onLoadStart => loadStartEvent.forTarget(this);

  /// Stream of `progress` events handled by this [FileReader].
  @DomName('FileReader.onprogress')
  @DocsEditable()
  Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);

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


@DocsEditable()
@DomName('Stream')
@Experimental() // untriaged
class FileStream extends Interceptor native "Stream" {
  // To suppress missing implicit constructor warnings.
  factory FileStream._() { throw new UnsupportedError("Not supported"); }

  @DomName('Stream.type')
  @DocsEditable()
  @Experimental() // untriaged
  final String type;
}
// 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.


@DocsEditable()
@DomName('DOMFileSystem')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://www.w3.org/TR/file-system-api/
class FileSystem extends Interceptor native "DOMFileSystem" {
  // To suppress missing implicit constructor warnings.
  factory FileSystem._() { throw new UnsupportedError("Not supported"); }

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.webkitRequestFileSystem)');

  @DomName('DOMFileSystem.name')
  @DocsEditable()
  final String name;

  @DomName('DOMFileSystem.root')
  @DocsEditable()
  final DirectoryEntry root;
}
// 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.


@DomName('FileSystemCallback')
// http://www.w3.org/TR/file-system-api/#the-filesystemcallback-interface
@Experimental()
typedef void _FileSystemCallback(FileSystem fileSystem);
// 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.


@DocsEditable()
@DomName('FileWriter')
// http://www.w3.org/TR/file-writer-api/#the-filewriter-interface
@Experimental()
class FileWriter extends EventTarget native "FileWriter" {
  // To suppress missing implicit constructor warnings.
  factory FileWriter._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `abort` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileWriter.abortEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> abortEvent = const EventStreamProvider<ProgressEvent>('abort');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileWriter.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `progress` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileWriter.progressEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> progressEvent = const EventStreamProvider<ProgressEvent>('progress');

  /**
   * Static factory designed to expose `write` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileWriter.writeEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> writeEvent = const EventStreamProvider<ProgressEvent>('write');

  /**
   * Static factory designed to expose `writeend` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileWriter.writeendEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> writeEndEvent = const EventStreamProvider<ProgressEvent>('writeend');

  /**
   * Static factory designed to expose `writestart` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileWriter.writestartEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> writeStartEvent = const EventStreamProvider<ProgressEvent>('writestart');

  @DomName('FileWriter.DONE')
  @DocsEditable()
  static const int DONE = 2;

  @DomName('FileWriter.INIT')
  @DocsEditable()
  static const int INIT = 0;

  @DomName('FileWriter.WRITING')
  @DocsEditable()
  static const int WRITING = 1;

  @DomName('FileWriter.error')
  @DocsEditable()
  final FileError error;

  @DomName('FileWriter.length')
  @DocsEditable()
  final int length;

  @DomName('FileWriter.position')
  @DocsEditable()
  final int position;

  @DomName('FileWriter.readyState')
  @DocsEditable()
  final int readyState;

  @DomName('FileWriter.abort')
  @DocsEditable()
  void abort() native;

  @DomName('FileWriter.seek')
  @DocsEditable()
  void seek(int position) native;

  @DomName('FileWriter.truncate')
  @DocsEditable()
  void truncate(int size) native;

  @DomName('FileWriter.write')
  @DocsEditable()
  void write(Blob data) native;

  /// Stream of `abort` events handled by this [FileWriter].
  @DomName('FileWriter.onabort')
  @DocsEditable()
  Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);

  /// Stream of `error` events handled by this [FileWriter].
  @DomName('FileWriter.onerror')
  @DocsEditable()
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `progress` events handled by this [FileWriter].
  @DomName('FileWriter.onprogress')
  @DocsEditable()
  Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);

  /// Stream of `write` events handled by this [FileWriter].
  @DomName('FileWriter.onwrite')
  @DocsEditable()
  Stream<ProgressEvent> get onWrite => writeEvent.forTarget(this);

  /// Stream of `writeend` events handled by this [FileWriter].
  @DomName('FileWriter.onwriteend')
  @DocsEditable()
  Stream<ProgressEvent> get onWriteEnd => writeEndEvent.forTarget(this);

  /// Stream of `writestart` events handled by this [FileWriter].
  @DomName('FileWriter.onwritestart')
  @DocsEditable()
  Stream<ProgressEvent> get onWriteStart => writeStartEvent.forTarget(this);
}
// 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.


@DomName('FileWriterCallback')
// http://www.w3.org/TR/file-writer-api/#idl-def-FileWriter
@Experimental()
typedef void _FileWriterCallback(FileWriter fileWriter);
// 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.


@DocsEditable()
@DomName('FocusEvent')
class FocusEvent extends UIEvent native "FocusEvent" {
  // To suppress missing implicit constructor warnings.
  factory FocusEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('FocusEvent.relatedTarget')
  @DocsEditable()
  EventTarget get relatedTarget => _convertNativeToDart_EventTarget(this._get_relatedTarget);
  @JSName('relatedTarget')
  @DomName('FocusEvent.relatedTarget')
  @DocsEditable()
  @Creates('Null')
  final dynamic _get_relatedTarget;
}
// 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.


@DocsEditable()
@DomName('FontFace')
@Experimental() // untriaged
class FontFace extends Interceptor native "FontFace" {
  // To suppress missing implicit constructor warnings.
  factory FontFace._() { throw new UnsupportedError("Not supported"); }

  @DomName('FontFace.FontFace')
  @DocsEditable()
  factory FontFace(String family, String source, Map descriptors) {
    return FontFace._create_1(family, source, descriptors);
  }
  static FontFace _create_1(family, source, descriptors) => JS('FontFace', 'new FontFace(#,#,#)', family, source, descriptors);

  @DomName('FontFace.family')
  @DocsEditable()
  @Experimental() // untriaged
  String family;

  @DomName('FontFace.featureSettings')
  @DocsEditable()
  @Experimental() // untriaged
  String featureSettings;

  @DomName('FontFace.status')
  @DocsEditable()
  @Experimental() // untriaged
  final String status;

  @DomName('FontFace.stretch')
  @DocsEditable()
  @Experimental() // untriaged
  String stretch;

  @DomName('FontFace.style')
  @DocsEditable()
  @Experimental() // untriaged
  String style;

  @DomName('FontFace.unicodeRange')
  @DocsEditable()
  @Experimental() // untriaged
  String unicodeRange;

  @DomName('FontFace.variant')
  @DocsEditable()
  @Experimental() // untriaged
  String variant;

  @DomName('FontFace.weight')
  @DocsEditable()
  @Experimental() // untriaged
  String weight;

  @DomName('FontFace.load')
  @DocsEditable()
  @Experimental() // untriaged
  void load() native;
}
// 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.


@DocsEditable()
@DomName('FontFaceSet')
@Experimental() // untriaged
class FontFaceSet extends EventTarget native "FontFaceSet" {
  // To suppress missing implicit constructor warnings.
  factory FontFaceSet._() { throw new UnsupportedError("Not supported"); }

  @DomName('FontFaceSet.size')
  @DocsEditable()
  @Experimental() // untriaged
  final int size;

  @DomName('FontFaceSet.status')
  @DocsEditable()
  @Experimental() // untriaged
  final String status;

  @DomName('FontFaceSet.add')
  @DocsEditable()
  @Experimental() // untriaged
  void add(FontFace fontFace) native;

  @DomName('FontFaceSet.check')
  @DocsEditable()
  @Experimental() // untriaged
  bool check(String font, String text) native;

  @DomName('FontFaceSet.clear')
  @DocsEditable()
  @Experimental() // untriaged
  void clear() native;

  @DomName('FontFaceSet.delete')
  @DocsEditable()
  @Experimental() // untriaged
  bool delete(FontFace fontFace) native;

  @DomName('FontFaceSet.forEach')
  @DocsEditable()
  @Experimental() // untriaged
  void forEach(FontFaceSetForEachCallback callback, [Object thisArg]) native;

  @DomName('FontFaceSet.has')
  @DocsEditable()
  @Experimental() // untriaged
  bool has(FontFace fontFace) native;
}
// 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.


@DomName('FontFaceSetForEachCallback')
@Experimental() // untriaged
typedef void FontFaceSetForEachCallback(FontFace fontFace, FontFace fontFaceAgain, FontFaceSet set);
// 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.


@DocsEditable()
@DomName('FormData')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
class FormData extends Interceptor native "FormData" {
  // To suppress missing implicit constructor warnings.
  factory FormData._() { throw new UnsupportedError("Not supported"); }

  @DomName('FormData.FormData')
  @DocsEditable()
  factory FormData([FormElement form]) {
    if (form != null) {
      return FormData._create_1(form);
    }
    return FormData._create_2();
  }
  static FormData _create_1(form) => JS('FormData', 'new FormData(#)', form);
  static FormData _create_2() => JS('FormData', 'new FormData()');

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.FormData)');

  @DomName('FormData.append')
  @DocsEditable()
  void append(String name, String value) native;

  @JSName('append')
  @DomName('FormData.append')
  @DocsEditable()
  void appendBlob(String name, Blob value, [String filename]) native;
}
// 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.


@DocsEditable()
@DomName('HTMLFormElement')
class FormElement extends HtmlElement native "HTMLFormElement" {
  // To suppress missing implicit constructor warnings.
  factory FormElement._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `autocomplete` events to event
   * handlers that are not necessarily instances of [FormElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLFormElement.autocompleteEvent')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#autofilling-form-controls:-the-autocomplete-attribute
  @Experimental()
  static const EventStreamProvider<Event> autocompleteEvent = const EventStreamProvider<Event>('autocomplete');

  /**
   * Static factory designed to expose `autocompleteerror` events to event
   * handlers that are not necessarily instances of [FormElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLFormElement.autocompleteerrorEvent')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#autofilling-form-controls:-the-autocomplete-attribute
  @Experimental()
  static const EventStreamProvider<AutocompleteErrorEvent> autocompleteErrorEvent = const EventStreamProvider<AutocompleteErrorEvent>('autocompleteerror');

  @DomName('HTMLFormElement.HTMLFormElement')
  @DocsEditable()
  factory FormElement() => document.createElement("form");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  FormElement.created() : super.created();

  @DomName('HTMLFormElement.acceptCharset')
  @DocsEditable()
  String acceptCharset;

  @DomName('HTMLFormElement.action')
  @DocsEditable()
  String action;

  @DomName('HTMLFormElement.autocomplete')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#autofilling-form-controls:-the-autocomplete-attribute
  @Experimental()
  String autocomplete;

  @DomName('HTMLFormElement.encoding')
  @DocsEditable()
  String encoding;

  @DomName('HTMLFormElement.enctype')
  @DocsEditable()
  String enctype;

  @DomName('HTMLFormElement.length')
  @DocsEditable()
  final int length;

  @DomName('HTMLFormElement.method')
  @DocsEditable()
  String method;

  @DomName('HTMLFormElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLFormElement.noValidate')
  @DocsEditable()
  bool noValidate;

  @DomName('HTMLFormElement.target')
  @DocsEditable()
  String target;

  @DomName('HTMLFormElement.__getter__')
  @DocsEditable()
  Element __getter__(int index) native;

  @DomName('HTMLFormElement.checkValidity')
  @DocsEditable()
  bool checkValidity() native;

  @DomName('HTMLFormElement.requestAutocomplete')
  @DocsEditable()
  // http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2012-October/037711.html
  @Experimental()
  void requestAutocomplete() native;

  @DomName('HTMLFormElement.reset')
  @DocsEditable()
  void reset() native;

  @DomName('HTMLFormElement.submit')
  @DocsEditable()
  void submit() native;

  /// Stream of `autocomplete` events handled by this [FormElement].
  @DomName('HTMLFormElement.onautocomplete')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#autofilling-form-controls:-the-autocomplete-attribute
  @Experimental()
  ElementStream<Event> get onAutocomplete => autocompleteEvent.forElement(this);

  /// Stream of `autocompleteerror` events handled by this [FormElement].
  @DomName('HTMLFormElement.onautocompleteerror')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#autofilling-form-controls:-the-autocomplete-attribute
  @Experimental()
  ElementStream<AutocompleteErrorEvent> get onAutocompleteError => autocompleteErrorEvent.forElement(this);
}
// 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.


@DocsEditable()
@DomName('Gamepad')
// https://dvcs.w3.org/hg/gamepad/raw-file/default/gamepad.html#gamepad-interface
@Experimental()
class Gamepad extends Interceptor native "Gamepad" {
  // To suppress missing implicit constructor warnings.
  factory Gamepad._() { throw new UnsupportedError("Not supported"); }

  @DomName('Gamepad.axes')
  @DocsEditable()
  final List<num> axes;

  @DomName('Gamepad.buttons')
  @DocsEditable()
  final List<num> buttons;

  @DomName('Gamepad.id')
  @DocsEditable()
  final String id;

  @DomName('Gamepad.index')
  @DocsEditable()
  final int index;

  @DomName('Gamepad.timestamp')
  @DocsEditable()
  final int timestamp;
}
// 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.


@DocsEditable()
@DomName('Geolocation')
@Unstable()
class Geolocation extends Interceptor native "Geolocation" {

  @DomName('Geolocation.getCurrentPosition')
  Future<Geoposition> getCurrentPosition({bool enableHighAccuracy,
      Duration timeout, Duration maximumAge}) {
    var options = {};
    if (enableHighAccuracy != null) {
      options['enableHighAccuracy'] = enableHighAccuracy;
    }
    if (timeout != null) {
      options['timeout'] = timeout.inMilliseconds;
    }
    if (maximumAge != null) {
      options['maximumAge'] = maximumAge.inMilliseconds;
    }
    var completer = new Completer<Geoposition>();
    try {
      _getCurrentPosition(
          (position) {
            completer.complete(_ensurePosition(position));
          },
          (error) {
            completer.completeError(error);
          },
          options);
    } catch (e, stacktrace) {
      completer.completeError(e, stacktrace);
    }
    return completer.future;
  }

  @DomName('Geolocation.watchPosition')
  Stream<Geoposition> watchPosition({bool enableHighAccuracy,
      Duration timeout, Duration maximumAge}) {

    var options = {};
    if (enableHighAccuracy != null) {
      options['enableHighAccuracy'] = enableHighAccuracy;
    }
    if (timeout != null) {
      options['timeout'] = timeout.inMilliseconds;
    }
    if (maximumAge != null) {
      options['maximumAge'] = maximumAge.inMilliseconds;
    }

    int watchId;
    var controller;
    controller = new StreamController<Geoposition>(sync: true,
      onListen: () {
        assert(watchId == null);
        watchId = _watchPosition(
            (position) {
              controller.add(_ensurePosition(position));
            },
            (error) {
              controller.addError(error);
            },
            options);
      },
      onCancel: () {
        assert(watchId != null);
        _clearWatch(watchId);
      });

    return controller.stream;
  }

  Geoposition _ensurePosition(domPosition) {
    try {
      // Firefox may throw on this.
      if (domPosition is Geoposition) {
        return domPosition;
      }
    } catch(e) {}
    return new _GeopositionWrapper(domPosition);
  }

  // To suppress missing implicit constructor warnings.
  factory Geolocation._() { throw new UnsupportedError("Not supported"); }

  @JSName('clearWatch')
  @DomName('Geolocation.clearWatch')
  @DocsEditable()
  void _clearWatch(int watchID) native;

  @JSName('getCurrentPosition')
  @DomName('Geolocation.getCurrentPosition')
  @DocsEditable()
  void _getCurrentPosition(_PositionCallback successCallback, [_PositionErrorCallback errorCallback, Object options]) native;

  @JSName('watchPosition')
  @DomName('Geolocation.watchPosition')
  @DocsEditable()
  int _watchPosition(_PositionCallback successCallback, [_PositionErrorCallback errorCallback, Object options]) native;
}

/**
 * Wrapper for Firefox- it returns an object which we cannot map correctly.
 * Basically Firefox was returning a [xpconnect wrapped nsIDOMGeoPosition] but
 * which has further oddities.
 */
class _GeopositionWrapper implements Geoposition {
  var _ptr;
  _GeopositionWrapper(this._ptr);

  Coordinates get coords => JS('Coordinates', '#.coords', _ptr);
  int get timestamp => JS('int', '#.timestamp', _ptr);
}


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


@DocsEditable()
@DomName('Geoposition')
@Unstable()
class Geoposition extends Interceptor native "Geoposition" {
  // To suppress missing implicit constructor warnings.
  factory Geoposition._() { throw new UnsupportedError("Not supported"); }

  @DomName('Geoposition.coords')
  @DocsEditable()
  final Coordinates coords;

  @DomName('Geoposition.timestamp')
  @DocsEditable()
  final int timestamp;
}
// 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.


@DocsEditable()
@DomName('GlobalEventHandlers')
@Experimental() // untriaged
abstract class GlobalEventHandlers extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory GlobalEventHandlers._() { throw new UnsupportedError("Not supported"); }

  @DomName('GlobalEventHandlers.abortEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> abortEvent = const EventStreamProvider<Event>('abort');

  @DomName('GlobalEventHandlers.blurEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> blurEvent = const EventStreamProvider<Event>('blur');

  @DomName('GlobalEventHandlers.changeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> changeEvent = const EventStreamProvider<Event>('change');

  @DomName('GlobalEventHandlers.clickEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> clickEvent = const EventStreamProvider<MouseEvent>('click');

  @DomName('GlobalEventHandlers.contextmenuEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> contextMenuEvent = const EventStreamProvider<MouseEvent>('contextmenu');

  @DomName('GlobalEventHandlers.dblclickEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> doubleClickEvent = const EventStreamProvider<Event>('dblclick');

  @DomName('GlobalEventHandlers.dragEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragEvent = const EventStreamProvider<MouseEvent>('drag');

  @DomName('GlobalEventHandlers.dragendEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragEndEvent = const EventStreamProvider<MouseEvent>('dragend');

  @DomName('GlobalEventHandlers.dragenterEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragEnterEvent = const EventStreamProvider<MouseEvent>('dragenter');

  @DomName('GlobalEventHandlers.dragleaveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragLeaveEvent = const EventStreamProvider<MouseEvent>('dragleave');

  @DomName('GlobalEventHandlers.dragoverEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragOverEvent = const EventStreamProvider<MouseEvent>('dragover');

  @DomName('GlobalEventHandlers.dragstartEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragStartEvent = const EventStreamProvider<MouseEvent>('dragstart');

  @DomName('GlobalEventHandlers.dropEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dropEvent = const EventStreamProvider<MouseEvent>('drop');

  @DomName('GlobalEventHandlers.errorEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  @DomName('GlobalEventHandlers.focusEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> focusEvent = const EventStreamProvider<Event>('focus');

  @DomName('GlobalEventHandlers.inputEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> inputEvent = const EventStreamProvider<Event>('input');

  @DomName('GlobalEventHandlers.invalidEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> invalidEvent = const EventStreamProvider<Event>('invalid');

  @DomName('GlobalEventHandlers.keydownEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<KeyboardEvent> keyDownEvent = const EventStreamProvider<KeyboardEvent>('keydown');

  @DomName('GlobalEventHandlers.keypressEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<KeyboardEvent> keyPressEvent = const EventStreamProvider<KeyboardEvent>('keypress');

  @DomName('GlobalEventHandlers.keyupEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<KeyboardEvent> keyUpEvent = const EventStreamProvider<KeyboardEvent>('keyup');

  @DomName('GlobalEventHandlers.loadEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadEvent = const EventStreamProvider<Event>('load');

  @DomName('GlobalEventHandlers.mousedownEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseDownEvent = const EventStreamProvider<MouseEvent>('mousedown');

  @DomName('GlobalEventHandlers.mouseenterEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseEnterEvent = const EventStreamProvider<MouseEvent>('mouseenter');

  @DomName('GlobalEventHandlers.mouseleaveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseLeaveEvent = const EventStreamProvider<MouseEvent>('mouseleave');

  @DomName('GlobalEventHandlers.mousemoveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseMoveEvent = const EventStreamProvider<MouseEvent>('mousemove');

  @DomName('GlobalEventHandlers.mouseoutEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseOutEvent = const EventStreamProvider<MouseEvent>('mouseout');

  @DomName('GlobalEventHandlers.mouseoverEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseOverEvent = const EventStreamProvider<MouseEvent>('mouseover');

  @DomName('GlobalEventHandlers.mouseupEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseUpEvent = const EventStreamProvider<MouseEvent>('mouseup');

  @DomName('GlobalEventHandlers.mousewheelEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<WheelEvent> mouseWheelEvent = const EventStreamProvider<WheelEvent>('mousewheel');

  @DomName('GlobalEventHandlers.resetEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> resetEvent = const EventStreamProvider<Event>('reset');

  @DomName('GlobalEventHandlers.resizeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> resizeEvent = const EventStreamProvider<Event>('resize');

  @DomName('GlobalEventHandlers.scrollEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> scrollEvent = const EventStreamProvider<Event>('scroll');

  @DomName('GlobalEventHandlers.selectEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> selectEvent = const EventStreamProvider<Event>('select');

  @DomName('GlobalEventHandlers.submitEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> submitEvent = const EventStreamProvider<Event>('submit');

  @DomName('GlobalEventHandlers.onabort')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onAbort => abortEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onblur')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onBlur => blurEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onChange => changeEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onclick')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onClick => clickEvent.forTarget(this);

  @DomName('GlobalEventHandlers.oncontextmenu')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onContextMenu => contextMenuEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondblclick')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onDoubleClick => doubleClickEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondrag')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDrag => dragEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondragend')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDragEnd => dragEndEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondragenter')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDragEnter => dragEnterEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondragleave')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDragLeave => dragLeaveEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondragover')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDragOver => dragOverEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondragstart')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDragStart => dragStartEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondrop')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDrop => dropEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onerror')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onError => errorEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onfocus')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onFocus => focusEvent.forTarget(this);

  @DomName('GlobalEventHandlers.oninput')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onInput => inputEvent.forTarget(this);

  @DomName('GlobalEventHandlers.oninvalid')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onInvalid => invalidEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onkeydown')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<KeyboardEvent> get onKeyDown => keyDownEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onkeypress')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<KeyboardEvent> get onKeyPress => keyPressEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onkeyup')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<KeyboardEvent> get onKeyUp => keyUpEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onload')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onLoad => loadEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmousedown')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseDown => mouseDownEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseEnter => mouseEnterEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseLeave => mouseLeaveEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmousemove')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseMove => mouseMoveEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmouseout')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseOut => mouseOutEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmouseover')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseOver => mouseOverEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmouseup')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseUp => mouseUpEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmousewheel')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<WheelEvent> get onMouseWheel => mouseWheelEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onreset')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onReset => resetEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onResize => resizeEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onscroll')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onScroll => scrollEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onselect')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSelect => selectEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onsubmit')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSubmit => submitEvent.forTarget(this);
}
// 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.


@DocsEditable()
/**
 * An `<hr>` tag.
 */
@DomName('HTMLHRElement')
class HRElement extends HtmlElement native "HTMLHRElement" {
  // To suppress missing implicit constructor warnings.
  factory HRElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLHRElement.HTMLHRElement')
  @DocsEditable()
  factory HRElement() => document.createElement("hr");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  HRElement.created() : super.created();

  @DomName('HTMLHRElement.color')
  @DocsEditable()
  @Experimental() // untriaged
  String color;
}
// 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.

// WARNING: Do not edit - generated code.

@DomName('HashChangeEvent')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
class HashChangeEvent extends Event native "HashChangeEvent" {
  factory HashChangeEvent(String type,
      {bool canBubble: true, bool cancelable: true, String oldUrl,
      String newUrl}) {
    var event = document._createEvent("HashChangeEvent");
    event._initHashChangeEvent(type, canBubble, cancelable, oldUrl, newUrl);
    return event;
  }
  // To suppress missing implicit constructor warnings.
  factory HashChangeEvent._() { throw new UnsupportedError("Not supported"); }

  /// Checks if this type is supported on the current platform.
  static bool get supported => Device.isEventTypeSupported('HashChangeEvent');

  @JSName('newURL')
  @DomName('HashChangeEvent.newURL')
  @DocsEditable()
  final String newUrl;

  @JSName('oldURL')
  @DomName('HashChangeEvent.oldURL')
  @DocsEditable()
  final String oldUrl;

  @JSName('initHashChangeEvent')
  @DomName('HashChangeEvent.initHashChangeEvent')
  @DocsEditable()
  void _initHashChangeEvent(String type, bool canBubble, bool cancelable, String oldURL, String newURL) native;

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


@DocsEditable()
@DomName('HTMLHeadElement')
class HeadElement extends HtmlElement native "HTMLHeadElement" {
  // To suppress missing implicit constructor warnings.
  factory HeadElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLHeadElement.HTMLHeadElement')
  @DocsEditable()
  factory HeadElement() => document.createElement("head");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  HeadElement.created() : super.created();
}
// 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.


@DocsEditable()
@DomName('HTMLHeadingElement')
class HeadingElement extends HtmlElement native "HTMLHeadingElement" {
  // To suppress missing implicit constructor warnings.
  factory HeadingElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h1() => document.createElement("h1");

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h2() => document.createElement("h2");

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h3() => document.createElement("h3");

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h4() => document.createElement("h4");

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h5() => document.createElement("h5");

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h6() => document.createElement("h6");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  HeadingElement.created() : super.created();
}
// 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.


@DomName('History')
class History extends Interceptor implements HistoryBase native "History" {

  /**
   * Checks if the State APIs are supported on the current platform.
   *
   * See also:
   *
   * * [pushState]
   * * [replaceState]
   * * [state]
   */
  static bool get supportsState => JS('bool', '!!window.history.pushState');
  // To suppress missing implicit constructor warnings.
  factory History._() { throw new UnsupportedError("Not supported"); }

  @DomName('History.length')
  @DocsEditable()
  final int length;

  @DomName('History.state')
  @DocsEditable()
  dynamic get state => convertNativeToDart_SerializedScriptValue(this._get_state);
  @JSName('state')
  @DomName('History.state')
  @DocsEditable()
  @annotation_Creates_SerializedScriptValue
  @annotation_Returns_SerializedScriptValue
  final dynamic _get_state;

  @DomName('History.back')
  @DocsEditable()
  void back() native;

  @DomName('History.forward')
  @DocsEditable()
  void forward() native;

  @DomName('History.go')
  @DocsEditable()
  void go(int distance) native;

  @DomName('History.pushState')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void pushState(Object data, String title, [String url]) native;

  @DomName('History.replaceState')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void replaceState(Object data, String title, [String url]) native;
}
// 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.


@DocsEditable()
@DomName('HTMLCollection')
class HtmlCollection extends Interceptor with ListMixin<Node>, ImmutableListMixin<Node> implements JavaScriptIndexingBehavior, List<Node> native "HTMLCollection" {
  // To suppress missing implicit constructor warnings.
  factory HtmlCollection._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLCollection.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  Node operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("Node", "#[#]", this, index);
  }
  void operator[]=(int index, Node value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Node> mixins.
  // Node is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Node get first {
    if (this.length > 0) {
      return JS('Node', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Node get last {
    int len = this.length;
    if (len > 0) {
      return JS('Node', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Node get single {
    int len = this.length;
    if (len == 1) {
      return JS('Node', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Node elementAt(int index) => this[index];
  // -- end List<Node> mixins.

  @DomName('HTMLCollection.item')
  @DocsEditable()
  Element item(int index) native;

  @DomName('HTMLCollection.namedItem')
  @DocsEditable()
  Element namedItem(String name) native;
}
// 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.


@DomName('HTMLDocument')
class HtmlDocument extends Document native "HTMLDocument" {
  // To suppress missing implicit constructor warnings.
  factory HtmlDocument._() { throw new UnsupportedError("Not supported"); }


  @DomName('Document.body')
  BodyElement body;

  @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]
   */
  static bool get supportsCssCanvasContext =>
      JS('bool', '!!(document.getCSSCanvasContext)');


  /**
   * 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;
  void set selectedStylesheetSet(String value) {
    _selectedStylesheetSet = value;
  }

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

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

  @DomName('Document.title')
  void 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();
  }

  @DomName('Document.webkitExitPointerLock')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  void exitPointerLock() {
    _webkitExitPointerLock();
  }

  /**
   * 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.webkitPointerLockElement')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  Element get pointerLockElement =>
      _webkitPointerLockElement;

  @DomName('Document.visibilityState')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @Experimental()
  String get visibilityState => JS('String',
    '(#.visibilityState || #.mozVisibilityState || #.msVisibilityState ||'
      '#.webkitVisibilityState)', this, this, this, this);

  @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}) {
    _registerCustomElement(JS('', 'window'), this, tag, customElementClass,
        extendsTag);
  }

  /** *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 (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';
  }

  @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}) {
    return new _JSElementUpgrader(this, type, extendsTag);
  }
}
// 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.


@DocsEditable()
@DomName('HTMLFormControlsCollection')
class HtmlFormControlsCollection extends HtmlCollection native "HTMLFormControlsCollection" {
  // To suppress missing implicit constructor warnings.
  factory HtmlFormControlsCollection._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('HTMLHtmlElement')
class HtmlHtmlElement extends HtmlElement native "HTMLHtmlElement" {
  // To suppress missing implicit constructor warnings.
  factory HtmlHtmlElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLHtmlElement.HTMLHtmlElement')
  @DocsEditable()
  factory HtmlHtmlElement() => document.createElement("html");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  HtmlHtmlElement.created() : super.created();
}
// 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.


@DocsEditable()
@DomName('HTMLOptionsCollection')
class HtmlOptionsCollection extends HtmlCollection native "HTMLOptionsCollection" {
  // To suppress missing implicit constructor warnings.
  factory HtmlOptionsCollection._() { throw new UnsupportedError("Not supported"); }
}
// 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.


 /**
  * A client-side XHR request for getting data from a URL,
  * formally known as XMLHttpRequest.
  *
  * HttpRequest can be used to obtain data from HTTP and FTP protocols,
  * and is useful for AJAX-style page updates.
  *
  * The simplest way to get the contents of a text file, such as a
  * JSON-formatted file, is with [getString].
  * For example, the following code gets the contents of a JSON file
  * and prints its length:
  *
  *     var path = 'myData.json';
  *     HttpRequest.getString(path)
  *         .then((String fileContents) {
  *           print(fileContents.length);
  *         })
  *         .catchError((Error error) {
  *           print(error.toString());
  *         });
  *
  * ## Fetching data from other servers
  *
  * For security reasons, browsers impose restrictions on requests
  * made by embedded apps.
  * With the default behavior of this class,
  * the code making the request must be served from the same origin
  * (domain name, port, and application layer protocol)
  * as the requested resource.
  * In the example above, the myData.json file must be co-located with the
  * app that uses it.
  * You might be able to
  * [get around this restriction](http://www.dartlang.org/articles/json-web-service/#a-note-on-cors-and-httprequest)
  * by using CORS headers or JSONP.
  *
  * ## Other resources
  *
  * * [Fetch Data Dynamically](https://www.dartlang.org/docs/tutorials/fetchdata/),
  * a tutorial from _A Game of Darts_,
  * shows two different ways to use HttpRequest to get a JSON file.
  * * [Get Input from a Form](https://www.dartlang.org/docs/tutorials/forms/),
  * another tutorial from _A Game of Darts_,
  * shows using HttpRequest with a custom server.
  * * [Dart article on using HttpRequests](http://www.dartlang.org/articles/json-web-service/#getting-data)
  * * [JS XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest)
  * * [Using XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest)
 */
@DomName('XMLHttpRequest')
class HttpRequest extends HttpRequestEventTarget native "XMLHttpRequest" {

  /**
   * Creates a GET request for the specified [url].
   *
   * The server response must be a `text/` mime type for this request to
   * succeed.
   *
   * This is similar to [request] but specialized for HTTP GET requests which
   * return text content.
   *
   * To add query parameters, append them to the [url] following a `?`,
   * joining each key to its value with `=` and separating key-value pairs with
   * `&`.
   *
   *     var name = Uri.encodeQueryComponent('John');
   *     var id = Uri.encodeQueryComponent('42');
   *     HttpRequest.getString('users.json?name=$name&id=$id')
   *       .then((HttpRequest resp) {
   *         // Do something with the response.
   *     });
   *
   * See also:
   *
   * * [request]
   */
  static Future<String> getString(String url,
      {bool withCredentials, void onProgress(ProgressEvent e)}) {
    return request(url, withCredentials: withCredentials,
        onProgress: onProgress).then((xhr) => xhr.responseText);
  }

  /**
   * Makes a server POST request with the specified data encoded as form data.
   *
   * This is roughly the POST equivalent of getString. This method is similar
   * to sending a FormData object with broader browser support but limited to
   * String values.
   *
   * If [data] is supplied, the key/value pairs are URI encoded with
   * [Uri.encodeQueryComponent] and converted into an HTTP query string.
   *
   * Unless otherwise specified, this method appends the following header:
   *
   *     Content-Type: application/x-www-form-urlencoded; charset=UTF-8
   *
   * Here's an example of using this method:
   *
   *     var data = { 'firstName' : 'John', 'lastName' : 'Doe' };
   *     HttpRequest.postFormData('/send', data).then((HttpRequest resp) {
   *       // Do something with the response.
   *     });
   *
   * See also:
   *
   * * [request]
   */
  static Future<HttpRequest> postFormData(String url, Map<String, String> data,
      {bool withCredentials, String responseType,
      Map<String, String> requestHeaders,
      void onProgress(ProgressEvent e)}) {

    var parts = [];
    data.forEach((key, value) {
      parts.add('${Uri.encodeQueryComponent(key)}='
          '${Uri.encodeQueryComponent(value)}');
    });
    var formData = parts.join('&');

    if (requestHeaders == null) {
      requestHeaders = <String, String>{};
    }
    requestHeaders.putIfAbsent('Content-Type',
        () => 'application/x-www-form-urlencoded; charset=UTF-8');

    return request(url, method: 'POST', withCredentials: withCredentials,
        responseType: responseType,
        requestHeaders: requestHeaders, sendData: formData,
        onProgress: onProgress);
  }

  /**
   * Creates and sends a URL request for the specified [url].
   *
   * By default `request` will perform an HTTP GET request, but a different
   * method (`POST`, `PUT`, `DELETE`, etc) can be used by specifying the
   * [method] parameter.
   *
   * The Future is completed when the response is available.
   *
   * If specified, `sendData` will send data in the form of a [ByteBuffer],
   * [Blob], [Document], [String], or [FormData] along with the HttpRequest.
   *
   * The [withCredentials] parameter specified that credentials such as a cookie
   * (already) set in the header or
   * [authorization headers](http://tools.ietf.org/html/rfc1945#section-10.2)
   * should be specified for the request. Details to keep in mind when using
   * credentials:
   *
   * * Using credentials is only useful for cross-origin requests.
   * * The `Access-Control-Allow-Origin` header of `url` cannot contain a wildcard (*).
   * * The `Access-Control-Allow-Credentials` header of `url` must be set to true.
   * * If `Access-Control-Expose-Headers` has not been set to true, only a subset of all the response headers will be returned when calling [getAllRequestHeaders].
   *
   * The following is equivalent to the [getString] sample above:
   *
   *     var name = Uri.encodeQueryComponent('John');
   *     var id = Uri.encodeQueryComponent('42');
   *     HttpRequest.request('users.json?name=$name&id=$id')
   *       .then((HttpRequest resp) {
   *         // Do something with the response.
   *     });
   *
   * Here's an example of submitting an entire form with [FormData].
   *
   *     var myForm = querySelector('form#myForm');
   *     var data = new FormData(myForm);
   *     HttpRequest.request('/submit', method: 'POST', sendData: data)
   *       .then((HttpRequest resp) {
   *         // Do something with the response.
   *     });
   *
   * Note that requests for file:// URIs are only supported by Chrome extensions
   * with appropriate permissions in their manifest. Requests to file:// URIs
   * will also never fail- the Future will always complete successfully, even
   * when the file cannot be found.
   *
   * See also: [authorization headers](http://en.wikipedia.org/wiki/Basic_access_authentication).
   */
  static Future<HttpRequest> request(String url,
      {String method, bool withCredentials, String responseType,
      String mimeType, Map<String, String> requestHeaders, sendData,
      void onProgress(ProgressEvent e)}) {
    var completer = new Completer<HttpRequest>();

    var xhr = new HttpRequest();
    if (method == null) {
      method = 'GET';
    }
    xhr.open(method, url, async: true);

    if (withCredentials != null) {
      xhr.withCredentials = withCredentials;
    }

    if (responseType != null) {
      xhr.responseType = responseType;
    }

    if (mimeType != null) {
      xhr.overrideMimeType(mimeType);
    }

    if (requestHeaders != null) {
      requestHeaders.forEach((header, value) {
        xhr.setRequestHeader(header, value);
      });
    }

    if (onProgress != null) {
      xhr.onProgress.listen(onProgress);
    }

    xhr.onLoad.listen((e) {
      // Note: file:// URIs have status of 0.
      if ((xhr.status >= 200 && xhr.status < 300) ||
          xhr.status == 0 || xhr.status == 304) {
        completer.complete(xhr);
      } else {
        completer.completeError(e);
      }
    });

    xhr.onError.listen(completer.completeError);

    if (sendData != null) {
      xhr.send(sendData);
    } else {
      xhr.send();
    }

    return completer.future;
  }

  /**
   * Checks to see if the Progress event is supported on the current platform.
   */
  static bool get supportsProgressEvent {
    var xhr = new HttpRequest();
    return JS('bool', '("onprogress" in #)', xhr);
  }

  /**
   * Checks to see if the current platform supports making cross origin
   * requests.
   *
   * Note that even if cross origin requests are supported, they still may fail
   * if the destination server does not support CORS requests.
   */
  static bool get supportsCrossOrigin {
    var xhr = new HttpRequest();
    return JS('bool', '("withCredentials" in #)', xhr);
  }

  /**
   * Checks to see if the LoadEnd event is supported on the current platform.
   */
  static bool get supportsLoadEndEvent {
    var xhr = new HttpRequest();
    return JS('bool', '("onloadend" in #)', xhr);
  }

  /**
   * Checks to see if the overrideMimeType method is supported on the current
   * platform.
   */
  static bool get supportsOverrideMimeType {
    var xhr = new HttpRequest();
    return JS('bool', '("overrideMimeType" in #)', xhr);
  }

  /**
   * Makes a cross-origin request to the specified URL.
   *
   * This API provides a subset of [request] which works on IE9. If IE9
   * cross-origin support is not required then [request] should be used instead.
   */
  @Experimental()
  static Future<String> requestCrossOrigin(String url,
      {String method, String sendData}) {
    if (supportsCrossOrigin) {
      return request(url, method: method, sendData: sendData).then((xhr) {
        return xhr.responseText;
      });
    }
    var completer = new Completer<String>();
    if (method == null) {
      method = 'GET';
    }
    var xhr = JS('var', 'new XDomainRequest()');
    JS('', '#.open(#, #)', xhr, method, url);
    JS('', '#.onload = #', xhr, convertDartClosureToJS((e) {
      var response = JS('String', '#.responseText', xhr);
      completer.complete(response);
    }, 1));
    JS('', '#.onerror = #', xhr, convertDartClosureToJS((e) {
      completer.completeError(e);
    }, 1));

    // IE9 RTM - XDomainRequest issued requests may abort if all event handlers
    // not specified
    // http://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified
    JS('', '#.onprogress = {}', xhr);
    JS('', '#.ontimeout = {}', xhr);
    JS('', '#.timeout = Number.MAX_VALUE', xhr);

    if (sendData != null) {
      JS('', '#.send(#)', xhr, sendData);
    } else {
      JS('', '#.send()', xhr);
    }

    return completer.future;
  }

  /**
   * Returns all response headers as a key-value map.
   *
   * Multiple values for the same header key can be combined into one,
   * separated by a comma and a space.
   *
   * See: http://www.w3.org/TR/XMLHttpRequest/#the-getresponseheader()-method
   */
  Map<String, String> get responseHeaders {
    // from Closure's goog.net.Xhrio.getResponseHeaders.
    var headers = <String, String>{};
    var headersString = this.getAllResponseHeaders();
    if (headersString == null) {
      return headers;
    }
    var headersList = headersString.split('\r\n');
    for (var header in headersList) {
      if (header.isEmpty) {
        continue;
      }

      var splitIdx = header.indexOf(': ');
      if (splitIdx == -1) {
        continue;
      }
      var key = header.substring(0, splitIdx).toLowerCase();
      var value = header.substring(splitIdx + 2);
      if (headers.containsKey(key)) {
        headers[key] = '${headers[key]}, $value';
      } else {
        headers[key] = value;
      }
    }
    return headers;
  }

  // To suppress missing implicit constructor warnings.
  factory HttpRequest._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `readystatechange` events to event
   * handlers that are not necessarily instances of [HttpRequest].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequest.readystatechangeEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> readyStateChangeEvent = const EventStreamProvider<ProgressEvent>('readystatechange');

  /**
   * General constructor for any type of request (GET, POST, etc).
   *
   * This call is used in conjunction with [open]:
   *
   *     var request = new HttpRequest();
   *     request.open('GET', 'http://dartlang.org');
   *     request.onLoad.listen((event) => print(
   *         'Request complete ${event.target.reponseText}'));
   *     request.send();
   *
   * is the (more verbose) equivalent of
   *
   *     HttpRequest.getString('http://dartlang.org').then(
   *         (result) => print('Request complete: $result'));
   */
  @DomName('XMLHttpRequest.XMLHttpRequest')
  @DocsEditable()
  factory HttpRequest() {
    return HttpRequest._create_1();
  }
  static HttpRequest _create_1() => JS('HttpRequest', 'new XMLHttpRequest()');

  @DomName('XMLHttpRequest.DONE')
  @DocsEditable()
  static const int DONE = 4;

  @DomName('XMLHttpRequest.HEADERS_RECEIVED')
  @DocsEditable()
  static const int HEADERS_RECEIVED = 2;

  @DomName('XMLHttpRequest.LOADING')
  @DocsEditable()
  static const int LOADING = 3;

  @DomName('XMLHttpRequest.OPENED')
  @DocsEditable()
  static const int OPENED = 1;

  @DomName('XMLHttpRequest.UNSENT')
  @DocsEditable()
  static const int UNSENT = 0;

  /**
   * Indicator of the current state of the request:
   *
   * <table>
   *   <tr>
   *     <td>Value</td>
   *     <td>State</td>
   *     <td>Meaning</td>
   *   </tr>
   *   <tr>
   *     <td>0</td>
   *     <td>unsent</td>
   *     <td><code>open()</code> has not yet been called</td>
   *   </tr>
   *   <tr>
   *     <td>1</td>
   *     <td>opened</td>
   *     <td><code>send()</code> has not yet been called</td>
   *   </tr>
   *   <tr>
   *     <td>2</td>
   *     <td>headers received</td>
   *     <td><code>sent()</code> has been called; response headers and <code>status</code> are available</td>
   *   </tr>
   *   <tr>
   *     <td>3</td> <td>loading</td> <td><code>responseText</code> holds some data</td>
   *   </tr>
   *   <tr>
   *     <td>4</td> <td>done</td> <td>request is complete</td>
   *   </tr>
   * </table>
   */
  @DomName('XMLHttpRequest.readyState')
  @DocsEditable()
  final int readyState;

  /**
   * The data received as a reponse from the request.
   *
   * The data could be in the
   * form of a [String], [ByteBuffer], [Document], [Blob], or json (also a
   * [String]). `null` indicates request failure.
   */
  @DomName('XMLHttpRequest.response')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  dynamic get response => _convertNativeToDart_XHR_Response(this._get_response);
  @JSName('response')
  /**
   * The data received as a reponse from the request.
   *
   * The data could be in the
   * form of a [String], [ByteBuffer], [Document], [Blob], or json (also a
   * [String]). `null` indicates request failure.
   */
  @DomName('XMLHttpRequest.response')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Creates('NativeByteBuffer|Blob|Document|=Object|JSExtendableArray|String|num')
  final dynamic _get_response;

  /**
   * The response in String form or empty String on failure.
   */
  @DomName('XMLHttpRequest.responseText')
  @DocsEditable()
  final String responseText;

  /**
   * [String] telling the server the desired response format.
   *
   * Default is `String`.
   * Other options are one of 'arraybuffer', 'blob', 'document', 'json',
   * 'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if
   * `responseType` is set while performing a synchronous request.
   *
   * See also: [MDN responseType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType)
   */
  @DomName('XMLHttpRequest.responseType')
  @DocsEditable()
  String responseType;

  @JSName('responseXML')
  /**
   * The request response, or null on failure.
   *
   * The response is processed as
   * `text/xml` stream, unless responseType = 'document' and the request is
   * synchronous.
   */
  @DomName('XMLHttpRequest.responseXML')
  @DocsEditable()
  final Document responseXml;

  /**
   * The http result code from the request (200, 404, etc).
   * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
   */
  @DomName('XMLHttpRequest.status')
  @DocsEditable()
  final int status;

  /**
   * The request response string (such as \"200 OK\").
   * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
   */
  @DomName('XMLHttpRequest.statusText')
  @DocsEditable()
  final String statusText;

  /**
   * Length of time before a request is automatically terminated.
   *
   * When the time has passed, a [TimeoutEvent] is dispatched.
   *
   * If [timeout] is set to 0, then the request will not time out.
   *
   * ## Other resources
   *
   * * [XMLHttpRequest.timeout]
   * (https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#timeout)
   * from MDN.
   * * [The timeout attribute]
   * (http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute)
   * from W3C.
   */
  @DomName('XMLHttpRequest.timeout')
  @DocsEditable()
  @Experimental() // untriaged
  int timeout;

  /**
   * [EventTarget] that can hold listeners to track the progress of the request.
   * The events fired will be members of [HttpRequestUploadEvents].
   */
  @DomName('XMLHttpRequest.upload')
  @DocsEditable()
  @Unstable()
  final HttpRequestUpload upload;

  /**
   * True if cross-site requests should use credentials such as cookies
   * or authorization headers; false otherwise.
   *
   * This value is ignored for same-site requests.
   */
  @DomName('XMLHttpRequest.withCredentials')
  @DocsEditable()
  bool withCredentials;

  /**
   * Stop the current request.
   *
   * The request can only be stopped if readyState is `HEADERS_RECIEVED` or
   * `LOADING`. If this method is not in the process of being sent, the method
   * has no effect.
   */
  @DomName('XMLHttpRequest.abort')
  @DocsEditable()
  void abort() native;

  /**
   * Retrieve all the response headers from a request.
   *
   * `null` if no headers have been received. For multipart requests,
   * `getAllResponseHeaders` will return the response headers for the current
   * part of the request.
   *
   * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)
   * for a list of common response headers.
   */
  @DomName('XMLHttpRequest.getAllResponseHeaders')
  @DocsEditable()
  @Unstable()
  String getAllResponseHeaders() native;

  /**
   * Return the response header named `header`, or null if not found.
   *
   * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)
   * for a list of common response headers.
   */
  @DomName('XMLHttpRequest.getResponseHeader')
  @DocsEditable()
  @Unstable()
  String getResponseHeader(String header) native;

  /**
   * Specify the desired `url`, and `method` to use in making the request.
   *
   * By default the request is done asyncronously, with no user or password
   * authentication information. If `async` is false, the request will be send
   * synchronously.
   *
   * Calling `open` again on a currently active request is equivalent to
   * calling `abort`.
   *
   * Note: Most simple HTTP requests can be accomplished using the [getString],
   * [request], [requestCrossOrigin], or [postFormData] methods. Use of this
   * `open` method is intended only for more complext HTTP requests where
   * finer-grained control is needed.
   */
  @DomName('XMLHttpRequest.open')
  @DocsEditable()
  void open(String method, String url, {bool async, String user, String password}) native;

  /**
   * Specify a particular MIME type (such as `text/xml`) desired for the
   * response.
   *
   * This value must be set before the request has been sent. See also the list
   * of [common MIME types](http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types)
   */
  @DomName('XMLHttpRequest.overrideMimeType')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void overrideMimeType(String override) native;

  /**
   * Send the request with any given `data`.
   *
   * Note: Most simple HTTP requests can be accomplished using the [getString],
   * [request], [requestCrossOrigin], or [postFormData] methods. Use of this
   * `send` method is intended only for more complext HTTP requests where
   * finer-grained control is needed.
   *
   * ## Other resources
   *
   * * [XMLHttpRequest.send]
   * (https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
   * from MDN.
   */
  @DomName('XMLHttpRequest.send')
  @DocsEditable()
  void send([data]) native;

  /**
   * Sets the value of an HTTP requst header.
   *
   * This method should be called after the request is opened, but before
   * the request is sent.
   *
   * Multiple calls with the same header will combine all their values into a
   * single header.
   *
   * ## Other resources
   *
   * * [XMLHttpRequest.setRequestHeader]
   * (https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
   * from MDN.
   * * [The setRequestHeader() method]
   * (http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method) from
   * W3C.
   */
  @DomName('XMLHttpRequest.setRequestHeader')
  @DocsEditable()
  void setRequestHeader(String header, String value) native;

  /// Stream of `readystatechange` events handled by this [HttpRequest].
/**
   * Event listeners to be notified every time the [HttpRequest]
   * object's `readyState` changes values.
   */
  @DomName('XMLHttpRequest.onreadystatechange')
  @DocsEditable()
  Stream<ProgressEvent> get onReadyStateChange => readyStateChangeEvent.forTarget(this);

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


@DocsEditable()
@DomName('XMLHttpRequestEventTarget')
@Experimental() // untriaged
class HttpRequestEventTarget extends EventTarget native "XMLHttpRequestEventTarget" {
  // To suppress missing implicit constructor warnings.
  factory HttpRequestEventTarget._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `abort` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequestEventTarget.abortEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<ProgressEvent> abortEvent = const EventStreamProvider<ProgressEvent>('abort');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequestEventTarget.errorEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<ProgressEvent> errorEvent = const EventStreamProvider<ProgressEvent>('error');

  /**
   * Static factory designed to expose `load` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequestEventTarget.loadEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<ProgressEvent> loadEvent = const EventStreamProvider<ProgressEvent>('load');

  /**
   * Static factory designed to expose `loadend` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequestEventTarget.loadendEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<ProgressEvent> loadEndEvent = const EventStreamProvider<ProgressEvent>('loadend');

  /**
   * Static factory designed to expose `loadstart` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequestEventTarget.loadstartEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<ProgressEvent> loadStartEvent = const EventStreamProvider<ProgressEvent>('loadstart');

  /**
   * Static factory designed to expose `progress` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequestEventTarget.progressEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<ProgressEvent> progressEvent = const EventStreamProvider<ProgressEvent>('progress');

  /**
   * Static factory designed to expose `timeout` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequestEventTarget.timeoutEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<ProgressEvent> timeoutEvent = const EventStreamProvider<ProgressEvent>('timeout');

  /// Stream of `abort` events handled by this [HttpRequestEventTarget].
  @DomName('XMLHttpRequestEventTarget.onabort')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);

  /// Stream of `error` events handled by this [HttpRequestEventTarget].
  @DomName('XMLHttpRequestEventTarget.onerror')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<ProgressEvent> get onError => errorEvent.forTarget(this);

  /// Stream of `load` events handled by this [HttpRequestEventTarget].
  @DomName('XMLHttpRequestEventTarget.onload')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<ProgressEvent> get onLoad => loadEvent.forTarget(this);

  /// Stream of `loadend` events handled by this [HttpRequestEventTarget].
  @DomName('XMLHttpRequestEventTarget.onloadend')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental() // untriaged
  Stream<ProgressEvent> get onLoadEnd => loadEndEvent.forTarget(this);

  /// Stream of `loadstart` events handled by this [HttpRequestEventTarget].
  @DomName('XMLHttpRequestEventTarget.onloadstart')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<ProgressEvent> get onLoadStart => loadStartEvent.forTarget(this);

  /// Stream of `progress` events handled by this [HttpRequestEventTarget].
  @DomName('XMLHttpRequestEventTarget.onprogress')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental() // untriaged
  Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);

  /// Stream of `timeout` events handled by this [HttpRequestEventTarget].
  @DomName('XMLHttpRequestEventTarget.ontimeout')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<ProgressEvent> get onTimeout => timeoutEvent.forTarget(this);
}
// 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.


@DocsEditable()
@DomName('XMLHttpRequestUpload')
// http://xhr.spec.whatwg.org/#xmlhttprequestupload
@Experimental()
class HttpRequestUpload extends HttpRequestEventTarget native "XMLHttpRequestUpload" {
  // To suppress missing implicit constructor warnings.
  factory HttpRequestUpload._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('HTMLIFrameElement')
class IFrameElement extends HtmlElement native "HTMLIFrameElement" {
  // To suppress missing implicit constructor warnings.
  factory IFrameElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLIFrameElement.HTMLIFrameElement')
  @DocsEditable()
  factory IFrameElement() => document.createElement("iframe");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  IFrameElement.created() : super.created();

  @DomName('HTMLIFrameElement.contentWindow')
  @DocsEditable()
  WindowBase get contentWindow => _convertNativeToDart_Window(this._get_contentWindow);
  @JSName('contentWindow')
  @DomName('HTMLIFrameElement.contentWindow')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_contentWindow;

  @DomName('HTMLIFrameElement.height')
  @DocsEditable()
  String height;

  @DomName('HTMLIFrameElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLIFrameElement.sandbox')
  @DocsEditable()
  String sandbox;

  @DomName('HTMLIFrameElement.src')
  @DocsEditable()
  String src;

  @DomName('HTMLIFrameElement.srcdoc')
  @DocsEditable()
  String srcdoc;

  @DomName('HTMLIFrameElement.width')
  @DocsEditable()
  String width;
}
// 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.


@DocsEditable()
@DomName('ImageBitmap')
@Experimental() // untriaged
class ImageBitmap extends Interceptor native "ImageBitmap" {
  // To suppress missing implicit constructor warnings.
  factory ImageBitmap._() { throw new UnsupportedError("Not supported"); }

  @DomName('ImageBitmap.height')
  @DocsEditable()
  @Experimental() // untriaged
  final int height;

  @DomName('ImageBitmap.width')
  @DocsEditable()
  @Experimental() // untriaged
  final int width;
}
// 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.

@DomName('ImageData')
class ImageData extends Interceptor native "ImageData" {

  // To suppress missing implicit constructor warnings.
  factory ImageData._() { throw new UnsupportedError("Not supported"); }

  @DomName('ImageData.data')
  @DocsEditable()
  @Creates('NativeUint8ClampedList')
  @Returns('NativeUint8ClampedList')
  final List<int> data;

  @DomName('ImageData.height')
  @DocsEditable()
  final int height;

  @DomName('ImageData.width')
  @DocsEditable()
  final int width;

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


@DomName('HTMLImageElement')
class ImageElement extends HtmlElement implements CanvasImageSource native "HTMLImageElement" {
  // To suppress missing implicit constructor warnings.
  factory ImageElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLImageElement.HTMLImageElement')
  @DocsEditable()
  factory ImageElement({String src, int width, int height}) {
    var e = document.createElement("img");
    if (src != null) e.src = src;
    if (width != null) e.width = width;
    if (height != null) e.height = height;
    return e;
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ImageElement.created() : super.created();

  @DomName('HTMLImageElement.alt')
  @DocsEditable()
  String alt;

  @DomName('HTMLImageElement.complete')
  @DocsEditable()
  final bool complete;

  @DomName('HTMLImageElement.crossOrigin')
  @DocsEditable()
  String crossOrigin;

  @DomName('HTMLImageElement.height')
  @DocsEditable()
  int height;

  @DomName('HTMLImageElement.isMap')
  @DocsEditable()
  bool isMap;

  @DomName('HTMLImageElement.naturalHeight')
  @DocsEditable()
  final int naturalHeight;

  @DomName('HTMLImageElement.naturalWidth')
  @DocsEditable()
  final int naturalWidth;

  @DomName('HTMLImageElement.src')
  @DocsEditable()
  String src;

  @DomName('HTMLImageElement.srcset')
  @DocsEditable()
  @Experimental() // untriaged
  String srcset;

  @DomName('HTMLImageElement.useMap')
  @DocsEditable()
  String useMap;

  @DomName('HTMLImageElement.width')
  @DocsEditable()
  int width;

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


@DomName('HTMLInputElement')
class InputElement extends HtmlElement implements
    HiddenInputElement,
    SearchInputElement,
    TextInputElement,
    UrlInputElement,
    TelephoneInputElement,
    EmailInputElement,
    PasswordInputElement,
    DateInputElement,
    MonthInputElement,
    WeekInputElement,
    TimeInputElement,
    LocalDateTimeInputElement,
    NumberInputElement,
    RangeInputElement,
    CheckboxInputElement,
    RadioButtonInputElement,
    FileUploadInputElement,
    SubmitButtonInputElement,
    ImageButtonInputElement,
    ResetButtonInputElement,
    ButtonInputElement
     native "HTMLInputElement" {

  factory InputElement({String type}) {
    var e = document.createElement("input");
    if (type != null) {
      try {
        // IE throws an exception for unknown types.
        e.type = type;
      } catch(_) {}
    }
    return e;
  }

  // To suppress missing implicit constructor warnings.
  factory InputElement._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `speechchange` events to event
   * handlers that are not necessarily instances of [InputElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLInputElement.webkitSpeechChangeEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://lists.w3.org/Archives/Public/public-xg-htmlspeech/2011Feb/att-0020/api-draft.html#extending_html_elements
  static const EventStreamProvider<Event> speechChangeEvent = const EventStreamProvider<Event>('webkitSpeechChange');
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  InputElement.created() : super.created();

  @DomName('HTMLInputElement.accept')
  @DocsEditable()
  String accept;

  @DomName('HTMLInputElement.alt')
  @DocsEditable()
  String alt;

  @DomName('HTMLInputElement.autocomplete')
  @DocsEditable()
  String autocomplete;

  @DomName('HTMLInputElement.autofocus')
  @DocsEditable()
  bool autofocus;

  @DomName('HTMLInputElement.checked')
  @DocsEditable()
  bool checked;

  @DomName('HTMLInputElement.defaultChecked')
  @DocsEditable()
  bool defaultChecked;

  @DomName('HTMLInputElement.defaultValue')
  @DocsEditable()
  String defaultValue;

  @DomName('HTMLInputElement.dirName')
  @DocsEditable()
  String dirName;

  @DomName('HTMLInputElement.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('HTMLInputElement.files')
  @DocsEditable()
  @Returns('FileList')
  @Creates('FileList')
  List<File> files;

  @DomName('HTMLInputElement.form')
  @DocsEditable()
  final FormElement form;

  @DomName('HTMLInputElement.formAction')
  @DocsEditable()
  String formAction;

  @DomName('HTMLInputElement.formEnctype')
  @DocsEditable()
  String formEnctype;

  @DomName('HTMLInputElement.formMethod')
  @DocsEditable()
  String formMethod;

  @DomName('HTMLInputElement.formNoValidate')
  @DocsEditable()
  bool formNoValidate;

  @DomName('HTMLInputElement.formTarget')
  @DocsEditable()
  String formTarget;

  @DomName('HTMLInputElement.height')
  @DocsEditable()
  int height;

  @DomName('HTMLInputElement.incremental')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  bool incremental;

  @DomName('HTMLInputElement.indeterminate')
  @DocsEditable()
  bool indeterminate;

  @DomName('HTMLInputElement.inputMode')
  @DocsEditable()
  @Experimental() // untriaged
  String inputMode;

  @DomName('HTMLInputElement.labels')
  @DocsEditable()
  @Returns('NodeList')
  @Creates('NodeList')
  final List<Node> labels;

  @DomName('HTMLInputElement.list')
  @DocsEditable()
  final HtmlElement list;

  @DomName('HTMLInputElement.max')
  @DocsEditable()
  String max;

  @DomName('HTMLInputElement.maxLength')
  @DocsEditable()
  int maxLength;

  @DomName('HTMLInputElement.min')
  @DocsEditable()
  String min;

  @DomName('HTMLInputElement.multiple')
  @DocsEditable()
  bool multiple;

  @DomName('HTMLInputElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLInputElement.pattern')
  @DocsEditable()
  String pattern;

  @DomName('HTMLInputElement.placeholder')
  @DocsEditable()
  String placeholder;

  @DomName('HTMLInputElement.readOnly')
  @DocsEditable()
  bool readOnly;

  @DomName('HTMLInputElement.required')
  @DocsEditable()
  bool required;

  @DomName('HTMLInputElement.selectionDirection')
  @DocsEditable()
  String selectionDirection;

  @DomName('HTMLInputElement.selectionEnd')
  @DocsEditable()
  int selectionEnd;

  @DomName('HTMLInputElement.selectionStart')
  @DocsEditable()
  int selectionStart;

  @DomName('HTMLInputElement.size')
  @DocsEditable()
  int size;

  @DomName('HTMLInputElement.src')
  @DocsEditable()
  String src;

  @DomName('HTMLInputElement.step')
  @DocsEditable()
  String step;

  @DomName('HTMLInputElement.type')
  @DocsEditable()
  String type;

  @DomName('HTMLInputElement.validationMessage')
  @DocsEditable()
  final String validationMessage;

  @DomName('HTMLInputElement.validity')
  @DocsEditable()
  final ValidityState validity;

  @DomName('HTMLInputElement.value')
  @DocsEditable()
  String value;

  @DomName('HTMLInputElement.valueAsDate')
  @DocsEditable()
  DateTime get valueAsDate => convertNativeToDart_DateTime(this._get_valueAsDate);
  @JSName('valueAsDate')
  @DomName('HTMLInputElement.valueAsDate')
  @DocsEditable()
  @Creates('Null')
  final dynamic _get_valueAsDate;

  void set valueAsDate(DateTime value) {
    this._set_valueAsDate = convertDartToNative_DateTime(value);
  }
  void set _set_valueAsDate(/*dynamic*/ value) {
    JS("void", "#.valueAsDate = #", this, value);
  }

  @DomName('HTMLInputElement.valueAsNumber')
  @DocsEditable()
  num valueAsNumber;

  @JSName('webkitEntries')
  @DomName('HTMLInputElement.webkitEntries')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#concept-input-type-file-selected
  final List<Entry> entries;

  @JSName('webkitGrammar')
  @DomName('HTMLInputElement.webkitGrammar')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://lists.w3.org/Archives/Public/public-xg-htmlspeech/2011Feb/att-0020/api-draft.html#attrib-grammar
  bool grammar;

  @JSName('webkitSpeech')
  @DomName('HTMLInputElement.webkitSpeech')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://lists.w3.org/Archives/Public/public-xg-htmlspeech/2011Feb/att-0020/api-draft.html#attrib-speech
  bool speech;

  @JSName('webkitdirectory')
  @DomName('HTMLInputElement.webkitdirectory')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://plus.sandbox.google.com/+AddyOsmani/posts/Dk5UhZ6zfF3
  bool directory;

  @DomName('HTMLInputElement.width')
  @DocsEditable()
  int width;

  @DomName('HTMLInputElement.willValidate')
  @DocsEditable()
  final bool willValidate;

  @DomName('HTMLInputElement.checkValidity')
  @DocsEditable()
  bool checkValidity() native;

  @DomName('HTMLInputElement.select')
  @DocsEditable()
  void select() native;

  @DomName('HTMLInputElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) native;

  @DomName('HTMLInputElement.setRangeText')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#dom-textarea/input-setrangetext
  @Experimental() // experimental
  void setRangeText(String replacement, {int start, int end, String selectionMode}) native;

  @DomName('HTMLInputElement.setSelectionRange')
  @DocsEditable()
  void setSelectionRange(int start, int end, [String direction]) native;

  @DomName('HTMLInputElement.stepDown')
  @DocsEditable()
  void stepDown([int n]) native;

  @DomName('HTMLInputElement.stepUp')
  @DocsEditable()
  void stepUp([int n]) native;

  /// Stream of `speechchange` events handled by this [InputElement].
  @DomName('HTMLInputElement.onwebkitSpeechChange')
  @DocsEditable()
  // http://lists.w3.org/Archives/Public/public-xg-htmlspeech/2011Feb/att-0020/api-draft.html#extending_html_elements
  @Experimental()
  ElementStream<Event> get onSpeechChange => speechChangeEvent.forElement(this);

}


// Interfaces representing the InputElement APIs which are supported
// for the various types of InputElement. From:
// http://www.w3.org/html/wg/drafts/html/master/forms.html#the-input-element.

/**
 * Exposes the functionality common between all InputElement types.
 */
abstract class InputElementBase implements Element {
  @DomName('HTMLInputElement.autofocus')
  bool autofocus;

  @DomName('HTMLInputElement.disabled')
  bool disabled;

  @DomName('HTMLInputElement.incremental')
  bool incremental;

  @DomName('HTMLInputElement.indeterminate')
  bool indeterminate;

  @DomName('HTMLInputElement.labels')
  List<Node> get labels;

  @DomName('HTMLInputElement.name')
  String name;

  @DomName('HTMLInputElement.validationMessage')
  String get validationMessage;

  @DomName('HTMLInputElement.validity')
  ValidityState get validity;

  @DomName('HTMLInputElement.value')
  String value;

  @DomName('HTMLInputElement.willValidate')
  bool get willValidate;

  @DomName('HTMLInputElement.checkValidity')
  bool checkValidity();

  @DomName('HTMLInputElement.setCustomValidity')
  void setCustomValidity(String error);
}

/**
 * Hidden input which is not intended to be seen or edited by the user.
 */
abstract class HiddenInputElement implements InputElementBase {
  factory HiddenInputElement() => new InputElement(type: 'hidden');
}


/**
 * Base interface for all inputs which involve text editing.
 */
abstract class TextInputElementBase implements InputElementBase {
  @DomName('HTMLInputElement.autocomplete')
  String autocomplete;

  @DomName('HTMLInputElement.maxLength')
  int maxLength;

  @DomName('HTMLInputElement.pattern')
  String pattern;

  @DomName('HTMLInputElement.placeholder')
  String placeholder;

  @DomName('HTMLInputElement.readOnly')
  bool readOnly;

  @DomName('HTMLInputElement.required')
  bool required;

  @DomName('HTMLInputElement.size')
  int size;

  @DomName('HTMLInputElement.select')
  void select();

  @DomName('HTMLInputElement.selectionDirection')
  String selectionDirection;

  @DomName('HTMLInputElement.selectionEnd')
  int selectionEnd;

  @DomName('HTMLInputElement.selectionStart')
  int selectionStart;

  @DomName('HTMLInputElement.setSelectionRange')
  void setSelectionRange(int start, int end, [String direction]);
}

/**
 * Similar to [TextInputElement], but on platforms where search is styled
 * differently this will get the search style.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
abstract class SearchInputElement implements TextInputElementBase {
  factory SearchInputElement() => new InputElement(type: 'search');

  @DomName('HTMLInputElement.dirName')
  String dirName;

  @DomName('HTMLInputElement.list')
  Element get list;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'search')).type == 'search';
  }
}

/**
 * A basic text input editor control.
 */
abstract class TextInputElement implements TextInputElementBase {
  factory TextInputElement() => new InputElement(type: 'text');

  @DomName('HTMLInputElement.dirName')
  String dirName;

  @DomName('HTMLInputElement.list')
  Element get list;
}

/**
 * A control for editing an absolute URL.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
abstract class UrlInputElement implements TextInputElementBase {
  factory UrlInputElement() => new InputElement(type: 'url');

  @DomName('HTMLInputElement.list')
  Element get list;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'url')).type == 'url';
  }
}

/**
 * Represents a control for editing a telephone number.
 *
 * This provides a single line of text with minimal formatting help since
 * there is a wide variety of telephone numbers.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
abstract class TelephoneInputElement implements TextInputElementBase {
  factory TelephoneInputElement() => new InputElement(type: 'tel');

  @DomName('HTMLInputElement.list')
  Element get list;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'tel')).type == 'tel';
  }
}

/**
 * An e-mail address or list of e-mail addresses.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
abstract class EmailInputElement implements TextInputElementBase {
  factory EmailInputElement() => new InputElement(type: 'email');

  @DomName('HTMLInputElement.autocomplete')
  String autocomplete;

  @DomName('HTMLInputElement.autofocus')
  bool autofocus;

  @DomName('HTMLInputElement.list')
  Element get list;

  @DomName('HTMLInputElement.maxLength')
  int maxLength;

  @DomName('HTMLInputElement.multiple')
  bool multiple;

  @DomName('HTMLInputElement.pattern')
  String pattern;

  @DomName('HTMLInputElement.placeholder')
  String placeholder;

  @DomName('HTMLInputElement.readOnly')
  bool readOnly;

  @DomName('HTMLInputElement.required')
  bool required;

  @DomName('HTMLInputElement.size')
  int size;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'email')).type == 'email';
  }
}

/**
 * Text with no line breaks (sensitive information).
 */
abstract class PasswordInputElement implements TextInputElementBase {
  factory PasswordInputElement() => new InputElement(type: 'password');
}

/**
 * Base interface for all input element types which involve ranges.
 */
abstract class RangeInputElementBase implements InputElementBase {

  @DomName('HTMLInputElement.list')
  Element get list;

  @DomName('HTMLInputElement.max')
  String max;

  @DomName('HTMLInputElement.min')
  String min;

  @DomName('HTMLInputElement.step')
  String step;

  @DomName('HTMLInputElement.valueAsNumber')
  num valueAsNumber;

  @DomName('HTMLInputElement.stepDown')
  void stepDown([int n]);

  @DomName('HTMLInputElement.stepUp')
  void stepUp([int n]);
}

/**
 * A date (year, month, day) with no time zone.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
abstract class DateInputElement implements RangeInputElementBase {
  factory DateInputElement() => new InputElement(type: 'date');

  @DomName('HTMLInputElement.valueAsDate')
  DateTime valueAsDate;

  @DomName('HTMLInputElement.readOnly')
  bool readOnly;

  @DomName('HTMLInputElement.required')
  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'date')).type == 'date';
  }
}

/**
 * A date consisting of a year and a month with no time zone.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
abstract class MonthInputElement implements RangeInputElementBase {
  factory MonthInputElement() => new InputElement(type: 'month');

  @DomName('HTMLInputElement.valueAsDate')
  DateTime valueAsDate;

  @DomName('HTMLInputElement.readOnly')
  bool readOnly;

  @DomName('HTMLInputElement.required')
  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'month')).type == 'month';
  }
}

/**
 * A date consisting of a week-year number and a week number with no time zone.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
abstract class WeekInputElement implements RangeInputElementBase {
  factory WeekInputElement() => new InputElement(type: 'week');

  @DomName('HTMLInputElement.valueAsDate')
  DateTime valueAsDate;

  @DomName('HTMLInputElement.readOnly')
  bool readOnly;

  @DomName('HTMLInputElement.required')
  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'week')).type == 'week';
  }
}

/**
 * A time (hour, minute, seconds, fractional seconds) with no time zone.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
abstract class TimeInputElement implements RangeInputElementBase {
  factory TimeInputElement() => new InputElement(type: 'time');

  @DomName('HTMLInputElement.valueAsDate')
  DateTime valueAsDate;

  @DomName('HTMLInputElement.readOnly')
  bool readOnly;

  @DomName('HTMLInputElement.required')
  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'time')).type == 'time';
  }
}

/**
 * A date and time (year, month, day, hour, minute, second, fraction of a
 * second) with no time zone.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
abstract class LocalDateTimeInputElement implements RangeInputElementBase {
  factory LocalDateTimeInputElement() =>
      new InputElement(type: 'datetime-local');

  @DomName('HTMLInputElement.readOnly')
  bool readOnly;

  @DomName('HTMLInputElement.required')
  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'datetime-local')).type == 'datetime-local';
  }
}

/**
 * A numeric editor control.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
abstract class NumberInputElement implements RangeInputElementBase {
  factory NumberInputElement() => new InputElement(type: 'number');

  @DomName('HTMLInputElement.placeholder')
  String placeholder;

  @DomName('HTMLInputElement.readOnly')
  bool readOnly;

  @DomName('HTMLInputElement.required')
  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'number')).type == 'number';
  }
}

/**
 * Similar to [NumberInputElement] but the browser may provide more optimal
 * styling (such as a slider control).
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE, '10')
@Experimental()
abstract class RangeInputElement implements RangeInputElementBase {
  factory RangeInputElement() => new InputElement(type: 'range');

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'range')).type == 'range';
  }
}

/**
 * A boolean editor control.
 *
 * Note that if [indeterminate] is set then this control is in a third
 * indeterminate state.
 */
abstract class CheckboxInputElement implements InputElementBase {
  factory CheckboxInputElement() => new InputElement(type: 'checkbox');

  @DomName('HTMLInputElement.checked')
  bool checked;

  @DomName('HTMLInputElement.required')
  bool required;
}


/**
 * A control that when used with other [ReadioButtonInputElement] controls
 * forms a radio button group in which only one control can be checked at a
 * time.
 *
 * Radio buttons are considered to be in the same radio button group if:
 *
 * * They are all of type 'radio'.
 * * They all have either the same [FormElement] owner, or no owner.
 * * Their name attributes contain the same name.
 */
abstract class RadioButtonInputElement implements InputElementBase {
  factory RadioButtonInputElement() => new InputElement(type: 'radio');

  @DomName('HTMLInputElement.checked')
  bool checked;

  @DomName('HTMLInputElement.required')
  bool required;
}

/**
 * A control for picking files from the user's computer.
 */
abstract class FileUploadInputElement implements InputElementBase {
  factory FileUploadInputElement() => new InputElement(type: 'file');

  @DomName('HTMLInputElement.accept')
  String accept;

  @DomName('HTMLInputElement.multiple')
  bool multiple;

  @DomName('HTMLInputElement.required')
  bool required;

  @DomName('HTMLInputElement.files')
  List<File> files;
}

/**
 * A button, which when clicked, submits the form.
 */
abstract class SubmitButtonInputElement implements InputElementBase {
  factory SubmitButtonInputElement() => new InputElement(type: 'submit');

  @DomName('HTMLInputElement.formAction')
  String formAction;

  @DomName('HTMLInputElement.formEnctype')
  String formEnctype;

  @DomName('HTMLInputElement.formMethod')
  String formMethod;

  @DomName('HTMLInputElement.formNoValidate')
  bool formNoValidate;

  @DomName('HTMLInputElement.formTarget')
  String formTarget;
}

/**
 * Either an image which the user can select a coordinate to or a form
 * submit button.
 */
abstract class ImageButtonInputElement implements InputElementBase {
  factory ImageButtonInputElement() => new InputElement(type: 'image');

  @DomName('HTMLInputElement.alt')
  String alt;

  @DomName('HTMLInputElement.formAction')
  String formAction;

  @DomName('HTMLInputElement.formEnctype')
  String formEnctype;

  @DomName('HTMLInputElement.formMethod')
  String formMethod;

  @DomName('HTMLInputElement.formNoValidate')
  bool formNoValidate;

  @DomName('HTMLInputElement.formTarget')
  String formTarget;

  @DomName('HTMLInputElement.height')
  int height;

  @DomName('HTMLInputElement.src')
  String src;

  @DomName('HTMLInputElement.width')
  int width;
}

/**
 * A button, which when clicked, resets the form.
 */
abstract class ResetButtonInputElement implements InputElementBase {
  factory ResetButtonInputElement() => new InputElement(type: 'reset');
}

/**
 * A button, with no default behavior.
 */
abstract class ButtonInputElement implements InputElementBase {
  factory ButtonInputElement() => new InputElement(type: 'button');
}

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


@DocsEditable()
@DomName('InputMethodContext')
// http://www.w3.org/TR/ime-api/#idl-def-InputMethodContext
@Experimental()
class InputMethodContext extends EventTarget native "InputMethodContext" {
  // To suppress missing implicit constructor warnings.
  factory InputMethodContext._() { throw new UnsupportedError("Not supported"); }

  @DomName('InputMethodContext.compositionEndOffset')
  @DocsEditable()
  @Experimental() // untriaged
  final int compositionEndOffset;

  @DomName('InputMethodContext.compositionStartOffset')
  @DocsEditable()
  @Experimental() // untriaged
  final int compositionStartOffset;

  @DomName('InputMethodContext.locale')
  @DocsEditable()
  final String locale;

  @DomName('InputMethodContext.target')
  @DocsEditable()
  @Experimental() // untriaged
  final HtmlElement target;

  @DomName('InputMethodContext.confirmComposition')
  @DocsEditable()
  void confirmComposition() native;
}
// 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.


@DocsEditable()
@DomName('InstallEvent')
@Experimental() // untriaged
class InstallEvent extends InstallPhaseEvent native "InstallEvent" {
  // To suppress missing implicit constructor warnings.
  factory InstallEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('InstallEvent.replace')
  @DocsEditable()
  @Experimental() // untriaged
  void replace() native;
}
// 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.


@DocsEditable()
@DomName('InstallPhaseEvent')
@Experimental() // untriaged
class InstallPhaseEvent extends Event native "InstallPhaseEvent" {
  // To suppress missing implicit constructor warnings.
  factory InstallPhaseEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('InstallPhaseEvent.waitUntil')
  @DocsEditable()
  @Experimental() // untriaged
  void waitUntil(Object value) native;
}
// 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.


@DocsEditable()
@DomName('KeyPair')
@Experimental() // untriaged
class KeyPair extends Interceptor native "KeyPair" {
  // To suppress missing implicit constructor warnings.
  factory KeyPair._() { throw new UnsupportedError("Not supported"); }

  @DomName('KeyPair.privateKey')
  @DocsEditable()
  @Experimental() // untriaged
  final CryptoKey privateKey;

  @DomName('KeyPair.publicKey')
  @DocsEditable()
  @Experimental() // untriaged
  final CryptoKey publicKey;
}
// 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.


/**
 * An event that describes user interaction with the keyboard.
 *
 * The [type] of the event identifies what kind of interaction occurred.
 *
 * See also:
 *
 * * [KeyboardEvent](https://developer.mozilla.org/en/DOM/KeyboardEvent) at MDN.
 */
@DomName('KeyboardEvent')
class KeyboardEvent extends UIEvent native "KeyboardEvent" {

  /** 
   * Programmatically create a KeyboardEvent. 
   *
   * Due to browser differences, keyCode, charCode, or keyIdentifier values
   * cannot be specified in this base level constructor. This constructor
   * enables the user to programmatically create and dispatch a [KeyboardEvent],
   * but it will not contain any particular key content. For programmatically
   * creating keyboard events with specific key value contents, see the custom
   * Event [KeyEvent]. 
   */
  factory KeyboardEvent(String type,
      {Window view, bool canBubble: true, bool cancelable: true,
      int keyLocation: 1, bool ctrlKey: false,
      bool altKey: false, bool shiftKey: false, bool metaKey: false,
      bool altGraphKey: false}) {
    if (view == null) {
      view = window;
    }
    final e = document._createEvent("KeyboardEvent");
    e._initKeyboardEvent(type, canBubble, cancelable, view, "",
        keyLocation, ctrlKey, altKey, shiftKey, metaKey, altGraphKey);
    return e;
  }

  @DomName('KeyboardEvent.initKeyboardEvent')
  void _initKeyboardEvent(String type, bool canBubble, bool cancelable,
      Window view, String keyIdentifier, int keyLocation, bool ctrlKey,
      bool altKey, bool shiftKey, bool metaKey, bool altGraphKey) {
    if (JS('bool', 'typeof(#.initKeyEvent) == "function"', this)) {
      // initKeyEvent is only in Firefox (instead of initKeyboardEvent). It has
      // a slightly different signature, and allows you to specify keyCode and
      // charCode as the last two arguments, but we just set them as the default
      // since they can't be specified in other browsers.
      JS('void', '#.initKeyEvent(#, #, #, #, #, #, #, #, 0, 0)', this,
          type, canBubble, cancelable, view,
          ctrlKey, altKey, shiftKey, metaKey);
    } else {
      // initKeyboardEvent is for all other browsers.
      JS('void', '#.initKeyboardEvent(#, #, #, #, #, #, #, #, #, #, #)', this,
          type, canBubble, cancelable, view, keyIdentifier, keyLocation,
          ctrlKey, altKey, shiftKey, metaKey, altGraphKey);
    }
  }

  @DomName('KeyboardEvent.keyCode')
  int get keyCode => _keyCode;

  @DomName('KeyboardEvent.charCode')
  int get charCode => _charCode;
  // To suppress missing implicit constructor warnings.
  factory KeyboardEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('KeyboardEvent.DOM_KEY_LOCATION_LEFT')
  @DocsEditable()
  @Experimental() // untriaged
  static const int DOM_KEY_LOCATION_LEFT = 0x01;

  @DomName('KeyboardEvent.DOM_KEY_LOCATION_NUMPAD')
  @DocsEditable()
  @Experimental() // untriaged
  static const int DOM_KEY_LOCATION_NUMPAD = 0x03;

  @DomName('KeyboardEvent.DOM_KEY_LOCATION_RIGHT')
  @DocsEditable()
  @Experimental() // untriaged
  static const int DOM_KEY_LOCATION_RIGHT = 0x02;

  @DomName('KeyboardEvent.DOM_KEY_LOCATION_STANDARD')
  @DocsEditable()
  @Experimental() // untriaged
  static const int DOM_KEY_LOCATION_STANDARD = 0x00;

  @DomName('KeyboardEvent.altGraphKey')
  @DocsEditable()
  @Experimental() // nonstandard
  final bool altGraphKey;

  @DomName('KeyboardEvent.altKey')
  @DocsEditable()
  final bool altKey;

  @DomName('KeyboardEvent.ctrlKey')
  @DocsEditable()
  final bool ctrlKey;

  @JSName('keyIdentifier')
  @DomName('KeyboardEvent.keyIdentifier')
  @DocsEditable()
  @Experimental() // nonstandard
  final String _keyIdentifier;

  @DomName('KeyboardEvent.keyLocation')
  @DocsEditable()
  @Experimental() // nonstandard
  final int keyLocation;

  @DomName('KeyboardEvent.location')
  @DocsEditable()
  @Experimental() // untriaged
  final int location;

  @DomName('KeyboardEvent.metaKey')
  @DocsEditable()
  final bool metaKey;

  @DomName('KeyboardEvent.repeat')
  @DocsEditable()
  @Experimental() // untriaged
  final bool repeat;

  @DomName('KeyboardEvent.shiftKey')
  @DocsEditable()
  final bool shiftKey;

  @DomName('KeyboardEvent.getModifierState')
  @DocsEditable()
  @Experimental() // untriaged
  bool getModifierState(String keyArgument) native;

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


@DocsEditable()
@DomName('HTMLKeygenElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#the-keygen-element
class KeygenElement extends HtmlElement native "HTMLKeygenElement" {
  // To suppress missing implicit constructor warnings.
  factory KeygenElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLKeygenElement.HTMLKeygenElement')
  @DocsEditable()
  factory KeygenElement() => document.createElement("keygen");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  KeygenElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('keygen') && (new Element.tag('keygen') is KeygenElement);

  @DomName('HTMLKeygenElement.autofocus')
  @DocsEditable()
  bool autofocus;

  @DomName('HTMLKeygenElement.challenge')
  @DocsEditable()
  String challenge;

  @DomName('HTMLKeygenElement.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('HTMLKeygenElement.form')
  @DocsEditable()
  final FormElement form;

  @DomName('HTMLKeygenElement.keytype')
  @DocsEditable()
  String keytype;

  @DomName('HTMLKeygenElement.labels')
  @DocsEditable()
  @Unstable()
  @Returns('NodeList')
  @Creates('NodeList')
  final List<Node> labels;

  @DomName('HTMLKeygenElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLKeygenElement.type')
  @DocsEditable()
  final String type;

  @DomName('HTMLKeygenElement.validationMessage')
  @DocsEditable()
  final String validationMessage;

  @DomName('HTMLKeygenElement.validity')
  @DocsEditable()
  final ValidityState validity;

  @DomName('HTMLKeygenElement.willValidate')
  @DocsEditable()
  final bool willValidate;

  @DomName('HTMLKeygenElement.checkValidity')
  @DocsEditable()
  bool checkValidity() native;

  @DomName('HTMLKeygenElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) native;
}
// 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.


@DocsEditable()
@DomName('HTMLLIElement')
class LIElement extends HtmlElement native "HTMLLIElement" {
  // To suppress missing implicit constructor warnings.
  factory LIElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLLIElement.HTMLLIElement')
  @DocsEditable()
  factory LIElement() => document.createElement("li");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  LIElement.created() : super.created();

  @DomName('HTMLLIElement.value')
  @DocsEditable()
  int value;
}
// 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.


@DocsEditable()
@DomName('HTMLLabelElement')
class LabelElement extends HtmlElement native "HTMLLabelElement" {
  // To suppress missing implicit constructor warnings.
  factory LabelElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLLabelElement.HTMLLabelElement')
  @DocsEditable()
  factory LabelElement() => document.createElement("label");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  LabelElement.created() : super.created();

  @DomName('HTMLLabelElement.control')
  @DocsEditable()
  final HtmlElement control;

  @DomName('HTMLLabelElement.form')
  @DocsEditable()
  final FormElement form;

  @DomName('HTMLLabelElement.htmlFor')
  @DocsEditable()
  String htmlFor;
}
// 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.


@DocsEditable()
@DomName('HTMLLegendElement')
class LegendElement extends HtmlElement native "HTMLLegendElement" {
  // To suppress missing implicit constructor warnings.
  factory LegendElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLLegendElement.HTMLLegendElement')
  @DocsEditable()
  factory LegendElement() => document.createElement("legend");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  LegendElement.created() : super.created();

  @DomName('HTMLLegendElement.form')
  @DocsEditable()
  final FormElement form;
}
// Copyright (c) 2014, 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.


@DocsEditable()
@DomName('HTMLLinkElement')
class LinkElement extends HtmlElement native "HTMLLinkElement" {
  // To suppress missing implicit constructor warnings.
  factory LinkElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLLinkElement.HTMLLinkElement')
  @DocsEditable()
  factory LinkElement() => document.createElement("link");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  LinkElement.created() : super.created();

  @DomName('HTMLLinkElement.crossOrigin')
  @DocsEditable()
  @Experimental() // untriaged
  String crossOrigin;

  @DomName('HTMLLinkElement.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('HTMLLinkElement.href')
  @DocsEditable()
  String href;

  @DomName('HTMLLinkElement.hreflang')
  @DocsEditable()
  String hreflang;

  @DomName('HTMLLinkElement.import')
  @DocsEditable()
  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/imports/index.html#interface-import
  @Experimental()
  final Document import;

  @DomName('HTMLLinkElement.media')
  @DocsEditable()
  String media;

  @DomName('HTMLLinkElement.rel')
  @DocsEditable()
  String rel;

  @DomName('HTMLLinkElement.sheet')
  @DocsEditable()
  final StyleSheet sheet;

  @DomName('HTMLLinkElement.sizes')
  @DocsEditable()
  final DomSettableTokenList sizes;

  @DomName('HTMLLinkElement.type')
  @DocsEditable()
  String type;


    /// Checks if HTML imports are supported on the current platform.
  bool get supportsImport {
    return JS('bool', '("import" in #)', this);
  }
}
// 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.


@DocsEditable()
@DomName('Location')
class Location extends Interceptor implements LocationBase native "Location" {
  // To suppress missing implicit constructor warnings.
  factory Location._() { throw new UnsupportedError("Not supported"); }

  @DomName('Location.ancestorOrigins')
  @DocsEditable()
  @Experimental() // nonstandard
  @Returns('DomStringList')
  @Creates('DomStringList')
  final List<String> ancestorOrigins;

  @DomName('Location.hash')
  @DocsEditable()
  String hash;

  @DomName('Location.host')
  @DocsEditable()
  String host;

  @DomName('Location.hostname')
  @DocsEditable()
  String hostname;

  @DomName('Location.href')
  @DocsEditable()
  String href;

  @DomName('Location.pathname')
  @DocsEditable()
  String pathname;

  @DomName('Location.port')
  @DocsEditable()
  String port;

  @DomName('Location.protocol')
  @DocsEditable()
  String protocol;

  @DomName('Location.search')
  @DocsEditable()
  String search;

  @DomName('Location.assign')
  @DocsEditable()
  void assign(String url) native;

  @DomName('Location.reload')
  @DocsEditable()
  void reload() native;

  @DomName('Location.replace')
  @DocsEditable()
  void replace(String url) native;

  @DomName('Location.toString')
  @DocsEditable()
  String toString() native;


  @DomName('Location.origin')
  String get origin {
    if (JS('bool', '("origin" in #)', this)) {
      return JS('String', '#.origin', this);
    }
    return '${this.protocol}//${this.host}';
  }
}
// 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.


@DomName('MIDIErrorCallback')
// http://webaudio.github.io/web-midi-api/#midierrorcallback
@Experimental()
typedef void MidiErrorCallback(DomError error);
// 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.


@DomName('MIDISuccessCallback')
@Experimental() // untriaged
typedef void MidiSuccessCallback(MidiAccess access, bool sysex);
// 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.


@DocsEditable()
@DomName('HTMLMapElement')
class MapElement extends HtmlElement native "HTMLMapElement" {
  // To suppress missing implicit constructor warnings.
  factory MapElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLMapElement.HTMLMapElement')
  @DocsEditable()
  factory MapElement() => document.createElement("map");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  MapElement.created() : super.created();

  @DomName('HTMLMapElement.areas')
  @DocsEditable()
  @Returns('HtmlCollection')
  @Creates('HtmlCollection')
  final List<Node> areas;

  @DomName('HTMLMapElement.name')
  @DocsEditable()
  String name;
}
// 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.


@DocsEditable()
@DomName('MediaController')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#mediacontroller
@Experimental()
class MediaController extends EventTarget native "MediaController" {
  // To suppress missing implicit constructor warnings.
  factory MediaController._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaController.MediaController')
  @DocsEditable()
  factory MediaController() {
    return MediaController._create_1();
  }
  static MediaController _create_1() => JS('MediaController', 'new MediaController()');

  @DomName('MediaController.buffered')
  @DocsEditable()
  final TimeRanges buffered;

  @DomName('MediaController.currentTime')
  @DocsEditable()
  num currentTime;

  @DomName('MediaController.defaultPlaybackRate')
  @DocsEditable()
  num defaultPlaybackRate;

  @DomName('MediaController.duration')
  @DocsEditable()
  final double duration;

  @DomName('MediaController.muted')
  @DocsEditable()
  bool muted;

  @DomName('MediaController.paused')
  @DocsEditable()
  final bool paused;

  @DomName('MediaController.playbackRate')
  @DocsEditable()
  num playbackRate;

  @DomName('MediaController.playbackState')
  @DocsEditable()
  final String playbackState;

  @DomName('MediaController.played')
  @DocsEditable()
  final TimeRanges played;

  @DomName('MediaController.seekable')
  @DocsEditable()
  final TimeRanges seekable;

  @DomName('MediaController.volume')
  @DocsEditable()
  num volume;

  @DomName('MediaController.pause')
  @DocsEditable()
  void pause() native;

  @DomName('MediaController.play')
  @DocsEditable()
  void play() native;

  @DomName('MediaController.unpause')
  @DocsEditable()
  void unpause() native;
}
// 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.


@DocsEditable()
@DomName('HTMLMediaElement')
@Unstable()
class MediaElement extends HtmlElement native "HTMLMediaElement" {
  // To suppress missing implicit constructor warnings.
  factory MediaElement._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `canplay` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.canplayEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> canPlayEvent = const EventStreamProvider<Event>('canplay');

  /**
   * Static factory designed to expose `canplaythrough` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.canplaythroughEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> canPlayThroughEvent = const EventStreamProvider<Event>('canplaythrough');

  /**
   * Static factory designed to expose `durationchange` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.durationchangeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> durationChangeEvent = const EventStreamProvider<Event>('durationchange');

  /**
   * Static factory designed to expose `emptied` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.emptiedEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> emptiedEvent = const EventStreamProvider<Event>('emptied');

  /**
   * Static factory designed to expose `ended` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.endedEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');

  /**
   * Static factory designed to expose `loadeddata` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.loadeddataEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> loadedDataEvent = const EventStreamProvider<Event>('loadeddata');

  /**
   * Static factory designed to expose `loadedmetadata` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.loadedmetadataEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> loadedMetadataEvent = const EventStreamProvider<Event>('loadedmetadata');

  /**
   * Static factory designed to expose `loadstart` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.loadstartEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> loadStartEvent = const EventStreamProvider<Event>('loadstart');

  /**
   * Static factory designed to expose `pause` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.pauseEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> pauseEvent = const EventStreamProvider<Event>('pause');

  /**
   * Static factory designed to expose `play` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.playEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> playEvent = const EventStreamProvider<Event>('play');

  /**
   * Static factory designed to expose `playing` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.playingEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> playingEvent = const EventStreamProvider<Event>('playing');

  /**
   * Static factory designed to expose `progress` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.progressEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> progressEvent = const EventStreamProvider<Event>('progress');

  /**
   * Static factory designed to expose `ratechange` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.ratechangeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> rateChangeEvent = const EventStreamProvider<Event>('ratechange');

  /**
   * Static factory designed to expose `seeked` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.seekedEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> seekedEvent = const EventStreamProvider<Event>('seeked');

  /**
   * Static factory designed to expose `seeking` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.seekingEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> seekingEvent = const EventStreamProvider<Event>('seeking');

  /**
   * Static factory designed to expose `show` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.showEvent')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#event-media-loadstart
  @Experimental()
  static const EventStreamProvider<Event> showEvent = const EventStreamProvider<Event>('show');

  /**
   * Static factory designed to expose `stalled` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.stalledEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> stalledEvent = const EventStreamProvider<Event>('stalled');

  /**
   * Static factory designed to expose `suspend` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.suspendEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> suspendEvent = const EventStreamProvider<Event>('suspend');

  /**
   * Static factory designed to expose `timeupdate` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.timeupdateEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> timeUpdateEvent = const EventStreamProvider<Event>('timeupdate');

  /**
   * Static factory designed to expose `volumechange` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.volumechangeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> volumeChangeEvent = const EventStreamProvider<Event>('volumechange');

  /**
   * Static factory designed to expose `waiting` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.waitingEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> waitingEvent = const EventStreamProvider<Event>('waiting');

  /**
   * Static factory designed to expose `keyadded` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.webkitkeyaddedEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  static const EventStreamProvider<MediaKeyEvent> keyAddedEvent = const EventStreamProvider<MediaKeyEvent>('webkitkeyadded');

  /**
   * Static factory designed to expose `keyerror` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.webkitkeyerrorEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  static const EventStreamProvider<MediaKeyEvent> keyErrorEvent = const EventStreamProvider<MediaKeyEvent>('webkitkeyerror');

  /**
   * Static factory designed to expose `keymessage` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.webkitkeymessageEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  static const EventStreamProvider<MediaKeyEvent> keyMessageEvent = const EventStreamProvider<MediaKeyEvent>('webkitkeymessage');

  /**
   * Static factory designed to expose `needkey` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.webkitneedkeyEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  static const EventStreamProvider<MediaKeyEvent> needKeyEvent = const EventStreamProvider<MediaKeyEvent>('webkitneedkey');
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  MediaElement.created() : super.created();

  @DomName('HTMLMediaElement.HAVE_CURRENT_DATA')
  @DocsEditable()
  static const int HAVE_CURRENT_DATA = 2;

  @DomName('HTMLMediaElement.HAVE_ENOUGH_DATA')
  @DocsEditable()
  static const int HAVE_ENOUGH_DATA = 4;

  @DomName('HTMLMediaElement.HAVE_FUTURE_DATA')
  @DocsEditable()
  static const int HAVE_FUTURE_DATA = 3;

  @DomName('HTMLMediaElement.HAVE_METADATA')
  @DocsEditable()
  static const int HAVE_METADATA = 1;

  @DomName('HTMLMediaElement.HAVE_NOTHING')
  @DocsEditable()
  static const int HAVE_NOTHING = 0;

  @DomName('HTMLMediaElement.NETWORK_EMPTY')
  @DocsEditable()
  static const int NETWORK_EMPTY = 0;

  @DomName('HTMLMediaElement.NETWORK_IDLE')
  @DocsEditable()
  static const int NETWORK_IDLE = 1;

  @DomName('HTMLMediaElement.NETWORK_LOADING')
  @DocsEditable()
  static const int NETWORK_LOADING = 2;

  @DomName('HTMLMediaElement.NETWORK_NO_SOURCE')
  @DocsEditable()
  static const int NETWORK_NO_SOURCE = 3;

  @DomName('HTMLMediaElement.autoplay')
  @DocsEditable()
  bool autoplay;

  @DomName('HTMLMediaElement.buffered')
  @DocsEditable()
  final TimeRanges buffered;

  @DomName('HTMLMediaElement.controller')
  @DocsEditable()
  MediaController controller;

  @DomName('HTMLMediaElement.controls')
  @DocsEditable()
  bool controls;

  @DomName('HTMLMediaElement.crossOrigin')
  @DocsEditable()
  @Experimental() // untriaged
  String crossOrigin;

  @DomName('HTMLMediaElement.currentSrc')
  @DocsEditable()
  final String currentSrc;

  @DomName('HTMLMediaElement.currentTime')
  @DocsEditable()
  num currentTime;

  @DomName('HTMLMediaElement.defaultMuted')
  @DocsEditable()
  bool defaultMuted;

  @DomName('HTMLMediaElement.defaultPlaybackRate')
  @DocsEditable()
  num defaultPlaybackRate;

  @DomName('HTMLMediaElement.duration')
  @DocsEditable()
  final double duration;

  @DomName('HTMLMediaElement.ended')
  @DocsEditable()
  final bool ended;

  @DomName('HTMLMediaElement.error')
  @DocsEditable()
  final MediaError error;

  @DomName('HTMLMediaElement.loop')
  @DocsEditable()
  bool loop;

  @DomName('HTMLMediaElement.mediaGroup')
  @DocsEditable()
  String mediaGroup;

  @DomName('HTMLMediaElement.mediaKeys')
  @DocsEditable()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html
  @Experimental()
  final MediaKeys mediaKeys;

  @DomName('HTMLMediaElement.muted')
  @DocsEditable()
  bool muted;

  @DomName('HTMLMediaElement.networkState')
  @DocsEditable()
  final int networkState;

  @DomName('HTMLMediaElement.paused')
  @DocsEditable()
  final bool paused;

  @DomName('HTMLMediaElement.playbackRate')
  @DocsEditable()
  num playbackRate;

  @DomName('HTMLMediaElement.played')
  @DocsEditable()
  final TimeRanges played;

  @DomName('HTMLMediaElement.preload')
  @DocsEditable()
  String preload;

  @DomName('HTMLMediaElement.readyState')
  @DocsEditable()
  final int readyState;

  @DomName('HTMLMediaElement.seekable')
  @DocsEditable()
  final TimeRanges seekable;

  @DomName('HTMLMediaElement.seeking')
  @DocsEditable()
  final bool seeking;

  @DomName('HTMLMediaElement.src')
  @DocsEditable()
  String src;

  @DomName('HTMLMediaElement.textTracks')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-media-texttracks
  @Experimental()
  final TextTrackList textTracks;

  @DomName('HTMLMediaElement.volume')
  @DocsEditable()
  num volume;

  @JSName('webkitAudioDecodedByteCount')
  @DomName('HTMLMediaElement.webkitAudioDecodedByteCount')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // nonstandard
  final int audioDecodedByteCount;

  @JSName('webkitVideoDecodedByteCount')
  @DomName('HTMLMediaElement.webkitVideoDecodedByteCount')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // nonstandard
  final int videoDecodedByteCount;

  @DomName('HTMLMediaElement.addTextTrack')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-media-addtexttrack
  @Experimental()
  TextTrack addTextTrack(String kind, [String label, String language]) native;

  @DomName('HTMLMediaElement.canPlayType')
  @DocsEditable()
  @Unstable()
  String canPlayType(String type, [String keySystem]) native;

  @DomName('HTMLMediaElement.load')
  @DocsEditable()
  void load() native;

  @DomName('HTMLMediaElement.pause')
  @DocsEditable()
  void pause() native;

  @DomName('HTMLMediaElement.play')
  @DocsEditable()
  void play() native;

  @DomName('HTMLMediaElement.setMediaKeys')
  @DocsEditable()
  @Experimental() // untriaged
  void setMediaKeys(MediaKeys mediaKeys) native;

  @JSName('webkitAddKey')
  @DomName('HTMLMediaElement.webkitAddKey')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#extensions
  void addKey(String keySystem, Uint8List key, [Uint8List initData, String sessionId]) native;

  @JSName('webkitCancelKeyRequest')
  @DomName('HTMLMediaElement.webkitCancelKeyRequest')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#extensions
  void cancelKeyRequest(String keySystem, String sessionId) native;

  @JSName('webkitGenerateKeyRequest')
  @DomName('HTMLMediaElement.webkitGenerateKeyRequest')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#extensions
  void generateKeyRequest(String keySystem, [Uint8List initData]) native;

  /// Stream of `canplay` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.oncanplay')
  @DocsEditable()
  ElementStream<Event> get onCanPlay => canPlayEvent.forElement(this);

  /// Stream of `canplaythrough` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.oncanplaythrough')
  @DocsEditable()
  ElementStream<Event> get onCanPlayThrough => canPlayThroughEvent.forElement(this);

  /// Stream of `durationchange` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.ondurationchange')
  @DocsEditable()
  ElementStream<Event> get onDurationChange => durationChangeEvent.forElement(this);

  /// Stream of `emptied` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onemptied')
  @DocsEditable()
  ElementStream<Event> get onEmptied => emptiedEvent.forElement(this);

  /// Stream of `ended` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onended')
  @DocsEditable()
  ElementStream<Event> get onEnded => endedEvent.forElement(this);

  /// Stream of `loadeddata` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onloadeddata')
  @DocsEditable()
  ElementStream<Event> get onLoadedData => loadedDataEvent.forElement(this);

  /// Stream of `loadedmetadata` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onloadedmetadata')
  @DocsEditable()
  ElementStream<Event> get onLoadedMetadata => loadedMetadataEvent.forElement(this);

  /// Stream of `loadstart` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onloadstart')
  @DocsEditable()
  ElementStream<Event> get onLoadStart => loadStartEvent.forElement(this);

  /// Stream of `pause` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onpause')
  @DocsEditable()
  ElementStream<Event> get onPause => pauseEvent.forElement(this);

  /// Stream of `play` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onplay')
  @DocsEditable()
  ElementStream<Event> get onPlay => playEvent.forElement(this);

  /// Stream of `playing` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onplaying')
  @DocsEditable()
  ElementStream<Event> get onPlaying => playingEvent.forElement(this);

  /// Stream of `progress` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onprogress')
  @DocsEditable()
  ElementStream<Event> get onProgress => progressEvent.forElement(this);

  /// Stream of `ratechange` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onratechange')
  @DocsEditable()
  ElementStream<Event> get onRateChange => rateChangeEvent.forElement(this);

  /// Stream of `seeked` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onseeked')
  @DocsEditable()
  ElementStream<Event> get onSeeked => seekedEvent.forElement(this);

  /// Stream of `seeking` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onseeking')
  @DocsEditable()
  ElementStream<Event> get onSeeking => seekingEvent.forElement(this);

  /// Stream of `show` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onshow')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#event-media-loadstart
  @Experimental()
  ElementStream<Event> get onShow => showEvent.forElement(this);

  /// Stream of `stalled` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onstalled')
  @DocsEditable()
  ElementStream<Event> get onStalled => stalledEvent.forElement(this);

  /// Stream of `suspend` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onsuspend')
  @DocsEditable()
  ElementStream<Event> get onSuspend => suspendEvent.forElement(this);

  /// Stream of `timeupdate` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.ontimeupdate')
  @DocsEditable()
  ElementStream<Event> get onTimeUpdate => timeUpdateEvent.forElement(this);

  /// Stream of `volumechange` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onvolumechange')
  @DocsEditable()
  ElementStream<Event> get onVolumeChange => volumeChangeEvent.forElement(this);

  /// Stream of `waiting` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onwaiting')
  @DocsEditable()
  ElementStream<Event> get onWaiting => waitingEvent.forElement(this);

  /// Stream of `keyadded` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onwebkitkeyadded')
  @DocsEditable()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  @Experimental()
  ElementStream<MediaKeyEvent> get onKeyAdded => keyAddedEvent.forElement(this);

  /// Stream of `keyerror` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onwebkitkeyerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  @Experimental()
  ElementStream<MediaKeyEvent> get onKeyError => keyErrorEvent.forElement(this);

  /// Stream of `keymessage` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onwebkitkeymessage')
  @DocsEditable()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  @Experimental()
  ElementStream<MediaKeyEvent> get onKeyMessage => keyMessageEvent.forElement(this);

  /// Stream of `needkey` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onwebkitneedkey')
  @DocsEditable()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  @Experimental()
  ElementStream<MediaKeyEvent> get onNeedKey => needKeyEvent.forElement(this);
}
// 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.


@DocsEditable()
@DomName('MediaError')
@Unstable()
class MediaError extends Interceptor native "MediaError" {
  // To suppress missing implicit constructor warnings.
  factory MediaError._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaError.MEDIA_ERR_ABORTED')
  @DocsEditable()
  static const int MEDIA_ERR_ABORTED = 1;

  @DomName('MediaError.MEDIA_ERR_DECODE')
  @DocsEditable()
  static const int MEDIA_ERR_DECODE = 3;

  @DomName('MediaError.MEDIA_ERR_ENCRYPTED')
  @DocsEditable()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#error-codes
  @Experimental()
  static const int MEDIA_ERR_ENCRYPTED = 5;

  @DomName('MediaError.MEDIA_ERR_NETWORK')
  @DocsEditable()
  static const int MEDIA_ERR_NETWORK = 2;

  @DomName('MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED')
  @DocsEditable()
  static const int MEDIA_ERR_SRC_NOT_SUPPORTED = 4;

  @DomName('MediaError.code')
  @DocsEditable()
  final int code;
}
// 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.


@DocsEditable()
@DomName('MediaKeyError')
// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#error-codes
@Experimental()
class MediaKeyError extends Interceptor native "MediaKeyError" {
  // To suppress missing implicit constructor warnings.
  factory MediaKeyError._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaKeyError.MEDIA_KEYERR_CLIENT')
  @DocsEditable()
  static const int MEDIA_KEYERR_CLIENT = 2;

  @DomName('MediaKeyError.MEDIA_KEYERR_DOMAIN')
  @DocsEditable()
  static const int MEDIA_KEYERR_DOMAIN = 6;

  @DomName('MediaKeyError.MEDIA_KEYERR_HARDWARECHANGE')
  @DocsEditable()
  static const int MEDIA_KEYERR_HARDWARECHANGE = 5;

  @DomName('MediaKeyError.MEDIA_KEYERR_OUTPUT')
  @DocsEditable()
  static const int MEDIA_KEYERR_OUTPUT = 4;

  @DomName('MediaKeyError.MEDIA_KEYERR_SERVICE')
  @DocsEditable()
  static const int MEDIA_KEYERR_SERVICE = 3;

  @DomName('MediaKeyError.MEDIA_KEYERR_UNKNOWN')
  @DocsEditable()
  static const int MEDIA_KEYERR_UNKNOWN = 1;

  @DomName('MediaKeyError.code')
  @DocsEditable()
  final int code;

  @DomName('MediaKeyError.systemCode')
  @DocsEditable()
  @Experimental() // non-standard
  final int systemCode;
}
// 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.


@DocsEditable()
@DomName('MediaKeyEvent')
// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#event-definitions
@Experimental()
class MediaKeyEvent extends Event native "MediaKeyEvent" {
  // To suppress missing implicit constructor warnings.
  factory MediaKeyEvent._() { throw new UnsupportedError("Not supported"); }

  @JSName('defaultURL')
  @DomName('MediaKeyEvent.defaultURL')
  @DocsEditable()
  final String defaultUrl;

  @DomName('MediaKeyEvent.errorCode')
  @DocsEditable()
  final MediaKeyError errorCode;

  @DomName('MediaKeyEvent.initData')
  @DocsEditable()
  final Uint8List initData;

  @DomName('MediaKeyEvent.keySystem')
  @DocsEditable()
  final String keySystem;

  @DomName('MediaKeyEvent.message')
  @DocsEditable()
  final Uint8List message;

  @DomName('MediaKeyEvent.sessionId')
  @DocsEditable()
  final String sessionId;

  @DomName('MediaKeyEvent.systemCode')
  @DocsEditable()
  final int systemCode;
}
// 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.


@DocsEditable()
@DomName('MediaKeyMessageEvent')
// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-mediakeymessageevent
@Experimental()
class MediaKeyMessageEvent extends Event native "MediaKeyMessageEvent" {
  // To suppress missing implicit constructor warnings.
  factory MediaKeyMessageEvent._() { throw new UnsupportedError("Not supported"); }

  @JSName('destinationURL')
  @DomName('MediaKeyMessageEvent.destinationURL')
  @DocsEditable()
  final String destinationUrl;

  @DomName('MediaKeyMessageEvent.message')
  @DocsEditable()
  final Uint8List message;
}
// 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.


@DocsEditable()
@DomName('MediaKeyNeededEvent')
// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-mediakeyneededevent
@Experimental()
class MediaKeyNeededEvent extends Event native "MediaKeyNeededEvent" {
  // To suppress missing implicit constructor warnings.
  factory MediaKeyNeededEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaKeyNeededEvent.contentType')
  @DocsEditable()
  @Experimental() // untriaged
  final String contentType;

  @DomName('MediaKeyNeededEvent.initData')
  @DocsEditable()
  final Uint8List initData;
}
// 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.


@DocsEditable()
@DomName('MediaKeySession')
// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-mediakeysession
@Experimental()
class MediaKeySession extends EventTarget native "MediaKeySession" {
  // To suppress missing implicit constructor warnings.
  factory MediaKeySession._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaKeySession.error')
  @DocsEditable()
  final MediaKeyError error;

  @DomName('MediaKeySession.keySystem')
  @DocsEditable()
  final String keySystem;

  @DomName('MediaKeySession.sessionId')
  @DocsEditable()
  final String sessionId;

  @DomName('MediaKeySession.release')
  @DocsEditable()
  @Experimental() // untriaged
  void release() native;

  @DomName('MediaKeySession.update')
  @DocsEditable()
  void update(Uint8List response) native;
}
// 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.


@DocsEditable()
@DomName('MediaKeys')
// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html
@Experimental()
class MediaKeys extends Interceptor native "MediaKeys" {
  // To suppress missing implicit constructor warnings.
  factory MediaKeys._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaKeys.MediaKeys')
  @DocsEditable()
  factory MediaKeys(String keySystem) {
    return MediaKeys._create_1(keySystem);
  }
  static MediaKeys _create_1(keySystem) => JS('MediaKeys', 'new MediaKeys(#)', keySystem);

  @DomName('MediaKeys.keySystem')
  @DocsEditable()
  final String keySystem;

  @DomName('MediaKeys.createSession')
  @DocsEditable()
  MediaKeySession createSession(String type, Uint8List initData) native;
}
// 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.


@DocsEditable()
@DomName('MediaList')
@Unstable()
class MediaList extends Interceptor native "MediaList" {
  // To suppress missing implicit constructor warnings.
  factory MediaList._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaList.length')
  @DocsEditable()
  final int length;

  @DomName('MediaList.mediaText')
  @DocsEditable()
  String mediaText;

  @DomName('MediaList.appendMedium')
  @DocsEditable()
  void appendMedium(String newMedium) native;

  @DomName('MediaList.deleteMedium')
  @DocsEditable()
  void deleteMedium(String oldMedium) native;

  @DomName('MediaList.item')
  @DocsEditable()
  String item(int index) native;
}
// 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.


@DocsEditable()
@DomName('MediaQueryList')
@Unstable()
class MediaQueryList extends Interceptor native "MediaQueryList" {
  // To suppress missing implicit constructor warnings.
  factory MediaQueryList._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaQueryList.matches')
  @DocsEditable()
  final bool matches;

  @DomName('MediaQueryList.media')
  @DocsEditable()
  final String media;
}
// 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.


@DocsEditable()
@DomName('MediaSource')
// https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#mediasource
@Experimental()
class MediaSource extends EventTarget native "MediaSource" {
  // To suppress missing implicit constructor warnings.
  factory MediaSource._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaSource.MediaSource')
  @DocsEditable()
  factory MediaSource() {
    return MediaSource._create_1();
  }
  static MediaSource _create_1() => JS('MediaSource', 'new MediaSource()');

  @DomName('MediaSource.activeSourceBuffers')
  @DocsEditable()
  final SourceBufferList activeSourceBuffers;

  @DomName('MediaSource.duration')
  @DocsEditable()
  num duration;

  @DomName('MediaSource.readyState')
  @DocsEditable()
  final String readyState;

  @DomName('MediaSource.sourceBuffers')
  @DocsEditable()
  final SourceBufferList sourceBuffers;

  @DomName('MediaSource.addSourceBuffer')
  @DocsEditable()
  SourceBuffer addSourceBuffer(String type) native;

  @DomName('MediaSource.endOfStream')
  @DocsEditable()
  void endOfStream([String error]) native;

  @DomName('MediaSource.isTypeSupported')
  @DocsEditable()
  static bool isTypeSupported(String type) native;

  @DomName('MediaSource.removeSourceBuffer')
  @DocsEditable()
  void removeSourceBuffer(SourceBuffer buffer) native;
}
// 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.


@DomName('MediaStream')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html#mediastream
class MediaStream extends EventTarget native "MediaStream" {
  // To suppress missing implicit constructor warnings.
  factory MediaStream._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `addtrack` events to event
   * handlers that are not necessarily instances of [MediaStream].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MediaStream.addtrackEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> addTrackEvent = const EventStreamProvider<Event>('addtrack');

  /**
   * Static factory designed to expose `ended` events to event
   * handlers that are not necessarily instances of [MediaStream].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MediaStream.endedEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');

  /**
   * Static factory designed to expose `removetrack` events to event
   * handlers that are not necessarily instances of [MediaStream].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MediaStream.removetrackEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> removeTrackEvent = const EventStreamProvider<Event>('removetrack');

  @DomName('MediaStream.MediaStream')
  @DocsEditable()
  factory MediaStream([stream_OR_tracks]) {
    if (stream_OR_tracks == null) {
      return MediaStream._create_1();
    }
    if ((stream_OR_tracks is MediaStream || stream_OR_tracks == null)) {
      return MediaStream._create_2(stream_OR_tracks);
    }
    if ((stream_OR_tracks is List<MediaStreamTrack> || stream_OR_tracks == null)) {
      return MediaStream._create_3(stream_OR_tracks);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static MediaStream _create_1() => JS('MediaStream', 'new MediaStream()');
  static MediaStream _create_2(stream_OR_tracks) => JS('MediaStream', 'new MediaStream(#)', stream_OR_tracks);
  static MediaStream _create_3(stream_OR_tracks) => JS('MediaStream', 'new MediaStream(#)', stream_OR_tracks);

  @DomName('MediaStream.ended')
  @DocsEditable()
  final bool ended;

  @DomName('MediaStream.id')
  @DocsEditable()
  final String id;

  @DomName('MediaStream.label')
  @DocsEditable()
  @Experimental() // non-standard
  final String label;

  @DomName('MediaStream.addTrack')
  @DocsEditable()
  void addTrack(MediaStreamTrack track) native;

  @DomName('MediaStream.getAudioTracks')
  @DocsEditable()
  @Creates('JSExtendableArray')
  @Returns('JSExtendableArray')
  List<MediaStreamTrack> getAudioTracks() native;

  @DomName('MediaStream.getTrackById')
  @DocsEditable()
  MediaStreamTrack getTrackById(String trackId) native;

  @DomName('MediaStream.getVideoTracks')
  @DocsEditable()
  @Creates('JSExtendableArray')
  @Returns('JSExtendableArray')
  List<MediaStreamTrack> getVideoTracks() native;

  @DomName('MediaStream.removeTrack')
  @DocsEditable()
  void removeTrack(MediaStreamTrack track) native;

  @DomName('MediaStream.stop')
  @DocsEditable()
  void stop() native;

  /// Stream of `addtrack` events handled by this [MediaStream].
  @DomName('MediaStream.onaddtrack')
  @DocsEditable()
  Stream<Event> get onAddTrack => addTrackEvent.forTarget(this);

  /// Stream of `ended` events handled by this [MediaStream].
  @DomName('MediaStream.onended')
  @DocsEditable()
  Stream<Event> get onEnded => endedEvent.forTarget(this);

  /// Stream of `removetrack` events handled by this [MediaStream].
  @DomName('MediaStream.onremovetrack')
  @DocsEditable()
  Stream<Event> get onRemoveTrack => removeTrackEvent.forTarget(this);


  /**
   * Checks if the MediaStream APIs are supported on the current platform.
   *
   * See also:
   *
   * * [Navigator.getUserMedia]
   */
  static bool get supported =>
    JS('bool', '''!!(#.getUserMedia || #.webkitGetUserMedia ||
        #.mozGetUserMedia || #.msGetUserMedia)''',
        window.navigator,
        window.navigator,
        window.navigator,
        window.navigator);
}
// 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.


@DocsEditable()
@DomName('MediaStreamEvent')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html
class MediaStreamEvent extends Event native "MediaStreamEvent" {
  // To suppress missing implicit constructor warnings.
  factory MediaStreamEvent._() { throw new UnsupportedError("Not supported"); }

  /// Checks if this type is supported on the current platform.
  static bool get supported => Device.isEventTypeSupported('MediaStreamEvent');

  @DomName('MediaStreamEvent.stream')
  @DocsEditable()
  final MediaStream stream;
}
// 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.


@DocsEditable()
@DomName('MediaStreamTrack')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html#mediastreamtrack
class MediaStreamTrack extends EventTarget native "MediaStreamTrack" {
  // To suppress missing implicit constructor warnings.
  factory MediaStreamTrack._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `ended` events to event
   * handlers that are not necessarily instances of [MediaStreamTrack].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MediaStreamTrack.endedEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');

  /**
   * Static factory designed to expose `mute` events to event
   * handlers that are not necessarily instances of [MediaStreamTrack].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MediaStreamTrack.muteEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> muteEvent = const EventStreamProvider<Event>('mute');

  /**
   * Static factory designed to expose `unmute` events to event
   * handlers that are not necessarily instances of [MediaStreamTrack].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MediaStreamTrack.unmuteEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> unmuteEvent = const EventStreamProvider<Event>('unmute');

  @DomName('MediaStreamTrack.enabled')
  @DocsEditable()
  bool enabled;

  @DomName('MediaStreamTrack.id')
  @DocsEditable()
  final String id;

  @DomName('MediaStreamTrack.kind')
  @DocsEditable()
  final String kind;

  @DomName('MediaStreamTrack.label')
  @DocsEditable()
  final String label;

  @DomName('MediaStreamTrack.readyState')
  @DocsEditable()
  final String readyState;

  @JSName('getSources')
  @DomName('MediaStreamTrack.getSources')
  @DocsEditable()
  @Experimental() // untriaged
  static void _getSources(MediaStreamTrackSourcesCallback callback) native;

  @JSName('getSources')
  @DomName('MediaStreamTrack.getSources')
  @DocsEditable()
  @Experimental() // untriaged
  static Future<List<SourceInfo>> getSources() {
    var completer = new Completer<List<SourceInfo>>();
    _getSources(
        (value) { completer.complete(value); });
    return completer.future;
  }

  @DomName('MediaStreamTrack.stop')
  @DocsEditable()
  @Experimental() // untriaged
  void stop() native;

  /// Stream of `ended` events handled by this [MediaStreamTrack].
  @DomName('MediaStreamTrack.onended')
  @DocsEditable()
  Stream<Event> get onEnded => endedEvent.forTarget(this);

  /// Stream of `mute` events handled by this [MediaStreamTrack].
  @DomName('MediaStreamTrack.onmute')
  @DocsEditable()
  Stream<Event> get onMute => muteEvent.forTarget(this);

  /// Stream of `unmute` events handled by this [MediaStreamTrack].
  @DomName('MediaStreamTrack.onunmute')
  @DocsEditable()
  Stream<Event> get onUnmute => unmuteEvent.forTarget(this);
}
// 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.


@DocsEditable()
@DomName('MediaStreamTrackEvent')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html
class MediaStreamTrackEvent extends Event native "MediaStreamTrackEvent" {
  // To suppress missing implicit constructor warnings.
  factory MediaStreamTrackEvent._() { throw new UnsupportedError("Not supported"); }

  /// Checks if this type is supported on the current platform.
  static bool get supported => Device.isEventTypeSupported('MediaStreamTrackEvent');

  @DomName('MediaStreamTrackEvent.track')
  @DocsEditable()
  final MediaStreamTrack track;
}
// 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.


@DomName('MediaStreamTrackSourcesCallback')
@Experimental() // untriaged
typedef void MediaStreamTrackSourcesCallback(List<SourceInfo> sources);
// 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.


@DocsEditable()
@DomName('MemoryInfo')
@Experimental() // nonstandard
class MemoryInfo extends Interceptor native "MemoryInfo" {
  // To suppress missing implicit constructor warnings.
  factory MemoryInfo._() { throw new UnsupportedError("Not supported"); }

  @DomName('MemoryInfo.jsHeapSizeLimit')
  @DocsEditable()
  final int jsHeapSizeLimit;

  @DomName('MemoryInfo.totalJSHeapSize')
  @DocsEditable()
  final int totalJSHeapSize;

  @DomName('MemoryInfo.usedJSHeapSize')
  @DocsEditable()
  final int usedJSHeapSize;
}
// 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.


@DocsEditable()
/**
 * An HTML <menu> element.
 *
 * A <menu> element represents an unordered list of menu commands.
 *
 * See also:
 *
 *  * [Menu Element](https://developer.mozilla.org/en-US/docs/HTML/Element/menu) from MDN.
 *  * [Menu Element](http://www.w3.org/TR/html5/the-menu-element.html#the-menu-element) from the W3C.
 */
@DomName('HTMLMenuElement')
class MenuElement extends HtmlElement native "HTMLMenuElement" {
  // To suppress missing implicit constructor warnings.
  factory MenuElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLMenuElement.HTMLMenuElement')
  @DocsEditable()
  factory MenuElement() => document.createElement("menu");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  MenuElement.created() : super.created();
}
// 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.


@DocsEditable()
@DomName('MessageChannel')
@Unstable()
class MessageChannel extends Interceptor native "MessageChannel" {
  // To suppress missing implicit constructor warnings.
  factory MessageChannel._() { throw new UnsupportedError("Not supported"); }

  @DomName('MessageChannel.port1')
  @DocsEditable()
  final MessagePort port1;

  @DomName('MessageChannel.port2')
  @DocsEditable()
  final MessagePort port2;
}
// 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.

// WARNING: Do not edit - generated code.


@DomName('MessageEvent')
class MessageEvent extends Event native "MessageEvent" {
  factory MessageEvent(String type,
      {bool canBubble: false, bool cancelable: false, Object data,
      String origin, String lastEventId,
      Window source, List messagePorts}) {
    if (source == null) {
      source = window;
    }
    var event = document._createEvent("MessageEvent");
    event._initMessageEvent(type, canBubble, cancelable, data, origin,
        lastEventId, source, messagePorts);
    return event;
  }
  // To suppress missing implicit constructor warnings.
  factory MessageEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('MessageEvent.data')
  @DocsEditable()
  dynamic get data => convertNativeToDart_SerializedScriptValue(this._get_data);
  @JSName('data')
  @DomName('MessageEvent.data')
  @DocsEditable()
  @annotation_Creates_SerializedScriptValue
  @annotation_Returns_SerializedScriptValue
  final dynamic _get_data;

  @DomName('MessageEvent.lastEventId')
  @DocsEditable()
  @Unstable()
  final String lastEventId;

  @DomName('MessageEvent.origin')
  @DocsEditable()
  final String origin;

  @DomName('MessageEvent.source')
  @DocsEditable()
  EventTarget get source => _convertNativeToDart_EventTarget(this._get_source);
  @JSName('source')
  @DomName('MessageEvent.source')
  @DocsEditable()
  @Creates('Null')
  @Returns('EventTarget|=Object')
  final dynamic _get_source;

  @JSName('initMessageEvent')
  @DomName('MessageEvent.initMessageEvent')
  @DocsEditable()
  void _initMessageEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Object dataArg, String originArg, String lastEventIdArg, Window sourceArg, List<MessagePort> messagePorts) native;

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


@DocsEditable()
@DomName('MessagePort')
@Unstable()
class MessagePort extends EventTarget native "MessagePort" {
  // To suppress missing implicit constructor warnings.
  factory MessagePort._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [MessagePort].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MessagePort.messageEvent')
  @DocsEditable()
  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');

  @DomName('MessagePort.close')
  @DocsEditable()
  void close() native;

  @DomName('MessagePort.postMessage')
  @DocsEditable()
  void postMessage(/*any*/ message, [List<MessagePort> messagePorts]) {
    if (messagePorts != null) {
      var message_1 = convertDartToNative_SerializedScriptValue(message);
      _postMessage_1(message_1, messagePorts);
      return;
    }
    var message_2 = convertDartToNative_SerializedScriptValue(message);
    _postMessage_2(message_2);
    return;
  }
  @JSName('postMessage')
  @DomName('MessagePort.postMessage')
  @DocsEditable()
  void _postMessage_1(message, List<MessagePort> messagePorts) native;
  @JSName('postMessage')
  @DomName('MessagePort.postMessage')
  @DocsEditable()
  void _postMessage_2(message) native;

  @DomName('MessagePort.start')
  @DocsEditable()
  void start() native;

  /// Stream of `message` events handled by this [MessagePort].
  @DomName('MessagePort.onmessage')
  @DocsEditable()
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
}
// 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.


@DocsEditable()
@DomName('HTMLMetaElement')
class MetaElement extends HtmlElement native "HTMLMetaElement" {
  // To suppress missing implicit constructor warnings.
  factory MetaElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLMetaElement.HTMLMetaElement')
  @DocsEditable()
  factory MetaElement() => document.createElement("meta");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  MetaElement.created() : super.created();

  @DomName('HTMLMetaElement.content')
  @DocsEditable()
  String content;

  @DomName('HTMLMetaElement.httpEquiv')
  @DocsEditable()
  String httpEquiv;

  @DomName('HTMLMetaElement.name')
  @DocsEditable()
  String name;
}
// 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.


@DocsEditable()
@DomName('Metadata')
// http://www.w3.org/TR/file-system-api/#the-metadata-interface
@Experimental()
class Metadata extends Interceptor native "Metadata" {
  // To suppress missing implicit constructor warnings.
  factory Metadata._() { throw new UnsupportedError("Not supported"); }

  @DomName('Metadata.modificationTime')
  @DocsEditable()
  DateTime get modificationTime => convertNativeToDart_DateTime(this._get_modificationTime);
  @JSName('modificationTime')
  @DomName('Metadata.modificationTime')
  @DocsEditable()
  @Creates('Null')
  final dynamic _get_modificationTime;

  @DomName('Metadata.size')
  @DocsEditable()
  final int size;
}
// 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.


@DomName('MetadataCallback')
// http://www.w3.org/TR/file-system-api/#idl-def-MetadataCallback
@Experimental()
typedef void MetadataCallback(Metadata metadata);
// 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.


@DocsEditable()
@DomName('HTMLMeterElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
class MeterElement extends HtmlElement native "HTMLMeterElement" {
  // To suppress missing implicit constructor warnings.
  factory MeterElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLMeterElement.HTMLMeterElement')
  @DocsEditable()
  factory MeterElement() => document.createElement("meter");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  MeterElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('meter');

  @DomName('HTMLMeterElement.high')
  @DocsEditable()
  num high;

  @DomName('HTMLMeterElement.labels')
  @DocsEditable()
  @Unstable()
  @Returns('NodeList')
  @Creates('NodeList')
  final List<Node> labels;

  @DomName('HTMLMeterElement.low')
  @DocsEditable()
  num low;

  @DomName('HTMLMeterElement.max')
  @DocsEditable()
  num max;

  @DomName('HTMLMeterElement.min')
  @DocsEditable()
  num min;

  @DomName('HTMLMeterElement.optimum')
  @DocsEditable()
  num optimum;

  @DomName('HTMLMeterElement.value')
  @DocsEditable()
  num value;
}
// 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.


@DocsEditable()
@DomName('MIDIAccess')
// http://webaudio.github.io/web-midi-api/#midiaccess-interface
@Experimental()
class MidiAccess extends EventTarget native "MIDIAccess" {
  // To suppress missing implicit constructor warnings.
  factory MidiAccess._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `connect` events to event
   * handlers that are not necessarily instances of [MidiAccess].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MIDIAccess.connectEvent')
  @DocsEditable()
  static const EventStreamProvider<MidiConnectionEvent> connectEvent = const EventStreamProvider<MidiConnectionEvent>('connect');

  /**
   * Static factory designed to expose `disconnect` events to event
   * handlers that are not necessarily instances of [MidiAccess].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MIDIAccess.disconnectEvent')
  @DocsEditable()
  static const EventStreamProvider<MidiConnectionEvent> disconnectEvent = const EventStreamProvider<MidiConnectionEvent>('disconnect');

  @DomName('MIDIAccess.inputs')
  @DocsEditable()
  List<MidiInput> inputs() native;

  @DomName('MIDIAccess.outputs')
  @DocsEditable()
  List<MidiOutput> outputs() native;

  /// Stream of `connect` events handled by this [MidiAccess].
  @DomName('MIDIAccess.onconnect')
  @DocsEditable()
  Stream<MidiConnectionEvent> get onConnect => connectEvent.forTarget(this);

  /// Stream of `disconnect` events handled by this [MidiAccess].
  @DomName('MIDIAccess.ondisconnect')
  @DocsEditable()
  Stream<MidiConnectionEvent> get onDisconnect => disconnectEvent.forTarget(this);
}
// 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.


@DocsEditable()
@DomName('MIDIAccessPromise')
@Experimental() // untriaged
class MidiAccessPromise extends Interceptor native "MIDIAccessPromise" {
  // To suppress missing implicit constructor warnings.
  factory MidiAccessPromise._() { throw new UnsupportedError("Not supported"); }

  @DomName('MIDIAccessPromise.then')
  @DocsEditable()
  @Experimental() // untriaged
  void then(MidiSuccessCallback successCallback, MidiErrorCallback errorCallback) native;
}
// 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.


@DocsEditable()
@DomName('MIDIConnectionEvent')
// http://webaudio.github.io/web-midi-api/#midiconnectionevent-interface
@Experimental()
class MidiConnectionEvent extends Event native "MIDIConnectionEvent" {
  // To suppress missing implicit constructor warnings.
  factory MidiConnectionEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('MIDIConnectionEvent.port')
  @DocsEditable()
  final MidiPort port;
}
// 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.


@DocsEditable()
@DomName('MIDIInput')
// http://webaudio.github.io/web-midi-api/#idl-def-MIDIInput
@Experimental()
class MidiInput extends MidiPort native "MIDIInput" {
  // To suppress missing implicit constructor warnings.
  factory MidiInput._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `midimessage` events to event
   * handlers that are not necessarily instances of [MidiInput].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MIDIInput.midimessageEvent')
  @DocsEditable()
  static const EventStreamProvider<MidiMessageEvent> midiMessageEvent = const EventStreamProvider<MidiMessageEvent>('midimessage');

  /// Stream of `midimessage` events handled by this [MidiInput].
  @DomName('MIDIInput.onmidimessage')
  @DocsEditable()
  Stream<MidiMessageEvent> get onMidiMessage => midiMessageEvent.forTarget(this);
}
// 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.


@DocsEditable()
@DomName('MIDIMessageEvent')
// http://webaudio.github.io/web-midi-api/#midimessageevent-interface
@Experimental()
class MidiMessageEvent extends Event native "MIDIMessageEvent" {
  // To suppress missing implicit constructor warnings.
  factory MidiMessageEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('MIDIMessageEvent.data')
  @DocsEditable()
  final Uint8List data;

  @DomName('MIDIMessageEvent.receivedTime')
  @DocsEditable()
  final double receivedTime;
}
// 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.


@DocsEditable()
@DomName('MIDIOutput')
// http://webaudio.github.io/web-midi-api/#midioutput-interface
@Experimental()
class MidiOutput extends MidiPort native "MIDIOutput" {
  // To suppress missing implicit constructor warnings.
  factory MidiOutput._() { throw new UnsupportedError("Not supported"); }

  @DomName('MIDIOutput.send')
  @DocsEditable()
  void send(Uint8List data, [num timestamp]) native;
}
// 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.


@DocsEditable()
@DomName('MIDIPort')
// http://webaudio.github.io/web-midi-api/#idl-def-MIDIPort
@Experimental()
class MidiPort extends EventTarget native "MIDIPort" {
  // To suppress missing implicit constructor warnings.
  factory MidiPort._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `disconnect` events to event
   * handlers that are not necessarily instances of [MidiPort].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MIDIPort.disconnectEvent')
  @DocsEditable()
  static const EventStreamProvider<MidiConnectionEvent> disconnectEvent = const EventStreamProvider<MidiConnectionEvent>('disconnect');

  @DomName('MIDIPort.id')
  @DocsEditable()
  final String id;

  @DomName('MIDIPort.manufacturer')
  @DocsEditable()
  final String manufacturer;

  @DomName('MIDIPort.name')
  @DocsEditable()
  final String name;

  @DomName('MIDIPort.type')
  @DocsEditable()
  final String type;

  @DomName('MIDIPort.version')
  @DocsEditable()
  final String version;

  /// Stream of `disconnect` events handled by this [MidiPort].
  @DomName('MIDIPort.ondisconnect')
  @DocsEditable()
  Stream<MidiConnectionEvent> get onDisconnect => disconnectEvent.forTarget(this);
}
// 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.


@DocsEditable()
@DomName('MimeType')
@Experimental() // non-standard
class MimeType extends Interceptor native "MimeType" {
  // To suppress missing implicit constructor warnings.
  factory MimeType._() { throw new UnsupportedError("Not supported"); }

  @DomName('MimeType.description')
  @DocsEditable()
  final String description;

  @DomName('MimeType.enabledPlugin')
  @DocsEditable()
  final Plugin enabledPlugin;

  @DomName('MimeType.suffixes')
  @DocsEditable()
  final String suffixes;

  @DomName('MimeType.type')
  @DocsEditable()
  final String type;
}
// 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.


@DocsEditable()
@DomName('MimeTypeArray')
@Experimental() // non-standard
class MimeTypeArray extends Interceptor with ListMixin<MimeType>, ImmutableListMixin<MimeType> implements JavaScriptIndexingBehavior, List<MimeType> native "MimeTypeArray" {
  // To suppress missing implicit constructor warnings.
  factory MimeTypeArray._() { throw new UnsupportedError("Not supported"); }

  @DomName('MimeTypeArray.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  MimeType operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("MimeType", "#[#]", this, index);
  }
  void operator[]=(int index, MimeType value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<MimeType> mixins.
  // MimeType is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  MimeType get first {
    if (this.length > 0) {
      return JS('MimeType', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  MimeType get last {
    int len = this.length;
    if (len > 0) {
      return JS('MimeType', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  MimeType get single {
    int len = this.length;
    if (len == 1) {
      return JS('MimeType', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  MimeType elementAt(int index) => this[index];
  // -- end List<MimeType> mixins.

  @DomName('MimeTypeArray.__getter__')
  @DocsEditable()
  MimeType __getter__(String name) native;

  @DomName('MimeTypeArray.item')
  @DocsEditable()
  MimeType item(int index) native;

  @DomName('MimeTypeArray.namedItem')
  @DocsEditable()
  MimeType namedItem(String name) native;
}
// 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.


@DocsEditable()
@DomName('HTMLModElement')
@Unstable()
class ModElement extends HtmlElement native "HTMLModElement" {
  // To suppress missing implicit constructor warnings.
  factory ModElement._() { throw new UnsupportedError("Not supported"); }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ModElement.created() : super.created();

  @DomName('HTMLModElement.cite')
  @DocsEditable()
  String cite;

  @DomName('HTMLModElement.dateTime')
  @DocsEditable()
  String dateTime;
}
// 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.


@DomName('MouseEvent')
class MouseEvent extends UIEvent native "MouseEvent,DragEvent,PointerEvent,MSPointerEvent" {
  factory MouseEvent(String type,
      {Window view, int detail: 0, int screenX: 0, int screenY: 0,
      int clientX: 0, int clientY: 0, int button: 0, bool canBubble: true,
      bool cancelable: true, bool ctrlKey: false, bool altKey: false,
      bool shiftKey: false, bool metaKey: false, EventTarget relatedTarget}) {

    if (view == null) {
      view = window;
    }
    var event = document._createEvent('MouseEvent');
    event._initMouseEvent(type, canBubble, cancelable, view, detail,
        screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey,
        button, relatedTarget);
    return event;
  }
  // To suppress missing implicit constructor warnings.
  factory MouseEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('MouseEvent.altKey')
  @DocsEditable()
  final bool altKey;

  @DomName('MouseEvent.button')
  @DocsEditable()
  final int button;

  @JSName('clientX')
  @DomName('MouseEvent.clientX')
  @DocsEditable()
  final int _clientX;

  @JSName('clientY')
  @DomName('MouseEvent.clientY')
  @DocsEditable()
  final int _clientY;

  @DomName('MouseEvent.ctrlKey')
  @DocsEditable()
  final bool ctrlKey;

  @DomName('MouseEvent.dataTransfer')
  @DocsEditable()
  @Unstable()
  final DataTransfer dataTransfer;

  @DomName('MouseEvent.fromElement')
  @DocsEditable()
  @Experimental() // nonstandard
  final Node fromElement;

  @DomName('MouseEvent.metaKey')
  @DocsEditable()
  final bool metaKey;

  @DomName('MouseEvent.relatedTarget')
  @DocsEditable()
  EventTarget get relatedTarget => _convertNativeToDart_EventTarget(this._get_relatedTarget);
  @JSName('relatedTarget')
  @DomName('MouseEvent.relatedTarget')
  @DocsEditable()
  @Creates('Node')
  @Returns('EventTarget|=Object')
  final dynamic _get_relatedTarget;

  @JSName('screenX')
  @DomName('MouseEvent.screenX')
  @DocsEditable()
  final int _screenX;

  @JSName('screenY')
  @DomName('MouseEvent.screenY')
  @DocsEditable()
  final int _screenY;

  @DomName('MouseEvent.shiftKey')
  @DocsEditable()
  final bool shiftKey;

  @DomName('MouseEvent.toElement')
  @DocsEditable()
  @Experimental() // nonstandard
  final Node toElement;

  @JSName('webkitMovementX')
  @DomName('MouseEvent.webkitMovementX')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  final int _webkitMovementX;

  @JSName('webkitMovementY')
  @DomName('MouseEvent.webkitMovementY')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  final int _webkitMovementY;

  @DomName('MouseEvent.initMouseEvent')
  @DocsEditable()
  void _initMouseEvent(String type, bool canBubble, bool cancelable, Window view, int detail, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, int button, EventTarget relatedTarget) {
    var relatedTarget_1 = _convertDartToNative_EventTarget(relatedTarget);
    _initMouseEvent_1(type, canBubble, cancelable, view, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget_1);
    return;
  }
  @JSName('initMouseEvent')
  @DomName('MouseEvent.initMouseEvent')
  @DocsEditable()
  void _initMouseEvent_1(type, canBubble, cancelable, Window view, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget) native;


  @DomName('MouseEvent.clientX')
  @DomName('MouseEvent.clientY')
  Point get client => new Point(_clientX, _clientY);

  @DomName('MouseEvent.movementX')
  @DomName('MouseEvent.movementY')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  Point get movement => new Point(_webkitMovementX, _webkitMovementY);

  /**
   * The coordinates of the mouse pointer in target node coordinates.
   *
   * This value may vary between platforms if the target node moves
   * after the event has fired or if the element has CSS transforms affecting
   * it.
   */
  Point get offset {
    if (JS('bool', '!!#.offsetX', this)) {
      var x = JS('int', '#.offsetX', this);
      var y = JS('int', '#.offsetY', this);
      return new Point(x, y);
    } else {
      // Firefox does not support offsetX.
      if (!(this.target is Element)) {
        throw new UnsupportedError(
            'offsetX is only supported on elements');
      }
      Element target = this.target;
      var point = (this.client - target.getBoundingClientRect().topLeft);
      return new Point(point.x.toInt(), point.y.toInt());
    }
  }

  @DomName('MouseEvent.screenX')
  @DomName('MouseEvent.screenY')
  Point get screen => new Point(_screenX, _screenY);
}
// 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.


@DomName('MutationCallback')
typedef void MutationCallback(List<MutationRecord> mutations, MutationObserver observer);
// 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.


@DomName('MutationObserver')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
class MutationObserver extends Interceptor native "MutationObserver,WebKitMutationObserver" {

  @DomName('MutationObserver.disconnect')
  @DocsEditable()
  void disconnect() native;

  @DomName('MutationObserver.observe')
  @DocsEditable()
  void _observe(Node target, Map options) {
    var options_1 = convertDartToNative_Dictionary(options);
    _observe_1(target, options_1);
    return;
  }
  @JSName('observe')
  @DomName('MutationObserver.observe')
  @DocsEditable()
  void _observe_1(Node target, options) native;

  @DomName('MutationObserver.takeRecords')
  @DocsEditable()
  List<MutationRecord> takeRecords() native;

  /**
   * Checks to see if the mutation observer API is supported on the current
   * platform.
   */
  static bool get supported {
    return JS('bool',
        '!!(window.MutationObserver || window.WebKitMutationObserver)');
  }

  /**
   * Observes the target for the specified changes.
   *
   * Some requirements for the optional parameters:
   *
   * * Either childList, attributes or characterData must be true.
   * * If attributeOldValue is true then attributes must also be true.
   * * If attributeFilter is specified then attributes must be true.
   * * If characterDataOldValue is true then characterData must be true.
   */
  void observe(Node target,
               {bool childList,
                bool attributes,
                bool characterData,
                bool subtree,
                bool attributeOldValue,
                bool characterDataOldValue,
                List<String> attributeFilter}) {

    // Parse options into map of known type.
    var parsedOptions = _createDict();

    // Override options passed in the map with named optional arguments.
    override(key, value) {
      if (value != null) _add(parsedOptions, key, value);
    }

    override('childList', childList);
    override('attributes', attributes);
    override('characterData', characterData);
    override('subtree', subtree);
    override('attributeOldValue', attributeOldValue);
    override('characterDataOldValue', characterDataOldValue);
    if (attributeFilter != null) {
      override('attributeFilter', _fixupList(attributeFilter));
    }

    _call(target, parsedOptions);
  }

   // TODO: Change to a set when const Sets are available.
  static final _boolKeys =
    const {'childList': true,
           'attributes': true,
           'characterData': true,
           'subtree': true,
           'attributeOldValue': true,
           'characterDataOldValue': true };


  static _createDict() => JS('var', '{}');
  static _add(m, String key, value) { JS('void', '#[#] = #', m, key, value); }
  static _fixupList(list) => list;  // TODO: Ensure is a JavaScript Array.

  // Call native function with no conversions.
  @JSName('observe')
  void _call(target, options) native;

  factory MutationObserver(MutationCallback callback) {
    // Dummy statement to mark types as instantiated.
    JS('MutationObserver|MutationRecord', '0');

    return JS('MutationObserver',
        'new(window.MutationObserver||window.WebKitMutationObserver||'
        'window.MozMutationObserver)(#)',
        convertDartClosureToJS(_wrapBinaryZone(callback), 2));
  }
}
// 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.


@DocsEditable()
@DomName('MutationRecord')
class MutationRecord extends Interceptor native "MutationRecord" {
  // To suppress missing implicit constructor warnings.
  factory MutationRecord._() { throw new UnsupportedError("Not supported"); }

  @DomName('MutationRecord.addedNodes')
  @DocsEditable()
  @Returns('NodeList')
  @Creates('NodeList')
  final List<Node> addedNodes;

  @DomName('MutationRecord.attributeName')
  @DocsEditable()
  final String attributeName;

  @DomName('MutationRecord.attributeNamespace')
  @DocsEditable()
  final String attributeNamespace;

  @DomName('MutationRecord.nextSibling')
  @DocsEditable()
  final Node nextSibling;

  @DomName('MutationRecord.oldValue')
  @DocsEditable()
  final String oldValue;

  @DomName('MutationRecord.previousSibling')
  @DocsEditable()
  final Node previousSibling;

  @DomName('MutationRecord.removedNodes')
  @DocsEditable()
  @Returns('NodeList')
  @Creates('NodeList')
  final List<Node> removedNodes;

  @DomName('MutationRecord.target')
  @DocsEditable()
  final Node target;

  @DomName('MutationRecord.type')
  @DocsEditable()
  final String type;
}
// 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.


@DomName('Navigator')
class Navigator extends Interceptor implements NavigatorOnLine, NavigatorID native "Navigator" {

  @DomName('Navigator.language')
  String get language => JS('String', '#.language || #.userLanguage', this,
      this);

  /**
   * Gets a stream (video and or audio) from the local computer.
   *
   * Use [MediaStream.supported] to check if this is supported by the current
   * platform. The arguments `audio` and `video` default to `false` (stream does
   * not use audio or video, respectively).
   *
   * Simple example usage:
   *
   *     window.navigator.getUserMedia(audio: true, video: true).then((stream) {
   *       var video = new VideoElement()
   *         ..autoplay = true
   *         ..src = Url.createObjectUrlFromStream(stream);
   *       document.body.append(video);
   *     });
   *
   * The user can also pass in Maps to the audio or video parameters to specify
   * mandatory and optional constraints for the media stream. Not passing in a
   * map, but passing in `true` will provide a MediaStream with audio or
   * video capabilities, but without any additional constraints. The particular
   * constraint names for audio and video are still in flux, but as of this
   * writing, here is an example providing more constraints.
   *
   *     window.navigator.getUserMedia(
   *         audio: true,
   *         video: {'mandatory':
   *                    { 'minAspectRatio': 1.333, 'maxAspectRatio': 1.334 },
   *                 'optional':
   *                    [{ 'minFrameRate': 60 },
   *                     { 'maxWidth': 640 }]
   *     });
   *
   * See also:
   * * [MediaStream.supported]
   */
  @DomName('Navigator.webkitGetUserMedia')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @Experimental()
  Future<MediaStream> getUserMedia({audio: false, video: false}) {
    var completer = new Completer<MediaStream>();
    var options = {
      'audio': audio,
      'video': video
    };
    _ensureGetUserMedia();
    this._getUserMedia(convertDartToNative_SerializedScriptValue(options),
      (stream) {
        completer.complete(stream);
      },
      (error) {
        completer.completeError(error);
      });
    return completer.future;
  }

  _ensureGetUserMedia() {
    if (JS('bool', '!(#.getUserMedia)', this)) {
      JS('void', '#.getUserMedia = '
          '(#.getUserMedia || #.webkitGetUserMedia || #.mozGetUserMedia ||'
          '#.msGetUserMedia)', this, this, this, this, this);
    }
  }

  @JSName('getUserMedia')
  void _getUserMedia(options, _NavigatorUserMediaSuccessCallback success,
      _NavigatorUserMediaErrorCallback error) native;

  // To suppress missing implicit constructor warnings.
  factory Navigator._() { throw new UnsupportedError("Not supported"); }

  @DomName('Navigator.cookieEnabled')
  @DocsEditable()
  @Unstable()
  final bool cookieEnabled;

  @DomName('Navigator.doNotTrack')
  @DocsEditable()
  // http://www.w3.org/2011/tracking-protection/drafts/tracking-dnt.html#js-dom
  @Experimental() // experimental
  final String doNotTrack;

  @DomName('Navigator.geolocation')
  @DocsEditable()
  @Unstable()
  final Geolocation geolocation;

  @DomName('Navigator.maxTouchPoints')
  @DocsEditable()
  @Experimental() // untriaged
  final int maxTouchPoints;

  @DomName('Navigator.mimeTypes')
  @DocsEditable()
  @Experimental() // nonstandard
  final MimeTypeArray mimeTypes;

  @DomName('Navigator.productSub')
  @DocsEditable()
  @Unstable()
  final String productSub;

  @DomName('Navigator.serviceWorker')
  @DocsEditable()
  @Experimental() // untriaged
  final ServiceWorkerContainer serviceWorker;

  @DomName('Navigator.storageQuota')
  @DocsEditable()
  @Experimental() // untriaged
  final StorageQuota storageQuota;

  @DomName('Navigator.vendor')
  @DocsEditable()
  @Unstable()
  final String vendor;

  @DomName('Navigator.vendorSub')
  @DocsEditable()
  @Unstable()
  final String vendorSub;

  @JSName('webkitPersistentStorage')
  @DomName('Navigator.webkitPersistentStorage')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.w3.org/TR/quota-api/#accessing-storagequota
  final DeprecatedStorageQuota persistentStorage;

  @JSName('webkitTemporaryStorage')
  @DomName('Navigator.webkitTemporaryStorage')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.w3.org/TR/quota-api/#accessing-storagequota
  final DeprecatedStorageQuota temporaryStorage;

  @DomName('Navigator.getStorageUpdates')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#navigatorstorageutils
  @Experimental()
  void getStorageUpdates() native;

  @DomName('Navigator.isProtocolHandlerRegistered')
  @DocsEditable()
  @Experimental() // untriaged
  String isProtocolHandlerRegistered(String scheme, String url) native;

  @DomName('Navigator.registerProtocolHandler')
  @DocsEditable()
  @Unstable()
  void registerProtocolHandler(String scheme, String url, String title) native;

  @DomName('Navigator.requestMIDIAccess')
  @DocsEditable()
  @Experimental() // untriaged
  MidiAccessPromise requestMidiAccess([Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _requestMidiAccess_1(options_1);
    }
    return _requestMidiAccess_2();
  }
  @JSName('requestMIDIAccess')
  @DomName('Navigator.requestMIDIAccess')
  @DocsEditable()
  @Experimental() // untriaged
  MidiAccessPromise _requestMidiAccess_1(options) native;
  @JSName('requestMIDIAccess')
  @DomName('Navigator.requestMIDIAccess')
  @DocsEditable()
  @Experimental() // untriaged
  MidiAccessPromise _requestMidiAccess_2() native;

  @DomName('Navigator.unregisterProtocolHandler')
  @DocsEditable()
  @Experimental() // untriaged
  void unregisterProtocolHandler(String scheme, String url) native;

  @JSName('webkitGetGamepads')
  @DomName('Navigator.webkitGetGamepads')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/gamepad/raw-file/default/gamepad.html#widl-Navigator-getGamepads-Gamepad
  @Returns('_GamepadList')
  @Creates('_GamepadList')
  List<Gamepad> getGamepads() native;

  // From NavigatorID

  @DomName('Navigator.appCodeName')
  @DocsEditable()
  @Experimental() // non-standard
  final String appCodeName;

  @DomName('Navigator.appName')
  @DocsEditable()
  final String appName;

  @DomName('Navigator.appVersion')
  @DocsEditable()
  final String appVersion;

  @DomName('Navigator.platform')
  @DocsEditable()
  final String platform;

  @DomName('Navigator.product')
  @DocsEditable()
  @Unstable()
  final String product;

  @DomName('Navigator.userAgent')
  @DocsEditable()
  final String userAgent;

  // From NavigatorOnLine

  @DomName('Navigator.onLine')
  @DocsEditable()
  @Unstable()
  final bool onLine;

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


@DocsEditable()
@DomName('NavigatorID')
@Experimental() // untriaged
abstract class NavigatorID extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigatorID._() { throw new UnsupportedError("Not supported"); }

  final String appCodeName;

  final String appName;

  final String appVersion;

  final String platform;

  final String product;

  final String userAgent;
}
// 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.


@DocsEditable()
@DomName('NavigatorOnLine')
@Experimental() // untriaged
abstract class NavigatorOnLine extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigatorOnLine._() { throw new UnsupportedError("Not supported"); }

  final bool onLine;
}
// 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.


@DocsEditable()
@DomName('NavigatorUserMediaError')
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html#idl-def-NavigatorUserMediaError
@Experimental()
class NavigatorUserMediaError extends Interceptor native "NavigatorUserMediaError" {
  // To suppress missing implicit constructor warnings.
  factory NavigatorUserMediaError._() { throw new UnsupportedError("Not supported"); }

  @DomName('NavigatorUserMediaError.constraintName')
  @DocsEditable()
  final String constraintName;

  @DomName('NavigatorUserMediaError.message')
  @DocsEditable()
  final String message;

  @DomName('NavigatorUserMediaError.name')
  @DocsEditable()
  final String name;
}
// 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.


@DomName('NavigatorUserMediaErrorCallback')
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html#idl-def-NavigatorUserMediaErrorCallback
@Experimental()
typedef void _NavigatorUserMediaErrorCallback(NavigatorUserMediaError error);
// 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.


@DomName('NavigatorUserMediaSuccessCallback')
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html#idl-def-NavigatorUserMediaSuccessCallback
@Experimental()
typedef void _NavigatorUserMediaSuccessCallback(MediaStream stream);
// 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.


/**
 * Lazy implementation of the child nodes of an element that does not request
 * the actual child nodes of an element until strictly necessary greatly
 * improving performance for the typical cases where it is not required.
 */
class _ChildNodeListLazy extends ListBase<Node> implements NodeListWrapper {
  final Node _this;

  _ChildNodeListLazy(this._this);


  Node get first {
    Node result = JS('Node|Null', '#.firstChild', _this);
    if (result == null) throw new StateError("No elements");
    return result;
  }
  Node get last {
    Node result = JS('Node|Null', '#.lastChild', _this);
    if (result == null) throw new StateError("No elements");
    return result;
  }
  Node get single {
    int l = this.length;
    if (l == 0) throw new StateError("No elements");
    if (l > 1) throw new StateError("More than one element");
    return JS('Node|Null', '#.firstChild', _this);
  }

  void add(Node value) {
    _this.append(value);
  }

  void addAll(Iterable<Node> iterable) {
    if (iterable is _ChildNodeListLazy) {
      _ChildNodeListLazy otherList = iterable;
      if (!identical(otherList._this, _this)) {
        // Optimized route for copying between nodes.
        for (var i = 0, len = otherList.length; i < len; ++i) {
          _this.append(otherList._this.firstChild);
        }
      }
      return;
    }
    for (Node node in iterable) {
      _this.append(node);
    }
  }

  void insert(int index, Node node) {
    if (index < 0 || index > length) {
      throw new RangeError.range(index, 0, length);
    }
    if (index == length) {
      _this.append(node);
    } else {
      _this.insertBefore(node, this[index]);
    }
  }

  void insertAll(int index, Iterable<Node> iterable) {
    var item = this[index];
    _this.insertAllBefore(iterable, item);
  }

  void setAll(int index, Iterable<Node> iterable) {
    throw new UnsupportedError("Cannot setAll on Node list");
  }

  Node removeLast() {
    final result = last;
    if (result != null) {
      _this._removeChild(result);
    }
    return result;
  }

  Node removeAt(int index) {
    var result = this[index];
    if (result != null) {
      _this._removeChild(result);
    }
    return result;
  }

  bool remove(Object object) {
    if (object is! Node) return false;
    Node node = object;
    if (!identical(_this, node.parentNode)) return false;
    _this._removeChild(node);
    return true;
  }

  void _filter(bool test(Node node), bool removeMatching) {
    // This implementation of removeWhere/retainWhere is more efficient
    // than the default in ListBase. Child nodes can be removed in constant
    // time.
    Node child = _this.firstChild;
    while (child != null) {
      Node nextChild = child.nextNode;
      if (test(child) == removeMatching) {
        _this._removeChild(child);
      }
      child = nextChild;
    }
  }

  void removeWhere(bool test(Node node)) {
    _filter(test, true);
  }

  void retainWhere(bool test(Node node)) {
    _filter(test, false);
  }

  void clear() {
    _this._clearChildren();
  }

  void operator []=(int index, Node value) {
    _this._replaceChild(value, this[index]);
  }

  Iterator<Node> get iterator => _this.childNodes.iterator;

  // From List<Node>:

  // TODO(jacobr): this could be implemented for child node lists.
  // The exception we throw here is misleading.
  void sort([Comparator<Node> compare]) {
    throw new UnsupportedError("Cannot sort Node list");
  }

  void shuffle([Random random]) {
    throw new UnsupportedError("Cannot shuffle Node list");
  }

  // FIXME: implement these.
  void setRange(int start, int end, Iterable<Node> iterable,
                [int skipCount = 0]) {
    throw new UnsupportedError("Cannot setRange on Node list");
  }

  void fillRange(int start, int end, [Node fill]) {
    throw new UnsupportedError("Cannot fillRange on Node list");
  }
  // -- end List<Node> mixins.

  // TODO(jacobr): benchmark whether this is more efficient or whether caching
  // a local copy of childNodes is more efficient.
  int get length => _this.childNodes.length;

  void set length(int value) {
    throw new UnsupportedError(
        "Cannot set length on immutable List.");
  }

  Node operator[](int index) => _this.childNodes[index];

  List<Node> get rawList => _this.childNodes;
}


@DomName('Node')
class Node extends EventTarget native "Node" {

  // Custom element created callback.
  Node._created() : super._created();

  /**
   * A modifiable list of this node's children.
   */
  List<Node> get nodes {
    return new _ChildNodeListLazy(this);
  }

  void set nodes(Iterable<Node> value) {
    // Copy list first since we don't want liveness during iteration.
    // TODO(jacobr): there is a better way to do this.
    List copy = new List.from(value);
    text = '';
    for (Node node in copy) {
      append(node);
    }
  }

  /**
   * Removes this node from the DOM.
   */
  @DomName('Node.removeChild')
  void remove() {
    // TODO(jacobr): should we throw an exception if parent is already null?
    // TODO(vsm): Use the native remove when available.
    if (this.parentNode != null) {
      final Node parent = this.parentNode;
      parentNode._removeChild(this);
    }
  }

  /**
   * Replaces this node with another node.
   */
  @DomName('Node.replaceChild')
  Node replaceWith(Node otherNode) {
    try {
      final Node parent = this.parentNode;
      parent._replaceChild(otherNode, this);
    } catch (e) {

    };
    return this;
  }

  /**
   * Inserts all of the nodes into this node directly before refChild.
   *
   * See also:
   *
   * * [insertBefore]
   */
  Node insertAllBefore(Iterable<Node> newNodes, Node refChild) {
    if (newNodes is _ChildNodeListLazy) {
      _ChildNodeListLazy otherList = newNodes;
      if (identical(otherList._this, this)) {
        throw new ArgumentError(newNodes);
      }

      // Optimized route for copying between nodes.
      for (var i = 0, len = otherList.length; i < len; ++i) {
        this.insertBefore(otherList._this.firstChild, refChild);
      }
    } else {
      for (var node in newNodes) {
        this.insertBefore(node, refChild);
      }
    }
  }

  void _clearChildren() {
    while (firstChild != null) {
      _removeChild(firstChild);
    }
  }

  /**
   * Print out a String representation of this Node.
   */
  String toString() => nodeValue == null ? super.toString() : nodeValue;
  // To suppress missing implicit constructor warnings.
  factory Node._() { throw new UnsupportedError("Not supported"); }

  @DomName('Node.ATTRIBUTE_NODE')
  @DocsEditable()
  static const int ATTRIBUTE_NODE = 2;

  @DomName('Node.CDATA_SECTION_NODE')
  @DocsEditable()
  static const int CDATA_SECTION_NODE = 4;

  @DomName('Node.COMMENT_NODE')
  @DocsEditable()
  static const int COMMENT_NODE = 8;

  @DomName('Node.DOCUMENT_FRAGMENT_NODE')
  @DocsEditable()
  static const int DOCUMENT_FRAGMENT_NODE = 11;

  @DomName('Node.DOCUMENT_NODE')
  @DocsEditable()
  static const int DOCUMENT_NODE = 9;

  @DomName('Node.DOCUMENT_TYPE_NODE')
  @DocsEditable()
  static const int DOCUMENT_TYPE_NODE = 10;

  @DomName('Node.ELEMENT_NODE')
  @DocsEditable()
  static const int ELEMENT_NODE = 1;

  @DomName('Node.ENTITY_NODE')
  @DocsEditable()
  static const int ENTITY_NODE = 6;

  @DomName('Node.ENTITY_REFERENCE_NODE')
  @DocsEditable()
  static const int ENTITY_REFERENCE_NODE = 5;

  @DomName('Node.NOTATION_NODE')
  @DocsEditable()
  static const int NOTATION_NODE = 12;

  @DomName('Node.PROCESSING_INSTRUCTION_NODE')
  @DocsEditable()
  static const int PROCESSING_INSTRUCTION_NODE = 7;

  @DomName('Node.TEXT_NODE')
  @DocsEditable()
  static const int TEXT_NODE = 3;

  @JSName('baseURI')
  @DomName('Node.baseURI')
  @DocsEditable()
  final String baseUri;

  /**
   * A list of this node's children.
   *
   * ## Other resources
   *
   * * [Node.childNodes]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)
   * from MDN.
   */
  @DomName('Node.childNodes')
  @DocsEditable()
  @Returns('NodeList')
  @Creates('NodeList')
  final List<Node> childNodes;

  /**
   * The first child of this node.
   *
   * ## Other resources
   *
   * * [Node.firstChild]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.firstChild)
   * from MDN.
   */
  @DomName('Node.firstChild')
  @DocsEditable()
  final Node firstChild;

  /**
   * The last child of this node.
   *
   * ## Other resources
   *
   * * [Node.lastChild]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.lastChild)
   * from MDN.
   */
  @DomName('Node.lastChild')
  @DocsEditable()
  final Node lastChild;

  @JSName('localName')
  @DomName('Node.localName')
  @DocsEditable()
  final String _localName;

  @JSName('namespaceURI')
  @DomName('Node.namespaceURI')
  @DocsEditable()
  final String _namespaceUri;

  @JSName('nextSibling')
  /**
   * The next sibling node.
   *
   * ## Other resources
   *
   * * [Node.nextSibling]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nextSibling)
   * from MDN.
   */
  @DomName('Node.nextSibling')
  @DocsEditable()
  final Node nextNode;

  /**
   * The name of this node.
   *
   * This varies by this node's [nodeType].
   *
   * ## Other resources
   *
   * * [Node.nodeName]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeName)
   * from MDN. This page contains a table of [nodeName] values for each
   * [nodeType].
   */
  @DomName('Node.nodeName')
  @DocsEditable()
  final String nodeName;

  /**
   * The type of node.
   *
   * This value is one of:
   *
   * * [ATTRIBUTE_NODE] if this node is an attribute.
   * * [CDATA_SECTION_NODE] if this node is a [CDataSection].
   * * [COMMENT_NODE] if this node is a [Comment].
   * * [DOCUMENT_FRAGMENT_NODE] if this node is a [DocumentFragment].
   * * [DOCUMENT_NODE] if this node is a [Document].
   * * [DOCUMENT_TYPE_NODE] if this node is a [DocumentType] node.
   * * [ELEMENT_NODE] if this node is an [Element].
   * * [ENTITY_NODE] if this node is an entity.
   * * [ENTITY_REFERENCE_NODE] if this node is an entity reference.
   * * [NOTATION_NODE] if this node is a notation.
   * * [PROCESSING_INSTRUCTION_NODE] if this node is a [ProcessingInstruction].
   * * [TEXT_NODE] if this node is a [Text] node.
   *
   * ## Other resources
   *
   * * [Node.nodeType]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeType) from MDN.
   */
  @DomName('Node.nodeType')
  @DocsEditable()
  final int nodeType;

  /**
   * The value of this node.
   *
   * This varies by this type's [nodeType].
   *
   * ## Other resources
   *
   * * [Node.nodeValue]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeValue)
   * from MDN. This page contains a table of [nodeValue] values for each
   * [nodeType].
   */
  @DomName('Node.nodeValue')
  @DocsEditable()
  final String nodeValue;

  /**
   * The document this node belongs to.
   *
   * Returns null if this node does not belong to any document.
   *
   * ## Other resources
   *
   * * [Node.ownerDocument]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.ownerDocument) from
   * MDN.
   */
  @DomName('Node.ownerDocument')
  @DocsEditable()
  final Document ownerDocument;

  @JSName('parentElement')
  /**
   * The parent element of this node.
   *
   * Returns null if this node either does not have a parent or its parent is
   * not an element.
   *
   * ## Other resources
   *
   * * [Node.parentElement]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.parentElement) from
   * W3C.
   */
  @DomName('Node.parentElement')
  @DocsEditable()
  final Element parent;

  /**
   * The parent node of this node.
   *
   * ## Other resources
   *
   * * [Node.parentNode]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.parentNode) from
   * MDN.
   */
  @DomName('Node.parentNode')
  @DocsEditable()
  final Node parentNode;

  @JSName('previousSibling')
  /**
   * The previous sibling node.
   *
   * ## Other resources
   *
   * * [Node.previousSibling]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.previousSibling)
   * from MDN.
   */
  @DomName('Node.previousSibling')
  @DocsEditable()
  final Node previousNode;

  @JSName('textContent')
  /**
   * All text within this node and its decendents.
   *
   * ## Other resources
   *
   * * [Node.textContent]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent) from
   * MDN.
   */
  @DomName('Node.textContent')
  @DocsEditable()
  String text;

  @JSName('appendChild')
  /**
   * Adds a node to the end of the child [nodes] list of this node.
   *
   * If the node already exists in this document, it will be removed from its
   * current parent node, then added to this node.
   *
   * This method is more efficient than `nodes.add`, and is the preferred
   * way of appending a child node.
   */
  @DomName('Node.appendChild')
  @DocsEditable()
  Node append(Node newChild) native;

  @JSName('cloneNode')
  /**
   * Returns a copy of this node.
   *
   * If [deep] is `true`, then all of this node's children and decendents are
   * copied as well. If [deep] is `false`, then only this node is copied.
   *
   * ## Other resources
   *
   * * [Node.cloneNode]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.cloneNode) from
   * MDN.
   */
  @DomName('Node.cloneNode')
  @DocsEditable()
  Node clone(bool deep) native;

  /**
   * Returns true if this node contains the specified node.
   *
   * ## Other resources
   *
   * * [Node.contains]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.contains) from MDN.
   */
  @DomName('Node.contains')
  @DocsEditable()
  bool contains(Node other) native;

  /**
   * Returns true if this node has any children.
   *
   * ## Other resources
   *
   * * [Node.hasChildNodes]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.hasChildNodes) from
   * MDN.
   */
  @DomName('Node.hasChildNodes')
  @DocsEditable()
  bool hasChildNodes() native;

  /**
   * Inserts all of the nodes into this node directly before refChild.
   *
   * ## Other resources
   *
   * * [Node.insertBefore]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.insertBefore) from
   * MDN.
   */
  @DomName('Node.insertBefore')
  @DocsEditable()
  Node insertBefore(Node newChild, Node refChild) native;

  @JSName('removeChild')
  @DomName('Node.removeChild')
  @DocsEditable()
  Node _removeChild(Node oldChild) native;

  @JSName('replaceChild')
  @DomName('Node.replaceChild')
  @DocsEditable()
  Node _replaceChild(Node newChild, Node oldChild) native;

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


@DocsEditable()
@DomName('NodeFilter')
@Unstable()
class NodeFilter extends Interceptor native "NodeFilter" {
  // To suppress missing implicit constructor warnings.
  factory NodeFilter._() { throw new UnsupportedError("Not supported"); }

  @DomName('NodeFilter.FILTER_ACCEPT')
  @DocsEditable()
  static const int FILTER_ACCEPT = 1;

  @DomName('NodeFilter.FILTER_REJECT')
  @DocsEditable()
  static const int FILTER_REJECT = 2;

  @DomName('NodeFilter.FILTER_SKIP')
  @DocsEditable()
  static const int FILTER_SKIP = 3;

  @DomName('NodeFilter.SHOW_ALL')
  @DocsEditable()
  static const int SHOW_ALL = 0xFFFFFFFF;

  @DomName('NodeFilter.SHOW_COMMENT')
  @DocsEditable()
  static const int SHOW_COMMENT = 0x00000080;

  @DomName('NodeFilter.SHOW_DOCUMENT')
  @DocsEditable()
  static const int SHOW_DOCUMENT = 0x00000100;

  @DomName('NodeFilter.SHOW_DOCUMENT_FRAGMENT')
  @DocsEditable()
  static const int SHOW_DOCUMENT_FRAGMENT = 0x00000400;

  @DomName('NodeFilter.SHOW_DOCUMENT_TYPE')
  @DocsEditable()
  static const int SHOW_DOCUMENT_TYPE = 0x00000200;

  @DomName('NodeFilter.SHOW_ELEMENT')
  @DocsEditable()
  static const int SHOW_ELEMENT = 0x00000001;

  @DomName('NodeFilter.SHOW_PROCESSING_INSTRUCTION')
  @DocsEditable()
  static const int SHOW_PROCESSING_INSTRUCTION = 0x00000040;

  @DomName('NodeFilter.SHOW_TEXT')
  @DocsEditable()
  static const int SHOW_TEXT = 0x00000004;
}
// 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.


@DomName('NodeIterator')
@Unstable()
class NodeIterator extends Interceptor native "NodeIterator" {
  factory NodeIterator(Node root, int whatToShow) {
    return document._createNodeIterator(root, whatToShow, null);
  }
  // To suppress missing implicit constructor warnings.
  factory NodeIterator._() { throw new UnsupportedError("Not supported"); }

  @DomName('NodeIterator.pointerBeforeReferenceNode')
  @DocsEditable()
  final bool pointerBeforeReferenceNode;

  @DomName('NodeIterator.referenceNode')
  @DocsEditable()
  final Node referenceNode;

  @DomName('NodeIterator.root')
  @DocsEditable()
  final Node root;

  @DomName('NodeIterator.whatToShow')
  @DocsEditable()
  final int whatToShow;

  @DomName('NodeIterator.detach')
  @DocsEditable()
  void detach() native;

  @DomName('NodeIterator.nextNode')
  @DocsEditable()
  Node nextNode() native;

  @DomName('NodeIterator.previousNode')
  @DocsEditable()
  Node previousNode() native;

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


@DocsEditable()
@DomName('NodeList')
class NodeList extends Interceptor with ListMixin<Node>, ImmutableListMixin<Node> implements JavaScriptIndexingBehavior, List<Node> native "NodeList,RadioNodeList" {
  // To suppress missing implicit constructor warnings.
  factory NodeList._() { throw new UnsupportedError("Not supported"); }

  @DomName('NodeList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  Node operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("Node", "#[#]", this, index);
  }
  void operator[]=(int index, Node value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Node> mixins.
  // Node is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Node get first {
    if (this.length > 0) {
      return JS('Node', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Node get last {
    int len = this.length;
    if (len > 0) {
      return JS('Node', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Node get single {
    int len = this.length;
    if (len == 1) {
      return JS('Node', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Node elementAt(int index) => this[index];
  // -- end List<Node> mixins.

  @JSName('item')
  @DomName('NodeList.item')
  @DocsEditable()
  Node _item(int index) native;
}
// 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.


@DomName('Notification')
// http://www.w3.org/TR/notifications/#notification
@Experimental() // experimental
class Notification extends EventTarget native "Notification" {

  factory Notification(String title, {String titleDir: null, String body: null,
      String bodyDir: null, String tag: null, String iconUrl: null}) {

    var parsedOptions = {};
    if (titleDir != null) parsedOptions['titleDir'] = titleDir;
    if (body != null) parsedOptions['body'] = body;
    if (bodyDir != null) parsedOptions['bodyDir'] = bodyDir;
    if (tag != null) parsedOptions['tag'] = tag;
    if (iconUrl != null) parsedOptions['iconUrl'] = iconUrl;

    return Notification._factoryNotification(title, parsedOptions);
  }
  // To suppress missing implicit constructor warnings.
  factory Notification._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `click` events to event
   * handlers that are not necessarily instances of [Notification].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Notification.clickEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> clickEvent = const EventStreamProvider<Event>('click');

  /**
   * Static factory designed to expose `close` events to event
   * handlers that are not necessarily instances of [Notification].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Notification.closeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> closeEvent = const EventStreamProvider<Event>('close');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [Notification].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Notification.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `show` events to event
   * handlers that are not necessarily instances of [Notification].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Notification.showEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> showEvent = const EventStreamProvider<Event>('show');

  @DomName('Notification.Notification')
  @DocsEditable()
  static Notification _factoryNotification(String title, [Map options]) {
    if (options != null) {
      return Notification._create_1(title, options);
    }
    return Notification._create_2(title);
  }
  static Notification _create_1(title, options) => JS('Notification', 'new Notification(#,#)', title, options);
  static Notification _create_2(title) => JS('Notification', 'new Notification(#)', title);

  @DomName('Notification.body')
  @DocsEditable()
  @Experimental() // untriaged
  final String body;

  @DomName('Notification.dir')
  @DocsEditable()
  @Experimental() // nonstandard
  final String dir;

  @DomName('Notification.icon')
  @DocsEditable()
  @Experimental() // untriaged
  final String icon;

  @DomName('Notification.lang')
  @DocsEditable()
  @Experimental() // untriaged
  final String lang;

  @DomName('Notification.permission')
  @DocsEditable()
  final String permission;

  @DomName('Notification.tag')
  @DocsEditable()
  @Experimental() // nonstandard
  final String tag;

  @DomName('Notification.title')
  @DocsEditable()
  @Experimental() // untriaged
  final String title;

  @DomName('Notification.close')
  @DocsEditable()
  void close() native;

  @JSName('requestPermission')
  @DomName('Notification.requestPermission')
  @DocsEditable()
  static void _requestPermission([_NotificationPermissionCallback callback]) native;

  @JSName('requestPermission')
  @DomName('Notification.requestPermission')
  @DocsEditable()
  static Future<String> requestPermission() {
    var completer = new Completer<String>();
    _requestPermission(
        (value) { completer.complete(value); });
    return completer.future;
  }

  /// Stream of `click` events handled by this [Notification].
  @DomName('Notification.onclick')
  @DocsEditable()
  Stream<Event> get onClick => clickEvent.forTarget(this);

  /// Stream of `close` events handled by this [Notification].
  @DomName('Notification.onclose')
  @DocsEditable()
  Stream<Event> get onClose => closeEvent.forTarget(this);

  /// Stream of `error` events handled by this [Notification].
  @DomName('Notification.onerror')
  @DocsEditable()
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `show` events handled by this [Notification].
  @DomName('Notification.onshow')
  @DocsEditable()
  Stream<Event> get onShow => showEvent.forTarget(this);

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


@DomName('NotificationPermissionCallback')
// http://www.w3.org/TR/notifications/#notificationpermissioncallback
@Experimental()
typedef void _NotificationPermissionCallback(String permission);
// 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.


@DocsEditable()
@DomName('HTMLOListElement')
class OListElement extends HtmlElement native "HTMLOListElement" {
  // To suppress missing implicit constructor warnings.
  factory OListElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLOListElement.HTMLOListElement')
  @DocsEditable()
  factory OListElement() => document.createElement("ol");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  OListElement.created() : super.created();

  @DomName('HTMLOListElement.reversed')
  @DocsEditable()
  bool reversed;

  @DomName('HTMLOListElement.start')
  @DocsEditable()
  int start;

  @DomName('HTMLOListElement.type')
  @DocsEditable()
  String type;
}
// 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.


@DocsEditable()
@DomName('HTMLObjectElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
class ObjectElement extends HtmlElement native "HTMLObjectElement" {
  // To suppress missing implicit constructor warnings.
  factory ObjectElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLObjectElement.HTMLObjectElement')
  @DocsEditable()
  factory ObjectElement() => document.createElement("object");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ObjectElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('object');

  @DomName('HTMLObjectElement.data')
  @DocsEditable()
  String data;

  @DomName('HTMLObjectElement.form')
  @DocsEditable()
  final FormElement form;

  @DomName('HTMLObjectElement.height')
  @DocsEditable()
  String height;

  @DomName('HTMLObjectElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLObjectElement.type')
  @DocsEditable()
  String type;

  @DomName('HTMLObjectElement.useMap')
  @DocsEditable()
  String useMap;

  @DomName('HTMLObjectElement.validationMessage')
  @DocsEditable()
  final String validationMessage;

  @DomName('HTMLObjectElement.validity')
  @DocsEditable()
  final ValidityState validity;

  @DomName('HTMLObjectElement.width')
  @DocsEditable()
  String width;

  @DomName('HTMLObjectElement.willValidate')
  @DocsEditable()
  final bool willValidate;

  @DomName('HTMLObjectElement.__getter__')
  @DocsEditable()
  bool __getter__(index_OR_name) native;

  @DomName('HTMLObjectElement.__setter__')
  @DocsEditable()
  void __setter__(index_OR_name, Node value) native;

  @DomName('HTMLObjectElement.checkValidity')
  @DocsEditable()
  bool checkValidity() native;

  @DomName('HTMLObjectElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) native;
}
// 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.


@DocsEditable()
@DomName('HTMLOptGroupElement')
class OptGroupElement extends HtmlElement native "HTMLOptGroupElement" {
  // To suppress missing implicit constructor warnings.
  factory OptGroupElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLOptGroupElement.HTMLOptGroupElement')
  @DocsEditable()
  factory OptGroupElement() => document.createElement("optgroup");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  OptGroupElement.created() : super.created();

  @DomName('HTMLOptGroupElement.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('HTMLOptGroupElement.label')
  @DocsEditable()
  String label;
}
// 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.


@DomName('HTMLOptionElement')
class OptionElement extends HtmlElement native "HTMLOptionElement" {
  factory OptionElement({String data: '', String value : '', bool selected: false}) {
    return new OptionElement._(data, value, null, selected);
  }

  @DomName('HTMLOptionElement.HTMLOptionElement')
  @DocsEditable()
  factory OptionElement._([String data, String value, bool defaultSelected, bool selected]) {
    if (selected != null) {
      return OptionElement._create_1(data, value, defaultSelected, selected);
    }
    if (defaultSelected != null) {
      return OptionElement._create_2(data, value, defaultSelected);
    }
    if (value != null) {
      return OptionElement._create_3(data, value);
    }
    if (data != null) {
      return OptionElement._create_4(data);
    }
    return OptionElement._create_5();
  }
  static OptionElement _create_1(data, value, defaultSelected, selected) => JS('OptionElement', 'new Option(#,#,#,#)', data, value, defaultSelected, selected);
  static OptionElement _create_2(data, value, defaultSelected) => JS('OptionElement', 'new Option(#,#,#)', data, value, defaultSelected);
  static OptionElement _create_3(data, value) => JS('OptionElement', 'new Option(#,#)', data, value);
  static OptionElement _create_4(data) => JS('OptionElement', 'new Option(#)', data);
  static OptionElement _create_5() => JS('OptionElement', 'new Option()');
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  OptionElement.created() : super.created();

  @DomName('HTMLOptionElement.defaultSelected')
  @DocsEditable()
  bool defaultSelected;

  @DomName('HTMLOptionElement.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('HTMLOptionElement.form')
  @DocsEditable()
  final FormElement form;

  @DomName('HTMLOptionElement.index')
  @DocsEditable()
  final int index;

  @DomName('HTMLOptionElement.label')
  @DocsEditable()
  String label;

  @DomName('HTMLOptionElement.selected')
  @DocsEditable()
  bool selected;

  @DomName('HTMLOptionElement.value')
  @DocsEditable()
  String value;

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


@DocsEditable()
@DomName('HTMLOutputElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
class OutputElement extends HtmlElement native "HTMLOutputElement" {
  // To suppress missing implicit constructor warnings.
  factory OutputElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLOutputElement.HTMLOutputElement')
  @DocsEditable()
  factory OutputElement() => document.createElement("output");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  OutputElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('output');

  @DomName('HTMLOutputElement.defaultValue')
  @DocsEditable()
  String defaultValue;

  @DomName('HTMLOutputElement.form')
  @DocsEditable()
  final FormElement form;

  @DomName('HTMLOutputElement.htmlFor')
  @DocsEditable()
  final DomSettableTokenList htmlFor;

  @DomName('HTMLOutputElement.labels')
  @DocsEditable()
  @Unstable()
  @Returns('NodeList')
  @Creates('NodeList')
  final List<Node> labels;

  @DomName('HTMLOutputElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLOutputElement.type')
  @DocsEditable()
  final String type;

  @DomName('HTMLOutputElement.validationMessage')
  @DocsEditable()
  final String validationMessage;

  @DomName('HTMLOutputElement.validity')
  @DocsEditable()
  final ValidityState validity;

  @DomName('HTMLOutputElement.value')
  @DocsEditable()
  String value;

  @DomName('HTMLOutputElement.willValidate')
  @DocsEditable()
  final bool willValidate;

  @DomName('HTMLOutputElement.checkValidity')
  @DocsEditable()
  bool checkValidity() native;

  @DomName('HTMLOutputElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) native;
}
// 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.


@DocsEditable()
@DomName('OverflowEvent')
@Experimental() // nonstandard
class OverflowEvent extends Event native "OverflowEvent" {
  // To suppress missing implicit constructor warnings.
  factory OverflowEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('OverflowEvent.BOTH')
  @DocsEditable()
  static const int BOTH = 2;

  @DomName('OverflowEvent.HORIZONTAL')
  @DocsEditable()
  static const int HORIZONTAL = 0;

  @DomName('OverflowEvent.VERTICAL')
  @DocsEditable()
  static const int VERTICAL = 1;

  @DomName('OverflowEvent.horizontalOverflow')
  @DocsEditable()
  final bool horizontalOverflow;

  @DomName('OverflowEvent.orient')
  @DocsEditable()
  final int orient;

  @DomName('OverflowEvent.verticalOverflow')
  @DocsEditable()
  final bool verticalOverflow;
}
// 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.


@DocsEditable()
@DomName('PageTransitionEvent')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html#pagetransitionevent
@Experimental()
class PageTransitionEvent extends Event native "PageTransitionEvent" {
  // To suppress missing implicit constructor warnings.
  factory PageTransitionEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('PageTransitionEvent.persisted')
  @DocsEditable()
  final bool persisted;
}
// 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.


@DocsEditable()
@DomName('HTMLParagraphElement')
class ParagraphElement extends HtmlElement native "HTMLParagraphElement" {
  // To suppress missing implicit constructor warnings.
  factory ParagraphElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLParagraphElement.HTMLParagraphElement')
  @DocsEditable()
  factory ParagraphElement() => document.createElement("p");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ParagraphElement.created() : super.created();
}
// 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.


@DocsEditable()
@DomName('HTMLParamElement')
@Unstable()
class ParamElement extends HtmlElement native "HTMLParamElement" {
  // To suppress missing implicit constructor warnings.
  factory ParamElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLParamElement.HTMLParamElement')
  @DocsEditable()
  factory ParamElement() => document.createElement("param");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ParamElement.created() : super.created();

  @DomName('HTMLParamElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLParamElement.value')
  @DocsEditable()
  String value;
}
// 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.


@DocsEditable()
@DomName('ParentNode')
@Experimental() // untriaged
abstract class ParentNode extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ParentNode._() { throw new UnsupportedError("Not supported"); }

  final int _childElementCount;

  final List<Node> _children;

  final Element _firstElementChild;

  final Element _lastElementChild;
}
// 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.


@DocsEditable()
@DomName('Path')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#path-objects
@Experimental()
class Path extends Interceptor native "Path" {
  // To suppress missing implicit constructor warnings.
  factory Path._() { throw new UnsupportedError("Not supported"); }

  @DomName('Path.Path')
  @DocsEditable()
  factory Path([path_OR_text]) {
    if (path_OR_text == null) {
      return Path._create_1();
    }
    if ((path_OR_text is Path || path_OR_text == null)) {
      return Path._create_2(path_OR_text);
    }
    if ((path_OR_text is String || path_OR_text == null)) {
      return Path._create_3(path_OR_text);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static Path _create_1() => JS('Path', 'new Path()');
  static Path _create_2(path_OR_text) => JS('Path', 'new Path(#)', path_OR_text);
  static Path _create_3(path_OR_text) => JS('Path', 'new Path(#)', path_OR_text);

  @DomName('Path.arc')
  @DocsEditable()
  void arc(num x, num y, num radius, num startAngle, num endAngle, bool anticlockwise) native;

  @DomName('Path.arcTo')
  @DocsEditable()
  void arcTo(num x1, num y1, num x2, num y2, num radius) native;

  @DomName('Path.bezierCurveTo')
  @DocsEditable()
  void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y, num x, num y) native;

  @DomName('Path.closePath')
  @DocsEditable()
  void closePath() native;

  @DomName('Path.lineTo')
  @DocsEditable()
  void lineTo(num x, num y) native;

  @DomName('Path.moveTo')
  @DocsEditable()
  void moveTo(num x, num y) native;

  @DomName('Path.quadraticCurveTo')
  @DocsEditable()
  void quadraticCurveTo(num cpx, num cpy, num x, num y) native;

  @DomName('Path.rect')
  @DocsEditable()
  void rect(num x, num y, num width, num height) native;
}
// 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.


@DocsEditable()
@DomName('Performance')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE)
class Performance extends EventTarget native "Performance" {
  // To suppress missing implicit constructor warnings.
  factory Performance._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `resourcetimingbufferfull` events to event
   * handlers that are not necessarily instances of [Performance].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Performance.webkitresourcetimingbufferfullEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.w3c-test.org/webperf/specs/ResourceTiming/#performanceresourcetiming-methods
  static const EventStreamProvider<Event> resourceTimingBufferFullEvent = const EventStreamProvider<Event>('webkitresourcetimingbufferfull');

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.performance)');

  @DomName('Performance.memory')
  @DocsEditable()
  @Experimental() // nonstandard
  final MemoryInfo memory;

  @DomName('Performance.navigation')
  @DocsEditable()
  final PerformanceNavigation navigation;

  @DomName('Performance.timing')
  @DocsEditable()
  final PerformanceTiming timing;

  @DomName('Performance.clearMarks')
  @DocsEditable()
  // https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/UserTiming/Overview.html#extensions-performance-interface
  @Experimental()
  void clearMarks(String markName) native;

  @DomName('Performance.clearMeasures')
  @DocsEditable()
  // https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/UserTiming/Overview.html#extensions-performance-interface
  @Experimental()
  void clearMeasures(String measureName) native;

  @DomName('Performance.getEntries')
  @DocsEditable()
  // http://www.w3.org/TR/performance-timeline/#sec-window.performance-attribute
  @Experimental()
  List<PerformanceEntry> getEntries() native;

  @DomName('Performance.getEntriesByName')
  @DocsEditable()
  // http://www.w3.org/TR/performance-timeline/#sec-window.performance-attribute
  @Experimental()
  List<PerformanceEntry> getEntriesByName(String name, String entryType) native;

  @DomName('Performance.getEntriesByType')
  @DocsEditable()
  // http://www.w3.org/TR/performance-timeline/#sec-window.performance-attribute
  @Experimental()
  List<PerformanceEntry> getEntriesByType(String entryType) native;

  @DomName('Performance.mark')
  @DocsEditable()
  // https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/UserTiming/Overview.html#extensions-performance-interface
  @Experimental()
  void mark(String markName) native;

  @DomName('Performance.measure')
  @DocsEditable()
  // https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/UserTiming/Overview.html#extensions-performance-interface
  @Experimental()
  void measure(String measureName, String startMark, String endMark) native;

  @DomName('Performance.now')
  @DocsEditable()
  double now() native;

  @JSName('webkitClearResourceTimings')
  @DomName('Performance.webkitClearResourceTimings')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.w3c-test.org/webperf/specs/ResourceTiming/#extensions-performance-interface
  void clearResourceTimings() native;

  @JSName('webkitSetResourceTimingBufferSize')
  @DomName('Performance.webkitSetResourceTimingBufferSize')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.w3c-test.org/webperf/specs/ResourceTiming/#performanceresourcetiming-methods
  void setResourceTimingBufferSize(int maxSize) native;

  /// Stream of `resourcetimingbufferfull` events handled by this [Performance].
  @DomName('Performance.onwebkitresourcetimingbufferfull')
  @DocsEditable()
  // http://www.w3c-test.org/webperf/specs/ResourceTiming/#performanceresourcetiming-methods
  @Experimental()
  Stream<Event> get onResourceTimingBufferFull => resourceTimingBufferFullEvent.forTarget(this);
}
// 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.


@DocsEditable()
@DomName('PerformanceEntry')
// http://www.w3.org/TR/performance-timeline/#sec-PerformanceEntry-interface
@Experimental()
class PerformanceEntry extends Interceptor native "PerformanceEntry" {
  // To suppress missing implicit constructor warnings.
  factory PerformanceEntry._() { throw new UnsupportedError("Not supported"); }

  @DomName('PerformanceEntry.duration')
  @DocsEditable()
  final double duration;

  @DomName('PerformanceEntry.entryType')
  @DocsEditable()
  final String entryType;

  @DomName('PerformanceEntry.name')
  @DocsEditable()
  final String name;

  @DomName('PerformanceEntry.startTime')
  @DocsEditable()
  final double startTime;
}
// 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.


@DocsEditable()
@DomName('PerformanceMark')
// http://www.w3.org/TR/user-timing/#performancemark
@Experimental()
class PerformanceMark extends PerformanceEntry native "PerformanceMark" {
  // To suppress missing implicit constructor warnings.
  factory PerformanceMark._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('PerformanceMeasure')
// http://www.w3.org/TR/user-timing/#performancemeasure
@Experimental()
class PerformanceMeasure extends PerformanceEntry native "PerformanceMeasure" {
  // To suppress missing implicit constructor warnings.
  factory PerformanceMeasure._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('PerformanceNavigation')
@Unstable()
class PerformanceNavigation extends Interceptor native "PerformanceNavigation" {
  // To suppress missing implicit constructor warnings.
  factory PerformanceNavigation._() { throw new UnsupportedError("Not supported"); }

  @DomName('PerformanceNavigation.TYPE_BACK_FORWARD')
  @DocsEditable()
  static const int TYPE_BACK_FORWARD = 2;

  @DomName('PerformanceNavigation.TYPE_NAVIGATE')
  @DocsEditable()
  static const int TYPE_NAVIGATE = 0;

  @DomName('PerformanceNavigation.TYPE_RELOAD')
  @DocsEditable()
  static const int TYPE_RELOAD = 1;

  @DomName('PerformanceNavigation.TYPE_RESERVED')
  @DocsEditable()
  static const int TYPE_RESERVED = 255;

  @DomName('PerformanceNavigation.redirectCount')
  @DocsEditable()
  final int redirectCount;

  @DomName('PerformanceNavigation.type')
  @DocsEditable()
  final int type;
}
// 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.


@DocsEditable()
@DomName('PerformanceResourceTiming')
// http://www.w3c-test.org/webperf/specs/ResourceTiming/#performanceresourcetiming
@Experimental()
class PerformanceResourceTiming extends PerformanceEntry native "PerformanceResourceTiming" {
  // To suppress missing implicit constructor warnings.
  factory PerformanceResourceTiming._() { throw new UnsupportedError("Not supported"); }

  @DomName('PerformanceResourceTiming.connectEnd')
  @DocsEditable()
  final double connectEnd;

  @DomName('PerformanceResourceTiming.connectStart')
  @DocsEditable()
  final double connectStart;

  @DomName('PerformanceResourceTiming.domainLookupEnd')
  @DocsEditable()
  final double domainLookupEnd;

  @DomName('PerformanceResourceTiming.domainLookupStart')
  @DocsEditable()
  final double domainLookupStart;

  @DomName('PerformanceResourceTiming.fetchStart')
  @DocsEditable()
  final double fetchStart;

  @DomName('PerformanceResourceTiming.initiatorType')
  @DocsEditable()
  final String initiatorType;

  @DomName('PerformanceResourceTiming.redirectEnd')
  @DocsEditable()
  final double redirectEnd;

  @DomName('PerformanceResourceTiming.redirectStart')
  @DocsEditable()
  final double redirectStart;

  @DomName('PerformanceResourceTiming.requestStart')
  @DocsEditable()
  @Experimental() // nonstandard
  final double requestStart;

  @DomName('PerformanceResourceTiming.responseEnd')
  @DocsEditable()
  @Experimental() // nonstandard
  final double responseEnd;

  @DomName('PerformanceResourceTiming.responseStart')
  @DocsEditable()
  @Experimental() // nonstandard
  final double responseStart;

  @DomName('PerformanceResourceTiming.secureConnectionStart')
  @DocsEditable()
  final double secureConnectionStart;
}
// 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.


@DocsEditable()
@DomName('PerformanceTiming')
@Unstable()
class PerformanceTiming extends Interceptor native "PerformanceTiming" {
  // To suppress missing implicit constructor warnings.
  factory PerformanceTiming._() { throw new UnsupportedError("Not supported"); }

  @DomName('PerformanceTiming.connectEnd')
  @DocsEditable()
  final int connectEnd;

  @DomName('PerformanceTiming.connectStart')
  @DocsEditable()
  final int connectStart;

  @DomName('PerformanceTiming.domComplete')
  @DocsEditable()
  final int domComplete;

  @DomName('PerformanceTiming.domContentLoadedEventEnd')
  @DocsEditable()
  final int domContentLoadedEventEnd;

  @DomName('PerformanceTiming.domContentLoadedEventStart')
  @DocsEditable()
  final int domContentLoadedEventStart;

  @DomName('PerformanceTiming.domInteractive')
  @DocsEditable()
  final int domInteractive;

  @DomName('PerformanceTiming.domLoading')
  @DocsEditable()
  final int domLoading;

  @DomName('PerformanceTiming.domainLookupEnd')
  @DocsEditable()
  final int domainLookupEnd;

  @DomName('PerformanceTiming.domainLookupStart')
  @DocsEditable()
  final int domainLookupStart;

  @DomName('PerformanceTiming.fetchStart')
  @DocsEditable()
  final int fetchStart;

  @DomName('PerformanceTiming.loadEventEnd')
  @DocsEditable()
  final int loadEventEnd;

  @DomName('PerformanceTiming.loadEventStart')
  @DocsEditable()
  final int loadEventStart;

  @DomName('PerformanceTiming.navigationStart')
  @DocsEditable()
  final int navigationStart;

  @DomName('PerformanceTiming.redirectEnd')
  @DocsEditable()
  final int redirectEnd;

  @DomName('PerformanceTiming.redirectStart')
  @DocsEditable()
  final int redirectStart;

  @DomName('PerformanceTiming.requestStart')
  @DocsEditable()
  final int requestStart;

  @DomName('PerformanceTiming.responseEnd')
  @DocsEditable()
  final int responseEnd;

  @DomName('PerformanceTiming.responseStart')
  @DocsEditable()
  final int responseStart;

  @DomName('PerformanceTiming.secureConnectionStart')
  @DocsEditable()
  final int secureConnectionStart;

  @DomName('PerformanceTiming.unloadEventEnd')
  @DocsEditable()
  final int unloadEventEnd;

  @DomName('PerformanceTiming.unloadEventStart')
  @DocsEditable()
  final int unloadEventStart;
}
// 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.


@DocsEditable()
@DomName('Player')
@Experimental() // untriaged
class Player extends Interceptor native "Player" {
  // To suppress missing implicit constructor warnings.
  factory Player._() { throw new UnsupportedError("Not supported"); }

  @DomName('Player.currentTime')
  @DocsEditable()
  @Experimental() // untriaged
  num currentTime;

  @DomName('Player.finished')
  @DocsEditable()
  @Experimental() // untriaged
  final bool finished;

  @DomName('Player.paused')
  @DocsEditable()
  @Experimental() // untriaged
  final bool paused;

  @DomName('Player.playbackRate')
  @DocsEditable()
  @Experimental() // untriaged
  num playbackRate;

  @DomName('Player.source')
  @DocsEditable()
  @Experimental() // untriaged
  TimedItem source;

  @DomName('Player.startTime')
  @DocsEditable()
  @Experimental() // untriaged
  num startTime;

  @DomName('Player.timeLag')
  @DocsEditable()
  @Experimental() // untriaged
  final double timeLag;

  @DomName('Player.cancel')
  @DocsEditable()
  @Experimental() // untriaged
  void cancel() native;

  @DomName('Player.finish')
  @DocsEditable()
  @Experimental() // untriaged
  void finish() native;

  @DomName('Player.pause')
  @DocsEditable()
  @Experimental() // untriaged
  void pause() native;

  @DomName('Player.play')
  @DocsEditable()
  @Experimental() // untriaged
  void play() native;

  @DomName('Player.reverse')
  @DocsEditable()
  @Experimental() // untriaged
  void reverse() native;
}
// 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.


@DocsEditable()
@DomName('Plugin')
@Experimental() // non-standard
class Plugin extends Interceptor native "Plugin" {
  // To suppress missing implicit constructor warnings.
  factory Plugin._() { throw new UnsupportedError("Not supported"); }

  @DomName('Plugin.description')
  @DocsEditable()
  final String description;

  @DomName('Plugin.filename')
  @DocsEditable()
  final String filename;

  @DomName('Plugin.length')
  @DocsEditable()
  final int length;

  @DomName('Plugin.name')
  @DocsEditable()
  final String name;

  @DomName('Plugin.__getter__')
  @DocsEditable()
  MimeType __getter__(String name) native;

  @DomName('Plugin.item')
  @DocsEditable()
  MimeType item(int index) native;

  @DomName('Plugin.namedItem')
  @DocsEditable()
  MimeType namedItem(String name) native;
}
// 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.


@DocsEditable()
@DomName('PluginArray')
@Experimental() // non-standard
class PluginArray extends Interceptor with ListMixin<Plugin>, ImmutableListMixin<Plugin> implements JavaScriptIndexingBehavior, List<Plugin> native "PluginArray" {
  // To suppress missing implicit constructor warnings.
  factory PluginArray._() { throw new UnsupportedError("Not supported"); }

  @DomName('PluginArray.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  Plugin operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("Plugin", "#[#]", this, index);
  }
  void operator[]=(int index, Plugin value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Plugin> mixins.
  // Plugin is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Plugin get first {
    if (this.length > 0) {
      return JS('Plugin', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Plugin get last {
    int len = this.length;
    if (len > 0) {
      return JS('Plugin', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Plugin get single {
    int len = this.length;
    if (len == 1) {
      return JS('Plugin', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Plugin elementAt(int index) => this[index];
  // -- end List<Plugin> mixins.

  @DomName('PluginArray.__getter__')
  @DocsEditable()
  Plugin __getter__(String name) native;

  @DomName('PluginArray.item')
  @DocsEditable()
  Plugin item(int index) native;

  @DomName('PluginArray.namedItem')
  @DocsEditable()
  Plugin namedItem(String name) native;

  @DomName('PluginArray.refresh')
  @DocsEditable()
  void refresh(bool reload) native;
}
// 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.


@DocsEditable()
@DomName('PopStateEvent')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
class PopStateEvent extends Event native "PopStateEvent" {
  // To suppress missing implicit constructor warnings.
  factory PopStateEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('PopStateEvent.state')
  @DocsEditable()
  dynamic get state => convertNativeToDart_SerializedScriptValue(this._get_state);
  @JSName('state')
  @DomName('PopStateEvent.state')
  @DocsEditable()
  @annotation_Creates_SerializedScriptValue
  @annotation_Returns_SerializedScriptValue
  final dynamic _get_state;
}
// 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.


@DomName('PositionCallback')
@Unstable()
typedef void _PositionCallback(Geoposition position);
// 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.


@DocsEditable()
@DomName('PositionError')
@Unstable()
class PositionError extends Interceptor native "PositionError" {
  // To suppress missing implicit constructor warnings.
  factory PositionError._() { throw new UnsupportedError("Not supported"); }

  @DomName('PositionError.PERMISSION_DENIED')
  @DocsEditable()
  static const int PERMISSION_DENIED = 1;

  @DomName('PositionError.POSITION_UNAVAILABLE')
  @DocsEditable()
  static const int POSITION_UNAVAILABLE = 2;

  @DomName('PositionError.TIMEOUT')
  @DocsEditable()
  static const int TIMEOUT = 3;

  @DomName('PositionError.code')
  @DocsEditable()
  final int code;

  @DomName('PositionError.message')
  @DocsEditable()
  final String message;
}
// 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.


@DomName('PositionErrorCallback')
@Unstable()
typedef void _PositionErrorCallback(PositionError error);
// 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.


@DocsEditable()
@DomName('HTMLPreElement')
class PreElement extends HtmlElement native "HTMLPreElement" {
  // To suppress missing implicit constructor warnings.
  factory PreElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLPreElement.HTMLPreElement')
  @DocsEditable()
  factory PreElement() => document.createElement("pre");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  PreElement.created() : super.created();
}
// 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.


@DocsEditable()
@DomName('ProcessingInstruction')
@Unstable()
class ProcessingInstruction extends CharacterData native "ProcessingInstruction" {
  // To suppress missing implicit constructor warnings.
  factory ProcessingInstruction._() { throw new UnsupportedError("Not supported"); }

  @DomName('ProcessingInstruction.sheet')
  @DocsEditable()
  @Experimental() // non-standard
  final StyleSheet sheet;

  @DomName('ProcessingInstruction.target')
  @DocsEditable()
  final String target;
}
// 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.


@DocsEditable()
@DomName('HTMLProgressElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
class ProgressElement extends HtmlElement native "HTMLProgressElement" {
  // To suppress missing implicit constructor warnings.
  factory ProgressElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLProgressElement.HTMLProgressElement')
  @DocsEditable()
  factory ProgressElement() => document.createElement("progress");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ProgressElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('progress');

  @DomName('HTMLProgressElement.labels')
  @DocsEditable()
  @Unstable()
  @Returns('NodeList')
  @Creates('NodeList')
  final List<Node> labels;

  @DomName('HTMLProgressElement.max')
  @DocsEditable()
  num max;

  @DomName('HTMLProgressElement.position')
  @DocsEditable()
  final double position;

  @DomName('HTMLProgressElement.value')
  @DocsEditable()
  num value;
}
// 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.


@DocsEditable()
@DomName('ProgressEvent')
class ProgressEvent extends Event native "ProgressEvent" {
  // To suppress missing implicit constructor warnings.
  factory ProgressEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('ProgressEvent.lengthComputable')
  @DocsEditable()
  final bool lengthComputable;

  @DomName('ProgressEvent.loaded')
  @DocsEditable()
  final int loaded;

  @DomName('ProgressEvent.total')
  @DocsEditable()
  final int total;
}
// 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.


@DocsEditable()
@DomName('HTMLQuoteElement')
class QuoteElement extends HtmlElement native "HTMLQuoteElement" {
  // To suppress missing implicit constructor warnings.
  factory QuoteElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLQuoteElement.HTMLQuoteElement')
  @DocsEditable()
  factory QuoteElement() => document.createElement("q");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  QuoteElement.created() : super.created();

  @DomName('HTMLQuoteElement.cite')
  @DocsEditable()
  String cite;
}
// 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.


@DomName('RTCErrorCallback')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#rtcerror
@Experimental()
typedef void _RtcErrorCallback(String errorInformation);
// 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.


@DomName('RTCSessionDescriptionCallback')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCSessionDescription
@Experimental()
typedef void _RtcSessionDescriptionCallback(RtcSessionDescription sdp);
// 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.


@DomName('RTCStatsCallback')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCStatsCallback
@Experimental()
typedef void RtcStatsCallback(RtcStatsResponse response);
// 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.


@DomName('Range')
@Unstable()
class Range extends Interceptor native "Range" {
  factory Range() => document.createRange();

  factory Range.fromPoint(Point point) =>
      document._caretRangeFromPoint(point.x, point.y);
  // To suppress missing implicit constructor warnings.
  factory Range._() { throw new UnsupportedError("Not supported"); }

  @DomName('Range.END_TO_END')
  @DocsEditable()
  static const int END_TO_END = 2;

  @DomName('Range.END_TO_START')
  @DocsEditable()
  static const int END_TO_START = 3;

  @DomName('Range.NODE_AFTER')
  @DocsEditable()
  @Experimental() // nonstandard
  static const int NODE_AFTER = 1;

  @DomName('Range.NODE_BEFORE')
  @DocsEditable()
  @Experimental() // nonstandard
  static const int NODE_BEFORE = 0;

  @DomName('Range.NODE_BEFORE_AND_AFTER')
  @DocsEditable()
  @Experimental() // nonstandard
  static const int NODE_BEFORE_AND_AFTER = 2;

  @DomName('Range.NODE_INSIDE')
  @DocsEditable()
  @Experimental() // nonstandard
  static const int NODE_INSIDE = 3;

  @DomName('Range.START_TO_END')
  @DocsEditable()
  static const int START_TO_END = 1;

  @DomName('Range.START_TO_START')
  @DocsEditable()
  static const int START_TO_START = 0;

  @DomName('Range.collapsed')
  @DocsEditable()
  final bool collapsed;

  @DomName('Range.commonAncestorContainer')
  @DocsEditable()
  final Node commonAncestorContainer;

  @DomName('Range.endContainer')
  @DocsEditable()
  final Node endContainer;

  @DomName('Range.endOffset')
  @DocsEditable()
  final int endOffset;

  @DomName('Range.startContainer')
  @DocsEditable()
  final Node startContainer;

  @DomName('Range.startOffset')
  @DocsEditable()
  final int startOffset;

  @DomName('Range.cloneContents')
  @DocsEditable()
  DocumentFragment cloneContents() native;

  @DomName('Range.cloneRange')
  @DocsEditable()
  Range cloneRange() native;

  @DomName('Range.collapse')
  @DocsEditable()
  void collapse(bool toStart) native;

  @DomName('Range.comparePoint')
  @DocsEditable()
  int comparePoint(Node refNode, int offset) native;

  @DomName('Range.createContextualFragment')
  @DocsEditable()
  DocumentFragment createContextualFragment(String html) native;

  @DomName('Range.deleteContents')
  @DocsEditable()
  void deleteContents() native;

  @DomName('Range.detach')
  @DocsEditable()
  void detach() native;

  @DomName('Range.expand')
  @DocsEditable()
  @Experimental() // non-standard
  void expand(String unit) native;

  @DomName('Range.extractContents')
  @DocsEditable()
  DocumentFragment extractContents() native;

  @DomName('Range.getBoundingClientRect')
  @DocsEditable()
  Rectangle getBoundingClientRect() native;

  @DomName('Range.getClientRects')
  @DocsEditable()
  @Returns('_ClientRectList')
  @Creates('_ClientRectList')
  List<Rectangle> getClientRects() native;

  @DomName('Range.insertNode')
  @DocsEditable()
  void insertNode(Node newNode) native;

  @DomName('Range.isPointInRange')
  @DocsEditable()
  bool isPointInRange(Node refNode, int offset) native;

  @DomName('Range.selectNode')
  @DocsEditable()
  void selectNode(Node refNode) native;

  @DomName('Range.selectNodeContents')
  @DocsEditable()
  void selectNodeContents(Node refNode) native;

  @DomName('Range.setEnd')
  @DocsEditable()
  void setEnd(Node refNode, int offset) native;

  @DomName('Range.setEndAfter')
  @DocsEditable()
  void setEndAfter(Node refNode) native;

  @DomName('Range.setEndBefore')
  @DocsEditable()
  void setEndBefore(Node refNode) native;

  @DomName('Range.setStart')
  @DocsEditable()
  void setStart(Node refNode, int offset) native;

  @DomName('Range.setStartAfter')
  @DocsEditable()
  void setStartAfter(Node refNode) native;

  @DomName('Range.setStartBefore')
  @DocsEditable()
  void setStartBefore(Node refNode) native;

  @DomName('Range.surroundContents')
  @DocsEditable()
  void surroundContents(Node newParent) native;

  @DomName('Range.toString')
  @DocsEditable()
  String toString() native;


  /**
   * Checks if createContextualFragment is supported.
   *
   * See also:
   *
   * * [createContextualFragment]
   */
  static bool get supportsCreateContextualFragment =>
      JS('bool', '("createContextualFragment" in window.Range.prototype)');
}
// 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.


@DomName('RequestAnimationFrameCallback')
typedef void RequestAnimationFrameCallback(num highResTime);
// 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.


@DocsEditable()
@DomName('ResourceProgressEvent')
// https://chromiumcodereview.appspot.com/14773025/
@deprecated // experimental
class ResourceProgressEvent extends ProgressEvent native "ResourceProgressEvent" {
  // To suppress missing implicit constructor warnings.
  factory ResourceProgressEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('ResourceProgressEvent.url')
  @DocsEditable()
  final String url;
}
// 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.


@DocsEditable()
@DomName('RTCDataChannel')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCDataChannel
@Experimental()
class RtcDataChannel extends EventTarget native "RTCDataChannel,DataChannel" {
  // To suppress missing implicit constructor warnings.
  factory RtcDataChannel._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `close` events to event
   * handlers that are not necessarily instances of [RtcDataChannel].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCDataChannel.closeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> closeEvent = const EventStreamProvider<Event>('close');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [RtcDataChannel].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCDataChannel.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [RtcDataChannel].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCDataChannel.messageEvent')
  @DocsEditable()
  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');

  /**
   * Static factory designed to expose `open` events to event
   * handlers that are not necessarily instances of [RtcDataChannel].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCDataChannel.openEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> openEvent = const EventStreamProvider<Event>('open');

  @DomName('RTCDataChannel.binaryType')
  @DocsEditable()
  String binaryType;

  @DomName('RTCDataChannel.bufferedAmount')
  @DocsEditable()
  final int bufferedAmount;

  @DomName('RTCDataChannel.id')
  @DocsEditable()
  @Experimental() // untriaged
  final int id;

  @DomName('RTCDataChannel.label')
  @DocsEditable()
  final String label;

  @DomName('RTCDataChannel.maxRetransmitTime')
  @DocsEditable()
  @Experimental() // untriaged
  final int maxRetransmitTime;

  @DomName('RTCDataChannel.maxRetransmits')
  @DocsEditable()
  @Experimental() // untriaged
  final int maxRetransmits;

  @DomName('RTCDataChannel.negotiated')
  @DocsEditable()
  @Experimental() // untriaged
  final bool negotiated;

  @DomName('RTCDataChannel.ordered')
  @DocsEditable()
  @Experimental() // untriaged
  final bool ordered;

  @DomName('RTCDataChannel.protocol')
  @DocsEditable()
  @Experimental() // untriaged
  final String protocol;

  @DomName('RTCDataChannel.readyState')
  @DocsEditable()
  final String readyState;

  @DomName('RTCDataChannel.reliable')
  @DocsEditable()
  final bool reliable;

  @DomName('RTCDataChannel.close')
  @DocsEditable()
  void close() native;

  @DomName('RTCDataChannel.send')
  @DocsEditable()
  void send(data) native;

  @JSName('send')
  @DomName('RTCDataChannel.send')
  @DocsEditable()
  void sendBlob(Blob data) native;

  @JSName('send')
  @DomName('RTCDataChannel.send')
  @DocsEditable()
  void sendByteBuffer(ByteBuffer data) native;

  @JSName('send')
  @DomName('RTCDataChannel.send')
  @DocsEditable()
  void sendString(String data) native;

  @JSName('send')
  @DomName('RTCDataChannel.send')
  @DocsEditable()
  void sendTypedData(TypedData data) native;

  /// Stream of `close` events handled by this [RtcDataChannel].
  @DomName('RTCDataChannel.onclose')
  @DocsEditable()
  Stream<Event> get onClose => closeEvent.forTarget(this);

  /// Stream of `error` events handled by this [RtcDataChannel].
  @DomName('RTCDataChannel.onerror')
  @DocsEditable()
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `message` events handled by this [RtcDataChannel].
  @DomName('RTCDataChannel.onmessage')
  @DocsEditable()
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  /// Stream of `open` events handled by this [RtcDataChannel].
  @DomName('RTCDataChannel.onopen')
  @DocsEditable()
  Stream<Event> get onOpen => openEvent.forTarget(this);
}
// 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.


@DocsEditable()
@DomName('RTCDataChannelEvent')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#rtcdatachannelevent
@Experimental()
class RtcDataChannelEvent extends Event native "RTCDataChannelEvent" {
  // To suppress missing implicit constructor warnings.
  factory RtcDataChannelEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('RTCDataChannelEvent.channel')
  @DocsEditable()
  final RtcDataChannel channel;
}
// 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.


@DocsEditable()
@DomName('RTCDTMFSender')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCDTMFSender
@Experimental()
class RtcDtmfSender extends EventTarget native "RTCDTMFSender" {
  // To suppress missing implicit constructor warnings.
  factory RtcDtmfSender._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `tonechange` events to event
   * handlers that are not necessarily instances of [RtcDtmfSender].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCDTMFSender.tonechangeEvent')
  @DocsEditable()
  static const EventStreamProvider<RtcDtmfToneChangeEvent> toneChangeEvent = const EventStreamProvider<RtcDtmfToneChangeEvent>('tonechange');

  @JSName('canInsertDTMF')
  @DomName('RTCDTMFSender.canInsertDTMF')
  @DocsEditable()
  final bool canInsertDtmf;

  @DomName('RTCDTMFSender.duration')
  @DocsEditable()
  final int duration;

  @DomName('RTCDTMFSender.interToneGap')
  @DocsEditable()
  final int interToneGap;

  @DomName('RTCDTMFSender.toneBuffer')
  @DocsEditable()
  final String toneBuffer;

  @DomName('RTCDTMFSender.track')
  @DocsEditable()
  final MediaStreamTrack track;

  @JSName('insertDTMF')
  @DomName('RTCDTMFSender.insertDTMF')
  @DocsEditable()
  void insertDtmf(String tones, [int duration, int interToneGap]) native;

  /// Stream of `tonechange` events handled by this [RtcDtmfSender].
  @DomName('RTCDTMFSender.ontonechange')
  @DocsEditable()
  Stream<RtcDtmfToneChangeEvent> get onToneChange => toneChangeEvent.forTarget(this);
}
// 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.


@DocsEditable()
@DomName('RTCDTMFToneChangeEvent')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCDTMFToneChangeEvent
@Experimental()
class RtcDtmfToneChangeEvent extends Event native "RTCDTMFToneChangeEvent" {
  // To suppress missing implicit constructor warnings.
  factory RtcDtmfToneChangeEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('RTCDTMFToneChangeEvent.tone')
  @DocsEditable()
  final String tone;
}
// 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.


@DomName('RTCIceCandidate')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCIceCandidate
class RtcIceCandidate extends Interceptor native "RTCIceCandidate,mozRTCIceCandidate" {
  factory RtcIceCandidate(Map dictionary) {
    // TODO(efortuna): Remove this check if when you can actually construct with
    // the unprefixed RTCIceCandidate in Firefox (currently both are defined,
    // but one can't be used as a constructor).
    var constructorName = JS('', 'window[#]',
        Device.isFirefox ? '${Device.propertyPrefix}RTCIceCandidate' :
        'RTCIceCandidate');
    return JS('RtcIceCandidate', 'new #(#)', constructorName,
        convertDartToNative_SerializedScriptValue(dictionary));
  }
  // To suppress missing implicit constructor warnings.
  factory RtcIceCandidate._() { throw new UnsupportedError("Not supported"); }

  @DomName('RTCIceCandidate.candidate')
  @DocsEditable()
  final String candidate;

  @DomName('RTCIceCandidate.sdpMLineIndex')
  @DocsEditable()
  final int sdpMLineIndex;

  @DomName('RTCIceCandidate.sdpMid')
  @DocsEditable()
  final String sdpMid;

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


@DocsEditable()
@DomName('RTCIceCandidateEvent')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#rtcicecandidate-type
@Experimental()
class RtcIceCandidateEvent extends Event native "RTCIceCandidateEvent" {
  // To suppress missing implicit constructor warnings.
  factory RtcIceCandidateEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('RTCIceCandidateEvent.candidate')
  @DocsEditable()
  final RtcIceCandidate candidate;
}
// 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.


@DomName('RTCPeerConnection')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCPeerConnection
class RtcPeerConnection extends EventTarget native "RTCPeerConnection,mozRTCPeerConnection" {
  factory RtcPeerConnection(Map rtcIceServers, [Map mediaConstraints]) {
    var constructorName = JS('RtcPeerConnection', 'window[#]',
        '${Device.propertyPrefix}RTCPeerConnection');
    if (mediaConstraints != null) {
      return JS('RtcPeerConnection', 'new #(#,#)', constructorName,
          convertDartToNative_SerializedScriptValue(rtcIceServers),
          convertDartToNative_SerializedScriptValue(mediaConstraints));
    } else {
      return JS('RtcPeerConnection', 'new #(#)', constructorName,
          convertDartToNative_SerializedScriptValue(rtcIceServers));
    }
  }

  /**
   * Checks if Real Time Communication (RTC) APIs are supported and enabled on
   * the current platform.
   */
  static bool get supported {
    // Currently in Firefox some of the RTC elements are defined but throw an
    // error unless the user has specifically enabled them in their
    // about:config. So we have to construct an element to actually test if RTC
    // is supported at the given time.
    try {
      new RtcPeerConnection(
          {"iceServers": [ {"url":"stun:localhost"}]});
      return true;
    } catch (_) { return false;}
    return false;
  }
  Future<RtcSessionDescription> createOffer([Map mediaConstraints]) {
    var completer = new Completer<RtcSessionDescription>();
    _createOffer(
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); }, mediaConstraints);
    return completer.future;
  }

  Future<RtcSessionDescription> createAnswer([Map mediaConstraints]) {
    var completer = new Completer<RtcSessionDescription>();
    _createAnswer(
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); }, mediaConstraints);
    return completer.future;
  }

  @DomName('RTCPeerConnection.getStats')
  Future<RtcStatsResponse> getStats(MediaStreamTrack selector) {
    var completer = new Completer<RtcStatsResponse>();
    _getStats((value) { completer.complete(value); }, selector);
    return completer.future;
  }
  // To suppress missing implicit constructor warnings.
  factory RtcPeerConnection._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `addstream` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCPeerConnection.addstreamEvent')
  @DocsEditable()
  static const EventStreamProvider<MediaStreamEvent> addStreamEvent = const EventStreamProvider<MediaStreamEvent>('addstream');

  /**
   * Static factory designed to expose `datachannel` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCPeerConnection.datachannelEvent')
  @DocsEditable()
  static const EventStreamProvider<RtcDataChannelEvent> dataChannelEvent = const EventStreamProvider<RtcDataChannelEvent>('datachannel');

  /**
   * Static factory designed to expose `icecandidate` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCPeerConnection.icecandidateEvent')
  @DocsEditable()
  static const EventStreamProvider<RtcIceCandidateEvent> iceCandidateEvent = const EventStreamProvider<RtcIceCandidateEvent>('icecandidate');

  /**
   * Static factory designed to expose `iceconnectionstatechange` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCPeerConnection.iceconnectionstatechangeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> iceConnectionStateChangeEvent = const EventStreamProvider<Event>('iceconnectionstatechange');

  /**
   * Static factory designed to expose `negotiationneeded` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCPeerConnection.negotiationneededEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> negotiationNeededEvent = const EventStreamProvider<Event>('negotiationneeded');

  /**
   * Static factory designed to expose `removestream` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCPeerConnection.removestreamEvent')
  @DocsEditable()
  static const EventStreamProvider<MediaStreamEvent> removeStreamEvent = const EventStreamProvider<MediaStreamEvent>('removestream');

  /**
   * Static factory designed to expose `signalingstatechange` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCPeerConnection.signalingstatechangeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> signalingStateChangeEvent = const EventStreamProvider<Event>('signalingstatechange');

  @DomName('RTCPeerConnection.iceConnectionState')
  @DocsEditable()
  final String iceConnectionState;

  @DomName('RTCPeerConnection.iceGatheringState')
  @DocsEditable()
  final String iceGatheringState;

  @DomName('RTCPeerConnection.localDescription')
  @DocsEditable()
  final RtcSessionDescription localDescription;

  @DomName('RTCPeerConnection.remoteDescription')
  @DocsEditable()
  final RtcSessionDescription remoteDescription;

  @DomName('RTCPeerConnection.signalingState')
  @DocsEditable()
  final String signalingState;

  @DomName('RTCPeerConnection.addIceCandidate')
  @DocsEditable()
  void addIceCandidate(RtcIceCandidate candidate, VoidCallback successCallback, _RtcErrorCallback failureCallback) native;

  @DomName('RTCPeerConnection.addStream')
  @DocsEditable()
  void addStream(MediaStream stream, [Map mediaConstraints]) {
    if (mediaConstraints != null) {
      var mediaConstraints_1 = convertDartToNative_Dictionary(mediaConstraints);
      _addStream_1(stream, mediaConstraints_1);
      return;
    }
    _addStream_2(stream);
    return;
  }
  @JSName('addStream')
  @DomName('RTCPeerConnection.addStream')
  @DocsEditable()
  void _addStream_1(MediaStream stream, mediaConstraints) native;
  @JSName('addStream')
  @DomName('RTCPeerConnection.addStream')
  @DocsEditable()
  void _addStream_2(MediaStream stream) native;

  @DomName('RTCPeerConnection.close')
  @DocsEditable()
  void close() native;

  @DomName('RTCPeerConnection.createAnswer')
  @DocsEditable()
  void _createAnswer(_RtcSessionDescriptionCallback successCallback, [_RtcErrorCallback failureCallback, Map mediaConstraints]) {
    if (mediaConstraints != null) {
      var mediaConstraints_1 = convertDartToNative_Dictionary(mediaConstraints);
      _createAnswer_1(successCallback, failureCallback, mediaConstraints_1);
      return;
    }
    _createAnswer_2(successCallback, failureCallback);
    return;
  }
  @JSName('createAnswer')
  @DomName('RTCPeerConnection.createAnswer')
  @DocsEditable()
  void _createAnswer_1(_RtcSessionDescriptionCallback successCallback, _RtcErrorCallback failureCallback, mediaConstraints) native;
  @JSName('createAnswer')
  @DomName('RTCPeerConnection.createAnswer')
  @DocsEditable()
  void _createAnswer_2(_RtcSessionDescriptionCallback successCallback, _RtcErrorCallback failureCallback) native;

  @JSName('createDTMFSender')
  @DomName('RTCPeerConnection.createDTMFSender')
  @DocsEditable()
  RtcDtmfSender createDtmfSender(MediaStreamTrack track) native;

  @DomName('RTCPeerConnection.createDataChannel')
  @DocsEditable()
  RtcDataChannel createDataChannel(String label, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _createDataChannel_1(label, options_1);
    }
    return _createDataChannel_2(label);
  }
  @JSName('createDataChannel')
  @DomName('RTCPeerConnection.createDataChannel')
  @DocsEditable()
  RtcDataChannel _createDataChannel_1(label, options) native;
  @JSName('createDataChannel')
  @DomName('RTCPeerConnection.createDataChannel')
  @DocsEditable()
  RtcDataChannel _createDataChannel_2(label) native;

  @DomName('RTCPeerConnection.createOffer')
  @DocsEditable()
  void _createOffer(_RtcSessionDescriptionCallback successCallback, [_RtcErrorCallback failureCallback, Map mediaConstraints]) {
    if (mediaConstraints != null) {
      var mediaConstraints_1 = convertDartToNative_Dictionary(mediaConstraints);
      _createOffer_1(successCallback, failureCallback, mediaConstraints_1);
      return;
    }
    _createOffer_2(successCallback, failureCallback);
    return;
  }
  @JSName('createOffer')
  @DomName('RTCPeerConnection.createOffer')
  @DocsEditable()
  void _createOffer_1(_RtcSessionDescriptionCallback successCallback, _RtcErrorCallback failureCallback, mediaConstraints) native;
  @JSName('createOffer')
  @DomName('RTCPeerConnection.createOffer')
  @DocsEditable()
  void _createOffer_2(_RtcSessionDescriptionCallback successCallback, _RtcErrorCallback failureCallback) native;

  @DomName('RTCPeerConnection.getLocalStreams')
  @DocsEditable()
  List<MediaStream> getLocalStreams() native;

  @DomName('RTCPeerConnection.getRemoteStreams')
  @DocsEditable()
  List<MediaStream> getRemoteStreams() native;

  @JSName('getStats')
  @DomName('RTCPeerConnection.getStats')
  @DocsEditable()
  void _getStats(RtcStatsCallback successCallback, MediaStreamTrack selector) native;

  @DomName('RTCPeerConnection.getStreamById')
  @DocsEditable()
  MediaStream getStreamById(String streamId) native;

  @DomName('RTCPeerConnection.removeStream')
  @DocsEditable()
  void removeStream(MediaStream stream) native;

  @JSName('setLocalDescription')
  @DomName('RTCPeerConnection.setLocalDescription')
  @DocsEditable()
  void _setLocalDescription(RtcSessionDescription description, [VoidCallback successCallback, _RtcErrorCallback failureCallback]) native;

  @JSName('setLocalDescription')
  @DomName('RTCPeerConnection.setLocalDescription')
  @DocsEditable()
  Future setLocalDescription(RtcSessionDescription description) {
    var completer = new Completer();
    _setLocalDescription(description,
        () { completer.complete(); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  @JSName('setRemoteDescription')
  @DomName('RTCPeerConnection.setRemoteDescription')
  @DocsEditable()
  void _setRemoteDescription(RtcSessionDescription description, [VoidCallback successCallback, _RtcErrorCallback failureCallback]) native;

  @JSName('setRemoteDescription')
  @DomName('RTCPeerConnection.setRemoteDescription')
  @DocsEditable()
  Future setRemoteDescription(RtcSessionDescription description) {
    var completer = new Completer();
    _setRemoteDescription(description,
        () { completer.complete(); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  @DomName('RTCPeerConnection.updateIce')
  @DocsEditable()
  void updateIce([Map configuration, Map mediaConstraints]) {
    if (mediaConstraints != null) {
      var configuration_1 = convertDartToNative_Dictionary(configuration);
      var mediaConstraints_2 = convertDartToNative_Dictionary(mediaConstraints);
      _updateIce_1(configuration_1, mediaConstraints_2);
      return;
    }
    if (configuration != null) {
      var configuration_3 = convertDartToNative_Dictionary(configuration);
      _updateIce_2(configuration_3);
      return;
    }
    _updateIce_3();
    return;
  }
  @JSName('updateIce')
  @DomName('RTCPeerConnection.updateIce')
  @DocsEditable()
  void _updateIce_1(configuration, mediaConstraints) native;
  @JSName('updateIce')
  @DomName('RTCPeerConnection.updateIce')
  @DocsEditable()
  void _updateIce_2(configuration) native;
  @JSName('updateIce')
  @DomName('RTCPeerConnection.updateIce')
  @DocsEditable()
  void _updateIce_3() native;

  /// Stream of `addstream` events handled by this [RtcPeerConnection].
  @DomName('RTCPeerConnection.onaddstream')
  @DocsEditable()
  Stream<MediaStreamEvent> get onAddStream => addStreamEvent.forTarget(this);

  /// Stream of `datachannel` events handled by this [RtcPeerConnection].
  @DomName('RTCPeerConnection.ondatachannel')
  @DocsEditable()
  Stream<RtcDataChannelEvent> get onDataChannel => dataChannelEvent.forTarget(this);

  /// Stream of `icecandidate` events handled by this [RtcPeerConnection].
  @DomName('RTCPeerConnection.onicecandidate')
  @DocsEditable()
  Stream<RtcIceCandidateEvent> get onIceCandidate => iceCandidateEvent.forTarget(this);

  /// Stream of `iceconnectionstatechange` events handled by this [RtcPeerConnection].
  @DomName('RTCPeerConnection.oniceconnectionstatechange')
  @DocsEditable()
  Stream<Event> get onIceConnectionStateChange => iceConnectionStateChangeEvent.forTarget(this);

  /// Stream of `negotiationneeded` events handled by this [RtcPeerConnection].
  @DomName('RTCPeerConnection.onnegotiationneeded')
  @DocsEditable()
  Stream<Event> get onNegotiationNeeded => negotiationNeededEvent.forTarget(this);

  /// Stream of `removestream` events handled by this [RtcPeerConnection].
  @DomName('RTCPeerConnection.onremovestream')
  @DocsEditable()
  Stream<MediaStreamEvent> get onRemoveStream => removeStreamEvent.forTarget(this);

  /// Stream of `signalingstatechange` events handled by this [RtcPeerConnection].
  @DomName('RTCPeerConnection.onsignalingstatechange')
  @DocsEditable()
  Stream<Event> get onSignalingStateChange => signalingStateChangeEvent.forTarget(this);

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


@DomName('RTCSessionDescription')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCSessionDescription
class RtcSessionDescription extends Interceptor native "RTCSessionDescription,mozRTCSessionDescription" {
  factory RtcSessionDescription(Map dictionary) {
    // TODO(efortuna): Remove this check if when you can actually construct with
    // the unprefixed RTCIceCandidate in Firefox (currently both are defined,
    // but one can't be used as a constructor).
    var constructorName = JS('', 'window[#]',
        Device.isFirefox ? '${Device.propertyPrefix}RTCSessionDescription' :
       'RTCSessionDescription');
    return JS('RtcSessionDescription',
        'new #(#)', constructorName,
        convertDartToNative_SerializedScriptValue(dictionary));
  }
  // To suppress missing implicit constructor warnings.
  factory RtcSessionDescription._() { throw new UnsupportedError("Not supported"); }

  @DomName('RTCSessionDescription.sdp')
  @DocsEditable()
  String sdp;

  @DomName('RTCSessionDescription.type')
  @DocsEditable()
  String type;

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


@DocsEditable()
@DomName('RTCStatsReport')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCStatsReport
@Experimental()
class RtcStatsReport extends Interceptor native "RTCStatsReport" {
  // To suppress missing implicit constructor warnings.
  factory RtcStatsReport._() { throw new UnsupportedError("Not supported"); }

  @DomName('RTCStatsReport.id')
  @DocsEditable()
  final String id;

  @DomName('RTCStatsReport.local')
  @DocsEditable()
  final RtcStatsReport local;

  @DomName('RTCStatsReport.remote')
  @DocsEditable()
  final RtcStatsReport remote;

  @DomName('RTCStatsReport.timestamp')
  @DocsEditable()
  DateTime get timestamp => convertNativeToDart_DateTime(this._get_timestamp);
  @JSName('timestamp')
  @DomName('RTCStatsReport.timestamp')
  @DocsEditable()
  @Creates('Null')
  final dynamic _get_timestamp;

  @DomName('RTCStatsReport.type')
  @DocsEditable()
  final String type;

  @DomName('RTCStatsReport.names')
  @DocsEditable()
  List<String> names() native;

  @DomName('RTCStatsReport.stat')
  @DocsEditable()
  String stat(String name) native;
}
// 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.


@DocsEditable()
@DomName('RTCStatsResponse')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#widl-RTCStatsReport-RTCStats-getter-DOMString-id
@Experimental()
class RtcStatsResponse extends Interceptor native "RTCStatsResponse" {
  // To suppress missing implicit constructor warnings.
  factory RtcStatsResponse._() { throw new UnsupportedError("Not supported"); }

  @DomName('RTCStatsResponse.__getter__')
  @DocsEditable()
  RtcStatsReport __getter__(String name) native;

  @DomName('RTCStatsResponse.namedItem')
  @DocsEditable()
  RtcStatsReport namedItem(String name) native;

  @DomName('RTCStatsResponse.result')
  @DocsEditable()
  List<RtcStatsReport> result() native;
}
// 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.


@DocsEditable()
@DomName('Screen')
class Screen extends EventTarget native "Screen" {

  @DomName('Screen.availHeight')
  @DomName('Screen.availLeft')
  @DomName('Screen.availTop')
  @DomName('Screen.availWidth')
  Rectangle get available => new Rectangle(_availLeft, _availTop, _availWidth,
      _availHeight);
  // To suppress missing implicit constructor warnings.
  factory Screen._() { throw new UnsupportedError("Not supported"); }

  @JSName('availHeight')
  @DomName('Screen.availHeight')
  @DocsEditable()
  final int _availHeight;

  @JSName('availLeft')
  @DomName('Screen.availLeft')
  @DocsEditable()
  @Experimental() // nonstandard
  final int _availLeft;

  @JSName('availTop')
  @DomName('Screen.availTop')
  @DocsEditable()
  @Experimental() // nonstandard
  final int _availTop;

  @JSName('availWidth')
  @DomName('Screen.availWidth')
  @DocsEditable()
  final int _availWidth;

  @DomName('Screen.colorDepth')
  @DocsEditable()
  final int colorDepth;

  @DomName('Screen.height')
  @DocsEditable()
  final int height;

  @DomName('Screen.orientation')
  @DocsEditable()
  @Experimental() // untriaged
  final String orientation;

  @DomName('Screen.pixelDepth')
  @DocsEditable()
  final int pixelDepth;

  @DomName('Screen.width')
  @DocsEditable()
  final int width;

  @DomName('Screen.lockOrientation')
  @DocsEditable()
  @Experimental() // untriaged
  bool lockOrientation(String orientation) native;

  @DomName('Screen.unlockOrientation')
  @DocsEditable()
  @Experimental() // untriaged
  void unlockOrientation() native;
}
// 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.


@DocsEditable()
@DomName('HTMLScriptElement')
class ScriptElement extends HtmlElement native "HTMLScriptElement" {
  // To suppress missing implicit constructor warnings.
  factory ScriptElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLScriptElement.HTMLScriptElement')
  @DocsEditable()
  factory ScriptElement() => document.createElement("script");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ScriptElement.created() : super.created();

  @DomName('HTMLScriptElement.async')
  @DocsEditable()
  bool async;

  @DomName('HTMLScriptElement.charset')
  @DocsEditable()
  String charset;

  @DomName('HTMLScriptElement.crossOrigin')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#attr-script-crossorigin
  @Experimental()
  String crossOrigin;

  @DomName('HTMLScriptElement.defer')
  @DocsEditable()
  bool defer;

  @DomName('HTMLScriptElement.nonce')
  @DocsEditable()
  // https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#interaction-with-the-script-src-directive
  @Experimental()
  String nonce;

  @DomName('HTMLScriptElement.src')
  @DocsEditable()
  String src;

  @DomName('HTMLScriptElement.type')
  @DocsEditable()
  String type;
}
// 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.


@DocsEditable()
@DomName('SecurityPolicyViolationEvent')
// https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#securitypolicyviolationevent-events
@Experimental()
class SecurityPolicyViolationEvent extends Event native "SecurityPolicyViolationEvent" {
  // To suppress missing implicit constructor warnings.
  factory SecurityPolicyViolationEvent._() { throw new UnsupportedError("Not supported"); }

  @JSName('blockedURI')
  @DomName('SecurityPolicyViolationEvent.blockedURI')
  @DocsEditable()
  final String blockedUri;

  @DomName('SecurityPolicyViolationEvent.columnNumber')
  @DocsEditable()
  final int columnNumber;

  @JSName('documentURI')
  @DomName('SecurityPolicyViolationEvent.documentURI')
  @DocsEditable()
  final String documentUri;

  @DomName('SecurityPolicyViolationEvent.effectiveDirective')
  @DocsEditable()
  final String effectiveDirective;

  @DomName('SecurityPolicyViolationEvent.lineNumber')
  @DocsEditable()
  final int lineNumber;

  @DomName('SecurityPolicyViolationEvent.originalPolicy')
  @DocsEditable()
  final String originalPolicy;

  @DomName('SecurityPolicyViolationEvent.referrer')
  @DocsEditable()
  final String referrer;

  @DomName('SecurityPolicyViolationEvent.sourceFile')
  @DocsEditable()
  final String sourceFile;

  @DomName('SecurityPolicyViolationEvent.statusCode')
  @DocsEditable()
  @Experimental() // untriaged
  final int statusCode;

  @DomName('SecurityPolicyViolationEvent.violatedDirective')
  @DocsEditable()
  final String violatedDirective;
}
// 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.


@DomName('HTMLSelectElement')
class SelectElement extends HtmlElement native "HTMLSelectElement" {
  // To suppress missing implicit constructor warnings.
  factory SelectElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLSelectElement.HTMLSelectElement')
  @DocsEditable()
  factory SelectElement() => document.createElement("select");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  SelectElement.created() : super.created();

  @DomName('HTMLSelectElement.autofocus')
  @DocsEditable()
  bool autofocus;

  @DomName('HTMLSelectElement.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('HTMLSelectElement.form')
  @DocsEditable()
  final FormElement form;

  @DomName('HTMLSelectElement.labels')
  @DocsEditable()
  @Unstable()
  @Returns('NodeList')
  @Creates('NodeList')
  final List<Node> labels;

  @DomName('HTMLSelectElement.length')
  @DocsEditable()
  int length;

  @DomName('HTMLSelectElement.multiple')
  @DocsEditable()
  bool multiple;

  @DomName('HTMLSelectElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLSelectElement.required')
  @DocsEditable()
  bool required;

  @DomName('HTMLSelectElement.selectedIndex')
  @DocsEditable()
  int selectedIndex;

  @DomName('HTMLSelectElement.size')
  @DocsEditable()
  int size;

  @DomName('HTMLSelectElement.type')
  @DocsEditable()
  final String type;

  @DomName('HTMLSelectElement.validationMessage')
  @DocsEditable()
  final String validationMessage;

  @DomName('HTMLSelectElement.validity')
  @DocsEditable()
  final ValidityState validity;

  @DomName('HTMLSelectElement.value')
  @DocsEditable()
  String value;

  @DomName('HTMLSelectElement.willValidate')
  @DocsEditable()
  final bool willValidate;

  @DomName('HTMLSelectElement.__setter__')
  @DocsEditable()
  void __setter__(int index, OptionElement value) native;

  @DomName('HTMLSelectElement.checkValidity')
  @DocsEditable()
  bool checkValidity() native;

  @DomName('HTMLSelectElement.item')
  @DocsEditable()
  Element item(int index) native;

  @DomName('HTMLSelectElement.namedItem')
  @DocsEditable()
  Element namedItem(String name) native;

  @DomName('HTMLSelectElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) native;


  // Override default options, since IE returns SelectElement itself and it
  // does not operate as a List.
  List<OptionElement> get options {
    var options = this.querySelectorAll('option').where(
        (e) => e is OptionElement).toList();
    return new UnmodifiableListView(options);
  }

  List<OptionElement> get selectedOptions {
    // IE does not change the selected flag for single-selection items.
    if (this.multiple) {
      var options = this.options.where((o) => o.selected).toList();
      return new UnmodifiableListView(options);
    } else {
      return [this.options[this.selectedIndex]];
    }
  }
}
// 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.


@DocsEditable()
@DomName('Selection')
class Selection extends Interceptor native "Selection" {
  // To suppress missing implicit constructor warnings.
  factory Selection._() { throw new UnsupportedError("Not supported"); }

  @DomName('Selection.anchorNode')
  @DocsEditable()
  final Node anchorNode;

  @DomName('Selection.anchorOffset')
  @DocsEditable()
  final int anchorOffset;

  @DomName('Selection.baseNode')
  @DocsEditable()
  @Experimental() // non-standard
  final Node baseNode;

  @DomName('Selection.baseOffset')
  @DocsEditable()
  @Experimental() // non-standard
  final int baseOffset;

  @DomName('Selection.extentNode')
  @DocsEditable()
  @Experimental() // non-standard
  final Node extentNode;

  @DomName('Selection.extentOffset')
  @DocsEditable()
  @Experimental() // non-standard
  final int extentOffset;

  @DomName('Selection.focusNode')
  @DocsEditable()
  final Node focusNode;

  @DomName('Selection.focusOffset')
  @DocsEditable()
  final int focusOffset;

  @DomName('Selection.isCollapsed')
  @DocsEditable()
  final bool isCollapsed;

  @DomName('Selection.rangeCount')
  @DocsEditable()
  final int rangeCount;

  @DomName('Selection.type')
  @DocsEditable()
  @Experimental() // non-standard
  final String type;

  @DomName('Selection.addRange')
  @DocsEditable()
  void addRange(Range range) native;

  @DomName('Selection.collapse')
  @DocsEditable()
  void collapse(Node node, int index) native;

  @DomName('Selection.collapseToEnd')
  @DocsEditable()
  void collapseToEnd() native;

  @DomName('Selection.collapseToStart')
  @DocsEditable()
  void collapseToStart() native;

  @DomName('Selection.containsNode')
  @DocsEditable()
  @Experimental() // non-standard
  bool containsNode(Node node, bool allowPartial) native;

  @DomName('Selection.deleteFromDocument')
  @DocsEditable()
  void deleteFromDocument() native;

  @DomName('Selection.empty')
  @DocsEditable()
  @Experimental() // non-standard
  void empty() native;

  @DomName('Selection.extend')
  @DocsEditable()
  void extend(Node node, int offset) native;

  @DomName('Selection.getRangeAt')
  @DocsEditable()
  Range getRangeAt(int index) native;

  @DomName('Selection.modify')
  @DocsEditable()
  @Experimental() // non-standard
  void modify(String alter, String direction, String granularity) native;

  @DomName('Selection.removeAllRanges')
  @DocsEditable()
  void removeAllRanges() native;

  @DomName('Selection.selectAllChildren')
  @DocsEditable()
  void selectAllChildren(Node node) native;

  @DomName('Selection.setBaseAndExtent')
  @DocsEditable()
  @Experimental() // non-standard
  void setBaseAndExtent(Node baseNode, int baseOffset, Node extentNode, int extentOffset) native;

  @DomName('Selection.setPosition')
  @DocsEditable()
  @Experimental() // non-standard
  void setPosition(Node node, int offset) native;

  @DomName('Selection.toString')
  @DocsEditable()
  String toString() native;
}
// 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.


@DocsEditable()
@DomName('ServiceWorkerContainer')
@Experimental() // untriaged
class ServiceWorkerContainer extends Interceptor native "ServiceWorkerContainer" {
  // To suppress missing implicit constructor warnings.
  factory ServiceWorkerContainer._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('ServiceWorkerGlobalScope')
@Experimental() // untriaged
class ServiceWorkerGlobalScope extends WorkerGlobalScope native "ServiceWorkerGlobalScope" {
  // To suppress missing implicit constructor warnings.
  factory ServiceWorkerGlobalScope._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('HTMLShadowElement')
@SupportedBrowser(SupportedBrowser.CHROME, '26')
@Experimental()
// https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#shadow-element
class ShadowElement extends HtmlElement native "HTMLShadowElement" {
  // To suppress missing implicit constructor warnings.
  factory ShadowElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLShadowElement.HTMLShadowElement')
  @DocsEditable()
  factory ShadowElement() => document.createElement("shadow");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ShadowElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('shadow');

  @DomName('HTMLShadowElement.resetStyleInheritance')
  @DocsEditable()
  bool resetStyleInheritance;

  @DomName('HTMLShadowElement.getDistributedNodes')
  @DocsEditable()
  @Experimental() // untriaged
  @Returns('NodeList')
  @Creates('NodeList')
  List<Node> getDistributedNodes() native;
}
// 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.


@DomName('ShadowRoot')
@SupportedBrowser(SupportedBrowser.CHROME, '26')
@Experimental()
// https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#api-shadow-root
class ShadowRoot extends DocumentFragment native "ShadowRoot" {
  // To suppress missing implicit constructor warnings.
  factory ShadowRoot._() { throw new UnsupportedError("Not supported"); }

  @DomName('ShadowRoot.activeElement')
  @DocsEditable()
  final Element activeElement;

  @DomName('ShadowRoot.applyAuthorStyles')
  @DocsEditable()
  bool applyAuthorStyles;

  @DomName('ShadowRoot.host')
  @DocsEditable()
  @Experimental() // untriaged
  final Element host;

  @JSName('innerHTML')
  @DomName('ShadowRoot.innerHTML')
  @DocsEditable()
  String innerHtml;

  @DomName('ShadowRoot.olderShadowRoot')
  @DocsEditable()
  @Experimental() // untriaged
  final ShadowRoot olderShadowRoot;

  @JSName('resetStyleInheritance')
  @DomName('ShadowRoot.resetStyleInheritance')
  @DocsEditable()
  bool _resetStyleInheritance;

  @DomName('ShadowRoot.styleSheets')
  @DocsEditable()
  @Experimental() // untriaged
  @Returns('_StyleSheetList')
  @Creates('_StyleSheetList')
  final List<StyleSheet> styleSheets;

  @JSName('cloneNode')
  @DomName('ShadowRoot.cloneNode')
  @DocsEditable()
  Node clone(bool deep) native;

  @DomName('ShadowRoot.elementFromPoint')
  @DocsEditable()
  Element elementFromPoint(int x, int y) native;

  @DomName('ShadowRoot.getElementById')
  @DocsEditable()
  Element getElementById(String elementId) native;

  @DomName('ShadowRoot.getElementsByClassName')
  @DocsEditable()
  @Creates('NodeList|HtmlCollection')
  @Returns('NodeList|HtmlCollection')
  List<Node> getElementsByClassName(String className) native;

  @DomName('ShadowRoot.getElementsByTagName')
  @DocsEditable()
  @Creates('NodeList|HtmlCollection')
  @Returns('NodeList|HtmlCollection')
  List<Node> getElementsByTagName(String tagName) native;

  @DomName('ShadowRoot.getSelection')
  @DocsEditable()
  Selection getSelection() native;

  static bool get supported =>
      JS('bool', '!!(Element.prototype.webkitCreateShadowRoot)');

  @deprecated
  bool get resetStyleInheritance => this._resetStyleInheritance;

  @deprecated
  void set resetStyleInheritance(bool value) {
    this._resetStyleInheritance = value;
  }
}
// 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.


@DocsEditable()
@DomName('SharedWorker')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#shared-workers-and-the-sharedworker-interface
@Experimental()
class SharedWorker extends EventTarget implements AbstractWorker native "SharedWorker" {
  // To suppress missing implicit constructor warnings.
  factory SharedWorker._() { throw new UnsupportedError("Not supported"); }

  @DomName('SharedWorker.errorEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  @DomName('SharedWorker.SharedWorker')
  @DocsEditable()
  factory SharedWorker(String scriptURL, [String name]) {
    if (name != null) {
      return SharedWorker._create_1(scriptURL, name);
    }
    return SharedWorker._create_2(scriptURL);
  }
  static SharedWorker _create_1(scriptURL, name) => JS('SharedWorker', 'new SharedWorker(#,#)', scriptURL, name);
  static SharedWorker _create_2(scriptURL) => JS('SharedWorker', 'new SharedWorker(#)', scriptURL);

  @DomName('SharedWorker.port')
  @DocsEditable()
  final MessagePort port;

  @DomName('SharedWorker.workerStart')
  @DocsEditable()
  @Experimental() // untriaged
  final double workerStart;

  @DomName('SharedWorker.onerror')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onError => errorEvent.forTarget(this);
}
// 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.


@DocsEditable()
@DomName('SharedWorkerGlobalScope')
@Experimental() // untriaged
class SharedWorkerGlobalScope extends WorkerGlobalScope native "SharedWorkerGlobalScope" {
  // To suppress missing implicit constructor warnings.
  factory SharedWorkerGlobalScope._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `connect` events to event
   * handlers that are not necessarily instances of [SharedWorkerGlobalScope].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SharedWorkerGlobalScope.connectEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> connectEvent = const EventStreamProvider<Event>('connect');

  @DomName('SharedWorkerGlobalScope.name')
  @DocsEditable()
  @Experimental() // untriaged
  final String name;

  /// Stream of `connect` events handled by this [SharedWorkerGlobalScope].
  @DomName('SharedWorkerGlobalScope.onconnect')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onConnect => connectEvent.forTarget(this);
}
// 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.


@DocsEditable()
@DomName('SourceBuffer')
// https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#sourcebuffer
@Experimental()
class SourceBuffer extends EventTarget native "SourceBuffer" {
  // To suppress missing implicit constructor warnings.
  factory SourceBuffer._() { throw new UnsupportedError("Not supported"); }

  @DomName('SourceBuffer.appendWindowEnd')
  @DocsEditable()
  @Experimental() // untriaged
  num appendWindowEnd;

  @DomName('SourceBuffer.appendWindowStart')
  @DocsEditable()
  @Experimental() // untriaged
  num appendWindowStart;

  @DomName('SourceBuffer.buffered')
  @DocsEditable()
  final TimeRanges buffered;

  @DomName('SourceBuffer.mode')
  @DocsEditable()
  @Experimental() // untriaged
  String mode;

  @DomName('SourceBuffer.timestampOffset')
  @DocsEditable()
  num timestampOffset;

  @DomName('SourceBuffer.updating')
  @DocsEditable()
  @Experimental() // untriaged
  final bool updating;

  @DomName('SourceBuffer.abort')
  @DocsEditable()
  void abort() native;

  @DomName('SourceBuffer.appendBuffer')
  @DocsEditable()
  @Experimental() // untriaged
  void appendBuffer(ByteBuffer data) native;

  @DomName('SourceBuffer.appendStream')
  @DocsEditable()
  @Experimental() // untriaged
  void appendStream(FileStream stream, [int maxSize]) native;

  @JSName('appendBuffer')
  @DomName('SourceBuffer.appendBuffer')
  @DocsEditable()
  @Experimental() // untriaged
  void appendTypedData(TypedData data) native;

  @DomName('SourceBuffer.remove')
  @DocsEditable()
  @Experimental() // untriaged
  void remove(num start, num end) native;
}
// 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.


@DocsEditable()
@DomName('SourceBufferList')
// https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#sourcebufferlist
@Experimental()
class SourceBufferList extends EventTarget with ListMixin<SourceBuffer>, ImmutableListMixin<SourceBuffer> implements JavaScriptIndexingBehavior, List<SourceBuffer> native "SourceBufferList" {
  // To suppress missing implicit constructor warnings.
  factory SourceBufferList._() { throw new UnsupportedError("Not supported"); }

  @DomName('SourceBufferList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  SourceBuffer operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("SourceBuffer", "#[#]", this, index);
  }
  void operator[]=(int index, SourceBuffer value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<SourceBuffer> mixins.
  // SourceBuffer is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  SourceBuffer get first {
    if (this.length > 0) {
      return JS('SourceBuffer', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  SourceBuffer get last {
    int len = this.length;
    if (len > 0) {
      return JS('SourceBuffer', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  SourceBuffer get single {
    int len = this.length;
    if (len == 1) {
      return JS('SourceBuffer', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  SourceBuffer elementAt(int index) => this[index];
  // -- end List<SourceBuffer> mixins.

  @DomName('SourceBufferList.item')
  @DocsEditable()
  SourceBuffer item(int index) native;
}
// 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.


@DocsEditable()
@DomName('HTMLSourceElement')
class SourceElement extends HtmlElement native "HTMLSourceElement" {
  // To suppress missing implicit constructor warnings.
  factory SourceElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLSourceElement.HTMLSourceElement')
  @DocsEditable()
  factory SourceElement() => document.createElement("source");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  SourceElement.created() : super.created();

  @DomName('HTMLSourceElement.media')
  @DocsEditable()
  String media;

  @DomName('HTMLSourceElement.src')
  @DocsEditable()
  String src;

  @DomName('HTMLSourceElement.type')
  @DocsEditable()
  String type;
}
// 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.


@DocsEditable()
@DomName('SourceInfo')
@Experimental() // untriaged
class SourceInfo extends Interceptor native "SourceInfo" {
  // To suppress missing implicit constructor warnings.
  factory SourceInfo._() { throw new UnsupportedError("Not supported"); }

  @DomName('SourceInfo.facing')
  @DocsEditable()
  @Experimental() // untriaged
  final String facing;

  @DomName('SourceInfo.id')
  @DocsEditable()
  @Experimental() // untriaged
  final String id;

  @DomName('SourceInfo.kind')
  @DocsEditable()
  @Experimental() // untriaged
  final String kind;

  @DomName('SourceInfo.label')
  @DocsEditable()
  @Experimental() // untriaged
  final String label;
}
// 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.


@DocsEditable()
@DomName('HTMLSpanElement')
class SpanElement extends HtmlElement native "HTMLSpanElement" {
  // To suppress missing implicit constructor warnings.
  factory SpanElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLSpanElement.HTMLSpanElement')
  @DocsEditable()
  factory SpanElement() => document.createElement("span");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  SpanElement.created() : super.created();
}
// 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.


@DocsEditable()
@DomName('SpeechGrammar')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#dfn-speechgrammar
@Experimental()
class SpeechGrammar extends Interceptor native "SpeechGrammar" {
  // To suppress missing implicit constructor warnings.
  factory SpeechGrammar._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechGrammar.SpeechGrammar')
  @DocsEditable()
  factory SpeechGrammar() {
    return SpeechGrammar._create_1();
  }
  static SpeechGrammar _create_1() => JS('SpeechGrammar', 'new SpeechGrammar()');

  @DomName('SpeechGrammar.src')
  @DocsEditable()
  String src;

  @DomName('SpeechGrammar.weight')
  @DocsEditable()
  num weight;
}
// 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.


@DocsEditable()
@DomName('SpeechGrammarList')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#dfn-speechgrammarlist
@Experimental()
class SpeechGrammarList extends Interceptor with ListMixin<SpeechGrammar>, ImmutableListMixin<SpeechGrammar> implements JavaScriptIndexingBehavior, List<SpeechGrammar> native "SpeechGrammarList" {
  // To suppress missing implicit constructor warnings.
  factory SpeechGrammarList._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechGrammarList.SpeechGrammarList')
  @DocsEditable()
  factory SpeechGrammarList() {
    return SpeechGrammarList._create_1();
  }
  static SpeechGrammarList _create_1() => JS('SpeechGrammarList', 'new SpeechGrammarList()');

  @DomName('SpeechGrammarList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  SpeechGrammar operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("SpeechGrammar", "#[#]", this, index);
  }
  void operator[]=(int index, SpeechGrammar value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<SpeechGrammar> mixins.
  // SpeechGrammar is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  SpeechGrammar get first {
    if (this.length > 0) {
      return JS('SpeechGrammar', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  SpeechGrammar get last {
    int len = this.length;
    if (len > 0) {
      return JS('SpeechGrammar', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  SpeechGrammar get single {
    int len = this.length;
    if (len == 1) {
      return JS('SpeechGrammar', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  SpeechGrammar elementAt(int index) => this[index];
  // -- end List<SpeechGrammar> mixins.

  @DomName('SpeechGrammarList.addFromString')
  @DocsEditable()
  void addFromString(String string, [num weight]) native;

  @DomName('SpeechGrammarList.addFromUri')
  @DocsEditable()
  void addFromUri(String src, [num weight]) native;

  @DomName('SpeechGrammarList.item')
  @DocsEditable()
  SpeechGrammar item(int index) native;
}
// 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.


@DocsEditable()
@DomName('SpeechInputEvent')
// http://lists.w3.org/Archives/Public/public-xg-htmlspeech/2011Feb/att-0020/api-draft.html#speech_input_event_interface
@Experimental()
class SpeechInputEvent extends Event native "SpeechInputEvent" {
  // To suppress missing implicit constructor warnings.
  factory SpeechInputEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechInputEvent.results')
  @DocsEditable()
  @Returns('_SpeechInputResultList')
  @Creates('_SpeechInputResultList')
  final List<SpeechInputResult> results;
}
// 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.


@DocsEditable()
@DomName('SpeechInputResult')
// http://lists.w3.org/Archives/Public/public-xg-htmlspeech/2011Feb/att-0020/api-draft.html#speech_input_result_interface
@Experimental()
class SpeechInputResult extends Interceptor native "SpeechInputResult" {
  // To suppress missing implicit constructor warnings.
  factory SpeechInputResult._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechInputResult.confidence')
  @DocsEditable()
  final double confidence;

  @DomName('SpeechInputResult.utterance')
  @DocsEditable()
  final String utterance;
}
// 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.


@DomName('SpeechRecognition')
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechreco-section
class SpeechRecognition extends EventTarget native "SpeechRecognition" {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognition._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `audioend` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.audioendEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> audioEndEvent = const EventStreamProvider<Event>('audioend');

  /**
   * Static factory designed to expose `audiostart` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.audiostartEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> audioStartEvent = const EventStreamProvider<Event>('audiostart');

  /**
   * Static factory designed to expose `end` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.endEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> endEvent = const EventStreamProvider<Event>('end');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<SpeechRecognitionError> errorEvent = const EventStreamProvider<SpeechRecognitionError>('error');

  /**
   * Static factory designed to expose `nomatch` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.nomatchEvent')
  @DocsEditable()
  static const EventStreamProvider<SpeechRecognitionEvent> noMatchEvent = const EventStreamProvider<SpeechRecognitionEvent>('nomatch');

  /**
   * Static factory designed to expose `result` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.resultEvent')
  @DocsEditable()
  static const EventStreamProvider<SpeechRecognitionEvent> resultEvent = const EventStreamProvider<SpeechRecognitionEvent>('result');

  /**
   * Static factory designed to expose `soundend` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.soundendEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> soundEndEvent = const EventStreamProvider<Event>('soundend');

  /**
   * Static factory designed to expose `soundstart` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.soundstartEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> soundStartEvent = const EventStreamProvider<Event>('soundstart');

  /**
   * Static factory designed to expose `speechend` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.speechendEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> speechEndEvent = const EventStreamProvider<Event>('speechend');

  /**
   * Static factory designed to expose `speechstart` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.speechstartEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> speechStartEvent = const EventStreamProvider<Event>('speechstart');

  /**
   * Static factory designed to expose `start` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.startEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> startEvent = const EventStreamProvider<Event>('start');

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.SpeechRecognition || window.webkitSpeechRecognition)');

  @DomName('SpeechRecognition.continuous')
  @DocsEditable()
  bool continuous;

  @DomName('SpeechRecognition.grammars')
  @DocsEditable()
  SpeechGrammarList grammars;

  @DomName('SpeechRecognition.interimResults')
  @DocsEditable()
  bool interimResults;

  @DomName('SpeechRecognition.lang')
  @DocsEditable()
  String lang;

  @DomName('SpeechRecognition.maxAlternatives')
  @DocsEditable()
  int maxAlternatives;

  @DomName('SpeechRecognition.abort')
  @DocsEditable()
  void abort() native;

  @DomName('SpeechRecognition.start')
  @DocsEditable()
  void start() native;

  @DomName('SpeechRecognition.stop')
  @DocsEditable()
  void stop() native;

  /// Stream of `audioend` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onaudioend')
  @DocsEditable()
  Stream<Event> get onAudioEnd => audioEndEvent.forTarget(this);

  /// Stream of `audiostart` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onaudiostart')
  @DocsEditable()
  Stream<Event> get onAudioStart => audioStartEvent.forTarget(this);

  /// Stream of `end` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onend')
  @DocsEditable()
  Stream<Event> get onEnd => endEvent.forTarget(this);

  /// Stream of `error` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onerror')
  @DocsEditable()
  Stream<SpeechRecognitionError> get onError => errorEvent.forTarget(this);

  /// Stream of `nomatch` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onnomatch')
  @DocsEditable()
  Stream<SpeechRecognitionEvent> get onNoMatch => noMatchEvent.forTarget(this);

  /// Stream of `result` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onresult')
  @DocsEditable()
  Stream<SpeechRecognitionEvent> get onResult => resultEvent.forTarget(this);

  /// Stream of `soundend` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onsoundend')
  @DocsEditable()
  Stream<Event> get onSoundEnd => soundEndEvent.forTarget(this);

  /// Stream of `soundstart` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onsoundstart')
  @DocsEditable()
  Stream<Event> get onSoundStart => soundStartEvent.forTarget(this);

  /// Stream of `speechend` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onspeechend')
  @DocsEditable()
  Stream<Event> get onSpeechEnd => speechEndEvent.forTarget(this);

  /// Stream of `speechstart` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onspeechstart')
  @DocsEditable()
  Stream<Event> get onSpeechStart => speechStartEvent.forTarget(this);

  /// Stream of `start` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onstart')
  @DocsEditable()
  Stream<Event> get onStart => startEvent.forTarget(this);

  factory SpeechRecognition() {
    return JS('SpeechRecognition',
        'new (window.SpeechRecognition || window.webkitSpeechRecognition)()');
  }
}
// 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.


@DocsEditable()
@DomName('SpeechRecognitionAlternative')
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechrecognitionalternative
class SpeechRecognitionAlternative extends Interceptor native "SpeechRecognitionAlternative" {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionAlternative._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechRecognitionAlternative.confidence')
  @DocsEditable()
  final double confidence;

  @DomName('SpeechRecognitionAlternative.transcript')
  @DocsEditable()
  final String transcript;
}
// 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.


@DocsEditable()
@DomName('SpeechRecognitionError')
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechreco-error
class SpeechRecognitionError extends Event native "SpeechRecognitionError" {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionError._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechRecognitionError.error')
  @DocsEditable()
  final String error;

  @DomName('SpeechRecognitionError.message')
  @DocsEditable()
  final String message;
}
// 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.


@DocsEditable()
@DomName('SpeechRecognitionEvent')
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechreco-event
class SpeechRecognitionEvent extends Event native "SpeechRecognitionEvent" {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechRecognitionEvent.emma')
  @DocsEditable()
  final Document emma;

  @DomName('SpeechRecognitionEvent.interpretation')
  @DocsEditable()
  final Document interpretation;

  @DomName('SpeechRecognitionEvent.resultIndex')
  @DocsEditable()
  final int resultIndex;

  @DomName('SpeechRecognitionEvent.results')
  @DocsEditable()
  @Returns('_SpeechRecognitionResultList')
  @Creates('_SpeechRecognitionResultList')
  final List<SpeechRecognitionResult> results;
}
// 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.


@DocsEditable()
@DomName('SpeechRecognitionResult')
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechrecognitionresult
class SpeechRecognitionResult extends Interceptor native "SpeechRecognitionResult" {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionResult._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechRecognitionResult.isFinal')
  @DocsEditable()
  final bool isFinal;

  @DomName('SpeechRecognitionResult.length')
  @DocsEditable()
  final int length;

  @DomName('SpeechRecognitionResult.item')
  @DocsEditable()
  SpeechRecognitionAlternative item(int index) native;
}
// 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.


@DocsEditable()
@DomName('SpeechSynthesis')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section
@Experimental()
class SpeechSynthesis extends EventTarget native "SpeechSynthesis" {
  // To suppress missing implicit constructor warnings.
  factory SpeechSynthesis._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechSynthesis.paused')
  @DocsEditable()
  final bool paused;

  @DomName('SpeechSynthesis.pending')
  @DocsEditable()
  final bool pending;

  @DomName('SpeechSynthesis.speaking')
  @DocsEditable()
  final bool speaking;

  @DomName('SpeechSynthesis.cancel')
  @DocsEditable()
  void cancel() native;

  @DomName('SpeechSynthesis.getVoices')
  @DocsEditable()
  List<SpeechSynthesisVoice> getVoices() native;

  @DomName('SpeechSynthesis.pause')
  @DocsEditable()
  void pause() native;

  @DomName('SpeechSynthesis.resume')
  @DocsEditable()
  void resume() native;

  @DomName('SpeechSynthesis.speak')
  @DocsEditable()
  void speak(SpeechSynthesisUtterance utterance) native;
}
// 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.


@DocsEditable()
@DomName('SpeechSynthesisEvent')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section
@Experimental()
class SpeechSynthesisEvent extends Event native "SpeechSynthesisEvent" {
  // To suppress missing implicit constructor warnings.
  factory SpeechSynthesisEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechSynthesisEvent.charIndex')
  @DocsEditable()
  final int charIndex;

  @DomName('SpeechSynthesisEvent.elapsedTime')
  @DocsEditable()
  final double elapsedTime;

  @DomName('SpeechSynthesisEvent.name')
  @DocsEditable()
  final String name;
}
// 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.


@DocsEditable()
@DomName('SpeechSynthesisUtterance')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section
@Experimental()
class SpeechSynthesisUtterance extends EventTarget native "SpeechSynthesisUtterance" {
  // To suppress missing implicit constructor warnings.
  factory SpeechSynthesisUtterance._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `boundary` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechSynthesisUtterance.boundaryEvent')
  @DocsEditable()
  static const EventStreamProvider<SpeechSynthesisEvent> boundaryEvent = const EventStreamProvider<SpeechSynthesisEvent>('boundary');

  /**
   * Static factory designed to expose `end` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechSynthesisUtterance.endEvent')
  @DocsEditable()
  static const EventStreamProvider<SpeechSynthesisEvent> endEvent = const EventStreamProvider<SpeechSynthesisEvent>('end');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechSynthesisUtterance.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `mark` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechSynthesisUtterance.markEvent')
  @DocsEditable()
  static const EventStreamProvider<SpeechSynthesisEvent> markEvent = const EventStreamProvider<SpeechSynthesisEvent>('mark');

  /**
   * Static factory designed to expose `pause` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechSynthesisUtterance.pauseEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> pauseEvent = const EventStreamProvider<Event>('pause');

  /**
   * Static factory designed to expose `resume` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechSynthesisUtterance.resumeEvent')
  @DocsEditable()
  static const EventStreamProvider<SpeechSynthesisEvent> resumeEvent = const EventStreamProvider<SpeechSynthesisEvent>('resume');

  /**
   * Static factory designed to expose `start` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechSynthesisUtterance.startEvent')
  @DocsEditable()
  static const EventStreamProvider<SpeechSynthesisEvent> startEvent = const EventStreamProvider<SpeechSynthesisEvent>('start');

  @DomName('SpeechSynthesisUtterance.SpeechSynthesisUtterance')
  @DocsEditable()
  factory SpeechSynthesisUtterance([String text]) {
    if (text != null) {
      return SpeechSynthesisUtterance._create_1(text);
    }
    return SpeechSynthesisUtterance._create_2();
  }
  static SpeechSynthesisUtterance _create_1(text) => JS('SpeechSynthesisUtterance', 'new SpeechSynthesisUtterance(#)', text);
  static SpeechSynthesisUtterance _create_2() => JS('SpeechSynthesisUtterance', 'new SpeechSynthesisUtterance()');

  @DomName('SpeechSynthesisUtterance.lang')
  @DocsEditable()
  String lang;

  @DomName('SpeechSynthesisUtterance.pitch')
  @DocsEditable()
  num pitch;

  @DomName('SpeechSynthesisUtterance.rate')
  @DocsEditable()
  num rate;

  @DomName('SpeechSynthesisUtterance.text')
  @DocsEditable()
  String text;

  @DomName('SpeechSynthesisUtterance.voice')
  @DocsEditable()
  SpeechSynthesisVoice voice;

  @DomName('SpeechSynthesisUtterance.volume')
  @DocsEditable()
  num volume;

  /// Stream of `boundary` events handled by this [SpeechSynthesisUtterance].
  @DomName('SpeechSynthesisUtterance.onboundary')
  @DocsEditable()
  Stream<SpeechSynthesisEvent> get onBoundary => boundaryEvent.forTarget(this);

  /// Stream of `end` events handled by this [SpeechSynthesisUtterance].
  @DomName('SpeechSynthesisUtterance.onend')
  @DocsEditable()
  Stream<SpeechSynthesisEvent> get onEnd => endEvent.forTarget(this);

  /// Stream of `error` events handled by this [SpeechSynthesisUtterance].
  @DomName('SpeechSynthesisUtterance.onerror')
  @DocsEditable()
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `mark` events handled by this [SpeechSynthesisUtterance].
  @DomName('SpeechSynthesisUtterance.onmark')
  @DocsEditable()
  Stream<SpeechSynthesisEvent> get onMark => markEvent.forTarget(this);

  /// Stream of `pause` events handled by this [SpeechSynthesisUtterance].
  @DomName('SpeechSynthesisUtterance.onpause')
  @DocsEditable()
  Stream<Event> get onPause => pauseEvent.forTarget(this);

  /// Stream of `resume` events handled by this [SpeechSynthesisUtterance].
  @DomName('SpeechSynthesisUtterance.onresume')
  @DocsEditable()
  Stream<SpeechSynthesisEvent> get onResume => resumeEvent.forTarget(this);

  /// Stream of `start` events handled by this [SpeechSynthesisUtterance].
  @DomName('SpeechSynthesisUtterance.onstart')
  @DocsEditable()
  Stream<SpeechSynthesisEvent> get onStart => startEvent.forTarget(this);
}
// 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.


@DocsEditable()
@DomName('SpeechSynthesisVoice')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section
@Experimental()
class SpeechSynthesisVoice extends Interceptor native "SpeechSynthesisVoice" {
  // To suppress missing implicit constructor warnings.
  factory SpeechSynthesisVoice._() { throw new UnsupportedError("Not supported"); }

  @JSName('default')
  @DomName('SpeechSynthesisVoice.default')
  @DocsEditable()
  final bool defaultValue;

  @DomName('SpeechSynthesisVoice.lang')
  @DocsEditable()
  final String lang;

  @DomName('SpeechSynthesisVoice.localService')
  @DocsEditable()
  final bool localService;

  @DomName('SpeechSynthesisVoice.name')
  @DocsEditable()
  final String name;

  @JSName('voiceURI')
  @DomName('SpeechSynthesisVoice.voiceURI')
  @DocsEditable()
  final String voiceUri;
}
// 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.


/**
 * The type used by the
 * [Window.localStorage] and [Window.sessionStorage] properties.
 * Storage is implemented as a Map&lt;String, String>.
 *
 * To store and get values, use Dart's built-in map syntax:
 *
 *     window.localStorage['key1'] = 'val1';
 *     window.localStorage['key2'] = 'val2';
 *     window.localStorage['key3'] = 'val3';
 *     assert(window.localStorage['key3'] == 'val3');
 *
 * You can use [Map](http://api.dartlang.org/dart_core/Map.html) APIs
 * such as containsValue(), clear(), and length:
 *
 *     assert(window.localStorage.containsValue('does not exist') == false);
 *     window.localStorage.clear();
 *     assert(window.localStorage.length == 0);
 *
 * For more examples of using this API, see
 * [localstorage_test.dart](http://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/tests/html/localstorage_test.dart).
 * For details on using the Map API, see the
 * [Maps](http://www.dartlang.org/docs/library-tour/#maps-aka-dictionaries-or-hashes)
 * section of the library tour.
 */
@DomName('Storage')
@Unstable()
class Storage extends Interceptor
    implements Map<String, String>  native "Storage" {

  void addAll(Map<String, String> other) {
    other.forEach((k, v) { this[k] = v; });
  }

  // TODO(nweiz): update this when maps support lazy iteration
  bool containsValue(String value) => values.any((e) => e == value);

  bool containsKey(String key) => _getItem(key) != null;

  String operator [](String key) => _getItem(key);

  void operator []=(String key, String value) { _setItem(key, value); }

  String putIfAbsent(String key, String ifAbsent()) {
    if (!containsKey(key)) this[key] = ifAbsent();
    return this[key];
  }

  String remove(String key) {
    final value = this[key];
    _removeItem(key);
    return value;
  }

  void clear() => _clear();

  void forEach(void f(String key, String value)) {
    for (var i = 0; true; i++) {
      final key = _key(i);
      if (key == null) return;

      f(key, this[key]);
    }
  }

  Iterable<String> get keys {
    final keys = [];
    forEach((k, v) => keys.add(k));
    return keys;
  }

  Iterable<String> get values {
    final values = [];
    forEach((k, v) => values.add(v));
    return values;
  }

  int get length => _length;

  bool get isEmpty => _key(0) == null;

  bool get isNotEmpty => !isEmpty;
  // To suppress missing implicit constructor warnings.
  factory Storage._() { throw new UnsupportedError("Not supported"); }

  @JSName('length')
  @DomName('Storage.length')
  @DocsEditable()
  final int _length;

  @DomName('Storage.__delete__')
  @DocsEditable()
  bool __delete__(index_OR_name) native;

  @DomName('Storage.__getter__')
  @DocsEditable()
  String __getter__(index_OR_name) native;

  @DomName('Storage.__setter__')
  @DocsEditable()
  void __setter__(index_OR_name, String value) native;

  @JSName('clear')
  @DomName('Storage.clear')
  @DocsEditable()
  void _clear() native;

  @JSName('getItem')
  @DomName('Storage.getItem')
  @DocsEditable()
  String _getItem(String key) native;

  @JSName('key')
  @DomName('Storage.key')
  @DocsEditable()
  String _key(int index) native;

  @JSName('removeItem')
  @DomName('Storage.removeItem')
  @DocsEditable()
  void _removeItem(String key) native;

  @JSName('setItem')
  @DomName('Storage.setItem')
  @DocsEditable()
  void _setItem(String key, String data) native;

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


@DomName('StorageErrorCallback')
// http://www.w3.org/TR/quota-api/#storageerrorcallback-callback
@Experimental()
typedef void StorageErrorCallback(DomError error);
// 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.

// WARNING: Do not edit - generated code.


@DomName('StorageEvent')
@Unstable()
class StorageEvent extends Event native "StorageEvent" {
  factory StorageEvent(String type,
    {bool canBubble: false, bool cancelable: false, String key, String oldValue,
    String newValue, String url, Storage storageArea}) {

    var e = document._createEvent("StorageEvent");
    e._initStorageEvent(type, canBubble, cancelable, key, oldValue,
        newValue, url, storageArea);
    return e;
  }
  // To suppress missing implicit constructor warnings.
  factory StorageEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('StorageEvent.key')
  @DocsEditable()
  final String key;

  @DomName('StorageEvent.newValue')
  @DocsEditable()
  final String newValue;

  @DomName('StorageEvent.oldValue')
  @DocsEditable()
  final String oldValue;

  @DomName('StorageEvent.storageArea')
  @DocsEditable()
  final Storage storageArea;

  @DomName('StorageEvent.url')
  @DocsEditable()
  final String url;

  @JSName('initStorageEvent')
  @DomName('StorageEvent.initStorageEvent')
  @DocsEditable()
  void _initStorageEvent(String typeArg, bool canBubbleArg, bool cancelableArg, String keyArg, String oldValueArg, String newValueArg, String urlArg, Storage storageAreaArg) native;

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


@DocsEditable()
@DomName('StorageInfo')
// http://www.w3.org/TR/file-system-api/
@Experimental()
class StorageInfo extends Interceptor native "StorageInfo" {
  // To suppress missing implicit constructor warnings.
  factory StorageInfo._() { throw new UnsupportedError("Not supported"); }

  @DomName('StorageInfo.quota')
  @DocsEditable()
  @Experimental() // untriaged
  final int quota;

  @DomName('StorageInfo.usage')
  @DocsEditable()
  @Experimental() // untriaged
  final int usage;
}
// 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.


@DocsEditable()
@DomName('StorageQuota')
// http://www.w3.org/TR/quota-api/#idl-def-StorageQuota
@Experimental()
class StorageQuota extends Interceptor native "StorageQuota" {
  // To suppress missing implicit constructor warnings.
  factory StorageQuota._() { throw new UnsupportedError("Not supported"); }

  @DomName('StorageQuota.supportedTypes')
  @DocsEditable()
  @Experimental() // untriaged
  final List<String> supportedTypes;
}
// 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.


@DomName('StorageQuotaCallback')
// http://www.w3.org/TR/quota-api/#idl-def-StorageQuotaCallback
@Experimental()
typedef void StorageQuotaCallback(int grantedQuotaInBytes);
// 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.


@DomName('StorageUsageCallback')
// http://www.w3.org/TR/quota-api/#idl-def-StorageUsageCallback
@Experimental()
typedef void StorageUsageCallback(int currentUsageInBytes, int currentQuotaInBytes);
// 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.


@DomName('StringCallback')
// http://www.w3.org/TR/2011/WD-html5-20110113/dnd.html#the-datatransferitem-interface
@Experimental()
typedef void _StringCallback(String data);
// 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.


@DocsEditable()
@DomName('HTMLStyleElement')
class StyleElement extends HtmlElement native "HTMLStyleElement" {
  // To suppress missing implicit constructor warnings.
  factory StyleElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLStyleElement.HTMLStyleElement')
  @DocsEditable()
  factory StyleElement() => document.createElement("style");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  StyleElement.created() : super.created();

  @DomName('HTMLStyleElement.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('HTMLStyleElement.media')
  @DocsEditable()
  String media;

  @DomName('HTMLStyleElement.scoped')
  @DocsEditable()
  bool scoped;

  @DomName('HTMLStyleElement.sheet')
  @DocsEditable()
  final StyleSheet sheet;

  @DomName('HTMLStyleElement.type')
  @DocsEditable()
  String type;
}
// 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.


@DocsEditable()
@DomName('StyleMedia')
// http://developer.apple.com/library/safari/#documentation/SafariDOMAdditions/Reference/StyleMedia/StyleMedia/StyleMedia.html
@Experimental() // nonstandard
class StyleMedia extends Interceptor native "StyleMedia" {
  // To suppress missing implicit constructor warnings.
  factory StyleMedia._() { throw new UnsupportedError("Not supported"); }

  @DomName('StyleMedia.type')
  @DocsEditable()
  final String type;

  @DomName('StyleMedia.matchMedium')
  @DocsEditable()
  bool matchMedium(String mediaquery) native;
}
// 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.


@DocsEditable()
@DomName('StyleSheet')
class StyleSheet extends Interceptor native "StyleSheet" {
  // To suppress missing implicit constructor warnings.
  factory StyleSheet._() { throw new UnsupportedError("Not supported"); }

  @DomName('StyleSheet.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('StyleSheet.href')
  @DocsEditable()
  final String href;

  @DomName('StyleSheet.media')
  @DocsEditable()
  final MediaList media;

  @DomName('StyleSheet.ownerNode')
  @DocsEditable()
  final Node ownerNode;

  @DomName('StyleSheet.parentStyleSheet')
  @DocsEditable()
  final StyleSheet parentStyleSheet;

  @DomName('StyleSheet.title')
  @DocsEditable()
  final String title;

  @DomName('StyleSheet.type')
  @DocsEditable()
  final String type;
}
// 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.


@DocsEditable()
@DomName('HTMLTableCaptionElement')
class TableCaptionElement extends HtmlElement native "HTMLTableCaptionElement" {
  // To suppress missing implicit constructor warnings.
  factory TableCaptionElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLTableCaptionElement.HTMLTableCaptionElement')
  @DocsEditable()
  factory TableCaptionElement() => document.createElement("caption");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableCaptionElement.created() : super.created();
}
// 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.


@DocsEditable()
@DomName('HTMLTableCellElement')
class TableCellElement extends HtmlElement native "HTMLTableCellElement,HTMLTableDataCellElement,HTMLTableHeaderCellElement" {
  // To suppress missing implicit constructor warnings.
  factory TableCellElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLTableCellElement.HTMLTableCellElement')
  @DocsEditable()
  factory TableCellElement() => document.createElement("td");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableCellElement.created() : super.created();

  @DomName('HTMLTableCellElement.cellIndex')
  @DocsEditable()
  final int cellIndex;

  @DomName('HTMLTableCellElement.colSpan')
  @DocsEditable()
  int colSpan;

  @DomName('HTMLTableCellElement.headers')
  @DocsEditable()
  String headers;

  @DomName('HTMLTableCellElement.rowSpan')
  @DocsEditable()
  int rowSpan;
}
// 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.


@DocsEditable()
@DomName('HTMLTableColElement')
class TableColElement extends HtmlElement native "HTMLTableColElement" {
  // To suppress missing implicit constructor warnings.
  factory TableColElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLTableColElement.HTMLTableColElement')
  @DocsEditable()
  factory TableColElement() => document.createElement("col");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableColElement.created() : super.created();

  @DomName('HTMLTableColElement.span')
  @DocsEditable()
  int span;
}
// 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.


@DocsEditable()
@DomName('HTMLTableElement')
class TableElement extends HtmlElement native "HTMLTableElement" {

  @DomName('HTMLTableElement.tBodies')
  List<TableSectionElement> get tBodies =>
  new _WrappedList<TableSectionElement>(_tBodies);

  @DomName('HTMLTableElement.rows')
  List<TableRowElement> get rows =>
      new _WrappedList<TableRowElement>(_rows);

  TableRowElement addRow() {
    return insertRow(-1);
  }

  TableCaptionElement createCaption() => _createCaption();
  TableSectionElement createTBody() => _createTBody();
  TableSectionElement createTFoot() => _createTFoot();
  TableSectionElement createTHead() => _createTHead();
  TableRowElement insertRow(int index) => _insertRow(index);

  TableSectionElement _createTBody() {
    if (JS('bool', '!!#.createTBody', this)) {
      return this._nativeCreateTBody();
    }
    var tbody = new Element.tag('tbody');
    this.children.add(tbody);
    return tbody;
  }

  @JSName('createTBody')
  TableSectionElement _nativeCreateTBody() native;

  DocumentFragment createFragment(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    if (Range.supportsCreateContextualFragment) {
      return super.createFragment(
          html, validator: validator, treeSanitizer: treeSanitizer);
    }
    // IE9 workaround which does not support innerHTML on Table elements.
    var contextualHtml = '<table>$html</table>';
    var table = new Element.html(contextualHtml, validator: validator,
        treeSanitizer: treeSanitizer);
    var fragment = new DocumentFragment();
    fragment.nodes.addAll(table.nodes);

    return fragment;
  }

  // To suppress missing implicit constructor warnings.
  factory TableElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLTableElement.HTMLTableElement')
  @DocsEditable()
  factory TableElement() => document.createElement("table");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableElement.created() : super.created();

  @DomName('HTMLTableElement.caption')
  @DocsEditable()
  TableCaptionElement caption;

  @JSName('rows')
  @DomName('HTMLTableElement.rows')
  @DocsEditable()
  @Returns('HtmlCollection')
  @Creates('HtmlCollection')
  final List<Node> _rows;

  @JSName('tBodies')
  @DomName('HTMLTableElement.tBodies')
  @DocsEditable()
  @Returns('HtmlCollection')
  @Creates('HtmlCollection')
  final List<Node> _tBodies;

  @DomName('HTMLTableElement.tFoot')
  @DocsEditable()
  TableSectionElement tFoot;

  @DomName('HTMLTableElement.tHead')
  @DocsEditable()
  TableSectionElement tHead;

  @JSName('createCaption')
  @DomName('HTMLTableElement.createCaption')
  @DocsEditable()
  HtmlElement _createCaption() native;

  @JSName('createTFoot')
  @DomName('HTMLTableElement.createTFoot')
  @DocsEditable()
  HtmlElement _createTFoot() native;

  @JSName('createTHead')
  @DomName('HTMLTableElement.createTHead')
  @DocsEditable()
  HtmlElement _createTHead() native;

  @DomName('HTMLTableElement.deleteCaption')
  @DocsEditable()
  void deleteCaption() native;

  @DomName('HTMLTableElement.deleteRow')
  @DocsEditable()
  void deleteRow(int index) native;

  @DomName('HTMLTableElement.deleteTFoot')
  @DocsEditable()
  void deleteTFoot() native;

  @DomName('HTMLTableElement.deleteTHead')
  @DocsEditable()
  void deleteTHead() native;

  @JSName('insertRow')
  @DomName('HTMLTableElement.insertRow')
  @DocsEditable()
  HtmlElement _insertRow(int index) native;
}
// 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.


@DocsEditable()
@DomName('HTMLTableRowElement')
class TableRowElement extends HtmlElement native "HTMLTableRowElement" {

  @DomName('HTMLTableRowElement.cells')
  List<TableCellElement> get cells =>
      new _WrappedList<TableCellElement>(_cells);

  TableCellElement addCell() {
    return insertCell(-1);
  }

  TableCellElement insertCell(int index) => _insertCell(index);

  DocumentFragment createFragment(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    if (Range.supportsCreateContextualFragment) {
      return super.createFragment(
          html, validator: validator, treeSanitizer: treeSanitizer);
    }
    // IE9 workaround which does not support innerHTML on Table elements.
    var fragment = new DocumentFragment();
    var section = new TableElement().createFragment(
        html, validator: validator, treeSanitizer: treeSanitizer).nodes.single;
    var row = section.nodes.single;
    fragment.nodes.addAll(row.nodes);
    return fragment;
  }

  // To suppress missing implicit constructor warnings.
  factory TableRowElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLTableRowElement.HTMLTableRowElement')
  @DocsEditable()
  factory TableRowElement() => document.createElement("tr");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableRowElement.created() : super.created();

  @JSName('cells')
  @DomName('HTMLTableRowElement.cells')
  @DocsEditable()
  @Returns('HtmlCollection')
  @Creates('HtmlCollection')
  final List<Node> _cells;

  @DomName('HTMLTableRowElement.rowIndex')
  @DocsEditable()
  final int rowIndex;

  @DomName('HTMLTableRowElement.sectionRowIndex')
  @DocsEditable()
  final int sectionRowIndex;

  @DomName('HTMLTableRowElement.deleteCell')
  @DocsEditable()
  void deleteCell(int index) native;

  @JSName('insertCell')
  @DomName('HTMLTableRowElement.insertCell')
  @DocsEditable()
  HtmlElement _insertCell(int index) native;
}
// 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.


@DocsEditable()
@DomName('HTMLTableSectionElement')
class TableSectionElement extends HtmlElement native "HTMLTableSectionElement" {

  @DomName('HTMLTableSectionElement.rows')
  List<TableRowElement> get rows =>
    new _WrappedList<TableRowElement>(_rows);

  TableRowElement addRow() {
    return insertRow(-1);
  }

  TableRowElement insertRow(int index) => _insertRow(index);

  DocumentFragment createFragment(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    if (Range.supportsCreateContextualFragment) {
      return super.createFragment(
          html, validator: validator, treeSanitizer: treeSanitizer);
    }
    // IE9 workaround which does not support innerHTML on Table elements.
    var fragment = new DocumentFragment();
    var section = new TableElement().createFragment(
        html, validator: validator, treeSanitizer: treeSanitizer).nodes.single;
    fragment.nodes.addAll(section.nodes);
    return fragment;
  }

  // To suppress missing implicit constructor warnings.
  factory TableSectionElement._() { throw new UnsupportedError("Not supported"); }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableSectionElement.created() : super.created();

  @JSName('rows')
  @DomName('HTMLTableSectionElement.rows')
  @DocsEditable()
  @Returns('HtmlCollection')
  @Creates('HtmlCollection')
  final List<Node> _rows;

  @DomName('HTMLTableSectionElement.deleteRow')
  @DocsEditable()
  void deleteRow(int index) native;

  @JSName('insertRow')
  @DomName('HTMLTableSectionElement.insertRow')
  @DocsEditable()
  HtmlElement _insertRow(int index) native;
}
// 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.

// WARNING: Do not edit - generated code.


@Experimental()
@DomName('HTMLTemplateElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#template-element
class TemplateElement extends HtmlElement native "HTMLTemplateElement" {
  // To suppress missing implicit constructor warnings.
  factory TemplateElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLTemplateElement.HTMLTemplateElement')
  @DocsEditable()
  factory TemplateElement() => document.createElement("template");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TemplateElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('template');

  @DomName('HTMLTemplateElement.content')
  @DocsEditable()
  final DocumentFragment content;


  /**
   * An override to place the contents into content rather than as child nodes.
   *
   * See also:
   *
   * * <https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#innerhtml-on-templates>
   */
  void setInnerHtml(String html,
    {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    text = null;
    var fragment = createFragment(
        html, validator: validator, treeSanitizer: treeSanitizer);

    content.append(fragment);
  }
}
// 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.


@DomName('Text')
class Text extends CharacterData native "Text" {
  factory Text(String data) => document._createTextNode(data);
  // To suppress missing implicit constructor warnings.
  factory Text._() { throw new UnsupportedError("Not supported"); }

  @DomName('Text.wholeText')
  @DocsEditable()
  final String wholeText;

  @DomName('Text.getDestinationInsertionPoints')
  @DocsEditable()
  @Experimental() // untriaged
  @Returns('NodeList')
  @Creates('NodeList')
  List<Node> getDestinationInsertionPoints() native;

  @DomName('Text.splitText')
  @DocsEditable()
  Text splitText(int offset) native;

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


@DocsEditable()
@DomName('HTMLTextAreaElement')
class TextAreaElement extends HtmlElement native "HTMLTextAreaElement" {
  // To suppress missing implicit constructor warnings.
  factory TextAreaElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLTextAreaElement.HTMLTextAreaElement')
  @DocsEditable()
  factory TextAreaElement() => document.createElement("textarea");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TextAreaElement.created() : super.created();

  @DomName('HTMLTextAreaElement.autofocus')
  @DocsEditable()
  bool autofocus;

  @DomName('HTMLTextAreaElement.cols')
  @DocsEditable()
  int cols;

  @DomName('HTMLTextAreaElement.defaultValue')
  @DocsEditable()
  String defaultValue;

  @DomName('HTMLTextAreaElement.dirName')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#dom-textarea-dirname
  @Experimental()
  String dirName;

  @DomName('HTMLTextAreaElement.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('HTMLTextAreaElement.form')
  @DocsEditable()
  final FormElement form;

  @DomName('HTMLTextAreaElement.inputMode')
  @DocsEditable()
  @Experimental() // untriaged
  String inputMode;

  @DomName('HTMLTextAreaElement.labels')
  @DocsEditable()
  @Unstable()
  @Returns('NodeList')
  @Creates('NodeList')
  final List<Node> labels;

  @DomName('HTMLTextAreaElement.maxLength')
  @DocsEditable()
  int maxLength;

  @DomName('HTMLTextAreaElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLTextAreaElement.placeholder')
  @DocsEditable()
  String placeholder;

  @DomName('HTMLTextAreaElement.readOnly')
  @DocsEditable()
  bool readOnly;

  @DomName('HTMLTextAreaElement.required')
  @DocsEditable()
  bool required;

  @DomName('HTMLTextAreaElement.rows')
  @DocsEditable()
  int rows;

  @DomName('HTMLTextAreaElement.selectionDirection')
  @DocsEditable()
  String selectionDirection;

  @DomName('HTMLTextAreaElement.selectionEnd')
  @DocsEditable()
  int selectionEnd;

  @DomName('HTMLTextAreaElement.selectionStart')
  @DocsEditable()
  int selectionStart;

  @DomName('HTMLTextAreaElement.textLength')
  @DocsEditable()
  final int textLength;

  @DomName('HTMLTextAreaElement.type')
  @DocsEditable()
  final String type;

  @DomName('HTMLTextAreaElement.validationMessage')
  @DocsEditable()
  final String validationMessage;

  @DomName('HTMLTextAreaElement.validity')
  @DocsEditable()
  final ValidityState validity;

  @DomName('HTMLTextAreaElement.value')
  @DocsEditable()
  String value;

  @DomName('HTMLTextAreaElement.willValidate')
  @DocsEditable()
  final bool willValidate;

  @DomName('HTMLTextAreaElement.wrap')
  @DocsEditable()
  String wrap;

  @DomName('HTMLTextAreaElement.checkValidity')
  @DocsEditable()
  bool checkValidity() native;

  @DomName('HTMLTextAreaElement.select')
  @DocsEditable()
  void select() native;

  @DomName('HTMLTextAreaElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) native;

  @DomName('HTMLTextAreaElement.setRangeText')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#dom-textarea/input-setrangetext
  @Experimental()
  void setRangeText(String replacement, {int start, int end, String selectionMode}) native;

  @DomName('HTMLTextAreaElement.setSelectionRange')
  @DocsEditable()
  void setSelectionRange(int start, int end, [String direction]) native;
}
// 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.

// WARNING: Do not edit - generated code.


@DomName('TextEvent')
@Unstable()
class TextEvent extends UIEvent native "TextEvent" {
  factory TextEvent(String type,
    {bool canBubble: false, bool cancelable: false, Window view, String data}) {
    if (view == null) {
      view = window;
    }
    var e = document._createEvent("TextEvent");
    e._initTextEvent(type, canBubble, cancelable, view, data);
    return e;
  }
  // To suppress missing implicit constructor warnings.
  factory TextEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('TextEvent.data')
  @DocsEditable()
  final String data;

  @JSName('initTextEvent')
  @DomName('TextEvent.initTextEvent')
  @DocsEditable()
  void _initTextEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Window viewArg, String dataArg) native;

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


@DocsEditable()
@DomName('TextMetrics')
class TextMetrics extends Interceptor native "TextMetrics" {
  // To suppress missing implicit constructor warnings.
  factory TextMetrics._() { throw new UnsupportedError("Not supported"); }

  @DomName('TextMetrics.width')
  @DocsEditable()
  final double width;
}
// 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.


@DocsEditable()
@DomName('TextTrack')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#texttrack
@Experimental()
class TextTrack extends EventTarget native "TextTrack" {
  // To suppress missing implicit constructor warnings.
  factory TextTrack._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `cuechange` events to event
   * handlers that are not necessarily instances of [TextTrack].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('TextTrack.cuechangeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> cueChangeEvent = const EventStreamProvider<Event>('cuechange');

  @DomName('TextTrack.activeCues')
  @DocsEditable()
  final TextTrackCueList activeCues;

  @DomName('TextTrack.cues')
  @DocsEditable()
  final TextTrackCueList cues;

  @DomName('TextTrack.id')
  @DocsEditable()
  @Experimental() // untriaged
  final String id;

  @DomName('TextTrack.kind')
  @DocsEditable()
  final String kind;

  @DomName('TextTrack.label')
  @DocsEditable()
  final String label;

  @DomName('TextTrack.language')
  @DocsEditable()
  final String language;

  @DomName('TextTrack.mode')
  @DocsEditable()
  String mode;

  @DomName('TextTrack.regions')
  @DocsEditable()
  @Experimental() // untriaged
  final VttRegionList regions;

  @DomName('TextTrack.addCue')
  @DocsEditable()
  void addCue(TextTrackCue cue) native;

  @DomName('TextTrack.addRegion')
  @DocsEditable()
  @Experimental() // untriaged
  void addRegion(VttRegion region) native;

  @DomName('TextTrack.removeCue')
  @DocsEditable()
  void removeCue(TextTrackCue cue) native;

  @DomName('TextTrack.removeRegion')
  @DocsEditable()
  @Experimental() // untriaged
  void removeRegion(VttRegion region) native;

  /// Stream of `cuechange` events handled by this [TextTrack].
  @DomName('TextTrack.oncuechange')
  @DocsEditable()
  Stream<Event> get onCueChange => cueChangeEvent.forTarget(this);
}
// 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.


@DocsEditable()
@DomName('TextTrackCue')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#texttrackcue
@Experimental()
class TextTrackCue extends EventTarget native "TextTrackCue" {
  // To suppress missing implicit constructor warnings.
  factory TextTrackCue._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `enter` events to event
   * handlers that are not necessarily instances of [TextTrackCue].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('TextTrackCue.enterEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> enterEvent = const EventStreamProvider<Event>('enter');

  /**
   * Static factory designed to expose `exit` events to event
   * handlers that are not necessarily instances of [TextTrackCue].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('TextTrackCue.exitEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> exitEvent = const EventStreamProvider<Event>('exit');

  @DomName('TextTrackCue.endTime')
  @DocsEditable()
  num endTime;

  @DomName('TextTrackCue.id')
  @DocsEditable()
  String id;

  @DomName('TextTrackCue.pauseOnExit')
  @DocsEditable()
  bool pauseOnExit;

  @DomName('TextTrackCue.startTime')
  @DocsEditable()
  num startTime;

  @DomName('TextTrackCue.track')
  @DocsEditable()
  final TextTrack track;

  /// Stream of `enter` events handled by this [TextTrackCue].
  @DomName('TextTrackCue.onenter')
  @DocsEditable()
  Stream<Event> get onEnter => enterEvent.forTarget(this);

  /// Stream of `exit` events handled by this [TextTrackCue].
  @DomName('TextTrackCue.onexit')
  @DocsEditable()
  Stream<Event> get onExit => exitEvent.forTarget(this);
}
// 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.


@DocsEditable()
@DomName('TextTrackCueList')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#texttrackcuelist
@Experimental()
class TextTrackCueList extends Interceptor with ListMixin<TextTrackCue>, ImmutableListMixin<TextTrackCue> implements List<TextTrackCue>, JavaScriptIndexingBehavior native "TextTrackCueList" {
  // To suppress missing implicit constructor warnings.
  factory TextTrackCueList._() { throw new UnsupportedError("Not supported"); }

  @DomName('TextTrackCueList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  TextTrackCue operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("TextTrackCue", "#[#]", this, index);
  }
  void operator[]=(int index, TextTrackCue value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<TextTrackCue> mixins.
  // TextTrackCue is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  TextTrackCue get first {
    if (this.length > 0) {
      return JS('TextTrackCue', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  TextTrackCue get last {
    int len = this.length;
    if (len > 0) {
      return JS('TextTrackCue', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  TextTrackCue get single {
    int len = this.length;
    if (len == 1) {
      return JS('TextTrackCue', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  TextTrackCue elementAt(int index) => this[index];
  // -- end List<TextTrackCue> mixins.

  @DomName('TextTrackCueList.getCueById')
  @DocsEditable()
  TextTrackCue getCueById(String id) native;

  @DomName('TextTrackCueList.item')
  @DocsEditable()
  TextTrackCue item(int index) native;
}
// 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.


@DocsEditable()
@DomName('TextTrackList')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#texttracklist
@Experimental()
class TextTrackList extends EventTarget with ListMixin<TextTrack>, ImmutableListMixin<TextTrack> implements JavaScriptIndexingBehavior, List<TextTrack> native "TextTrackList" {
  // To suppress missing implicit constructor warnings.
  factory TextTrackList._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `addtrack` events to event
   * handlers that are not necessarily instances of [TextTrackList].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('TextTrackList.addtrackEvent')
  @DocsEditable()
  static const EventStreamProvider<TrackEvent> addTrackEvent = const EventStreamProvider<TrackEvent>('addtrack');

  @DomName('TextTrackList.changeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> changeEvent = const EventStreamProvider<Event>('change');

  @DomName('TextTrackList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  TextTrack operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("TextTrack", "#[#]", this, index);
  }
  void operator[]=(int index, TextTrack value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<TextTrack> mixins.
  // TextTrack is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  TextTrack get first {
    if (this.length > 0) {
      return JS('TextTrack', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  TextTrack get last {
    int len = this.length;
    if (len > 0) {
      return JS('TextTrack', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  TextTrack get single {
    int len = this.length;
    if (len == 1) {
      return JS('TextTrack', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  TextTrack elementAt(int index) => this[index];
  // -- end List<TextTrack> mixins.

  @DomName('TextTrackList.getTrackById')
  @DocsEditable()
  @Experimental() // untriaged
  TextTrack getTrackById(String id) native;

  @DomName('TextTrackList.item')
  @DocsEditable()
  TextTrack item(int index) native;

  /// Stream of `addtrack` events handled by this [TextTrackList].
  @DomName('TextTrackList.onaddtrack')
  @DocsEditable()
  Stream<TrackEvent> get onAddTrack => addTrackEvent.forTarget(this);

  @DomName('TextTrackList.onchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onChange => changeEvent.forTarget(this);
}
// 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.


@DocsEditable()
@DomName('TimeRanges')
@Unstable()
class TimeRanges extends Interceptor native "TimeRanges" {
  // To suppress missing implicit constructor warnings.
  factory TimeRanges._() { throw new UnsupportedError("Not supported"); }

  @DomName('TimeRanges.length')
  @DocsEditable()
  final int length;

  @DomName('TimeRanges.end')
  @DocsEditable()
  double end(int index) native;

  @DomName('TimeRanges.start')
  @DocsEditable()
  double start(int index) native;
}
// 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.


@DocsEditable()
@DomName('TimedItem')
@Experimental() // untriaged
class TimedItem extends Interceptor native "TimedItem" {
  // To suppress missing implicit constructor warnings.
  factory TimedItem._() { throw new UnsupportedError("Not supported"); }

  @DomName('TimedItem.activeDuration')
  @DocsEditable()
  @Experimental() // untriaged
  final double activeDuration;

  @DomName('TimedItem.currentIteration')
  @DocsEditable()
  @Experimental() // untriaged
  final int currentIteration;

  @DomName('TimedItem.duration')
  @DocsEditable()
  @Experimental() // untriaged
  final double duration;

  @DomName('TimedItem.endTime')
  @DocsEditable()
  @Experimental() // untriaged
  final double endTime;

  @DomName('TimedItem.localTime')
  @DocsEditable()
  @Experimental() // untriaged
  final double localTime;

  @DomName('TimedItem.player')
  @DocsEditable()
  @Experimental() // untriaged
  final Player player;

  @DomName('TimedItem.specified')
  @DocsEditable()
  @Experimental() // untriaged
  final Timing specified;

  @DomName('TimedItem.startTime')
  @DocsEditable()
  @Experimental() // untriaged
  final double startTime;
}
// 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.


@DocsEditable()
@DomName('Timeline')
@Experimental() // untriaged
class Timeline extends Interceptor native "Timeline" {
  // To suppress missing implicit constructor warnings.
  factory Timeline._() { throw new UnsupportedError("Not supported"); }

  @DomName('Timeline.play')
  @DocsEditable()
  @Experimental() // untriaged
  Player play(TimedItem source) native;
}
// 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.


@DomName('TimeoutHandler')
typedef void TimeoutHandler();
// 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.


@DocsEditable()
@DomName('Timing')
@Experimental() // untriaged
class Timing extends Interceptor native "Timing" {
  // To suppress missing implicit constructor warnings.
  factory Timing._() { throw new UnsupportedError("Not supported"); }

  @DomName('Timing.delay')
  @DocsEditable()
  @Experimental() // untriaged
  num delay;

  @DomName('Timing.direction')
  @DocsEditable()
  @Experimental() // untriaged
  String direction;

  @DomName('Timing.easing')
  @DocsEditable()
  @Experimental() // untriaged
  String easing;

  @DomName('Timing.endDelay')
  @DocsEditable()
  @Experimental() // untriaged
  num endDelay;

  @DomName('Timing.fill')
  @DocsEditable()
  @Experimental() // untriaged
  String fill;

  @DomName('Timing.iterationStart')
  @DocsEditable()
  @Experimental() // untriaged
  num iterationStart;

  @DomName('Timing.iterations')
  @DocsEditable()
  @Experimental() // untriaged
  num iterations;

  @DomName('Timing.playbackRate')
  @DocsEditable()
  @Experimental() // untriaged
  num playbackRate;

  @DomName('Timing.__setter__')
  @DocsEditable()
  @Experimental() // untriaged
  void __setter__(String name, num duration) native;
}
// 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.


@DocsEditable()
@DomName('HTMLTitleElement')
class TitleElement extends HtmlElement native "HTMLTitleElement" {
  // To suppress missing implicit constructor warnings.
  factory TitleElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLTitleElement.HTMLTitleElement')
  @DocsEditable()
  factory TitleElement() => document.createElement("title");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TitleElement.created() : super.created();
}
// 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.


@DocsEditable()
@DomName('Touch')
// http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
@Experimental()
class Touch extends Interceptor native "Touch" {
  // To suppress missing implicit constructor warnings.
  factory Touch._() { throw new UnsupportedError("Not supported"); }

  @JSName('clientX')
  @DomName('Touch.clientX')
  @DocsEditable()
  final int _clientX;

  @JSName('clientY')
  @DomName('Touch.clientY')
  @DocsEditable()
  final int _clientY;

  @DomName('Touch.identifier')
  @DocsEditable()
  final int identifier;

  @JSName('pageX')
  @DomName('Touch.pageX')
  @DocsEditable()
  final int _pageX;

  @JSName('pageY')
  @DomName('Touch.pageY')
  @DocsEditable()
  final int _pageY;

  @JSName('screenX')
  @DomName('Touch.screenX')
  @DocsEditable()
  final int _screenX;

  @JSName('screenY')
  @DomName('Touch.screenY')
  @DocsEditable()
  final int _screenY;

  @DomName('Touch.target')
  @DocsEditable()
  EventTarget get target => _convertNativeToDart_EventTarget(this._get_target);
  @JSName('target')
  @DomName('Touch.target')
  @DocsEditable()
  @Creates('Element|Document')
  @Returns('Element|Document')
  final dynamic _get_target;

  @JSName('webkitForce')
  @DomName('Touch.webkitForce')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  final double force;

  @JSName('webkitRadiusX')
  @DomName('Touch.webkitRadiusX')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  final int radiusX;

  @JSName('webkitRadiusY')
  @DomName('Touch.webkitRadiusY')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  final int radiusY;

  @JSName('webkitRotationAngle')
  @DomName('Touch.webkitRotationAngle')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  final double rotationAngle;


  @DomName('Touch.clientX')
  @DomName('Touch.clientY')
  Point get client => new Point(_clientX, _clientY);

  @DomName('Touch.pageX')
  @DomName('Touch.pageY')
  Point get page => new Point(_pageX, _pageY);

  @DomName('Touch.screenX')
  @DomName('Touch.screenY')
  Point get screen => new Point(_screenX, _screenY);
}
// 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.

// WARNING: Do not edit - generated code.


@DomName('TouchEvent')
// http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
@Experimental()
class TouchEvent extends UIEvent native "TouchEvent" {
  factory TouchEvent(TouchList touches, TouchList targetTouches,
      TouchList changedTouches, String type,
      {Window view, int screenX: 0, int screenY: 0, int clientX: 0,
      int clientY: 0, bool ctrlKey: false, bool altKey: false,
      bool shiftKey: false, bool metaKey: false}) {
    if (view == null) {
      view = window;
    }
    var e = document._createEvent("TouchEvent");
    e._initTouchEvent(touches, targetTouches, changedTouches, type, view,
        screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey);
    return e;
  }
  // To suppress missing implicit constructor warnings.
  factory TouchEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('TouchEvent.altKey')
  @DocsEditable()
  final bool altKey;

  @DomName('TouchEvent.changedTouches')
  @DocsEditable()
  final TouchList changedTouches;

  @DomName('TouchEvent.ctrlKey')
  @DocsEditable()
  final bool ctrlKey;

  @DomName('TouchEvent.metaKey')
  @DocsEditable()
  final bool metaKey;

  @DomName('TouchEvent.shiftKey')
  @DocsEditable()
  final bool shiftKey;

  @DomName('TouchEvent.targetTouches')
  @DocsEditable()
  final TouchList targetTouches;

  @DomName('TouchEvent.touches')
  @DocsEditable()
  final TouchList touches;

  @JSName('initTouchEvent')
  @DomName('TouchEvent.initTouchEvent')
  @DocsEditable()
  void _initTouchEvent(TouchList touches, TouchList targetTouches, TouchList changedTouches, String type, Window view, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey) native;


  /**
   * Checks if touch events supported on the current platform.
   *
   * Note that touch events are only supported if the user is using a touch
   * device.
   */
  static bool get supported => Device.isEventTypeSupported('TouchEvent');
}
// 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.

// WARNING: Do not edit - generated code.


@DomName('TouchList')
// http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
@Experimental()
class TouchList extends Interceptor with ListMixin<Touch>, ImmutableListMixin<Touch> implements JavaScriptIndexingBehavior, List<Touch> native "TouchList" {
  /// NB: This constructor likely does not work as you might expect it to! This
  /// constructor will simply fail (returning null) if you are not on a device
  /// with touch enabled. See dartbug.com/8314.
  // TODO(5760): createTouchList now uses varargs.
  factory TouchList() => null;//document._createTouchList();
  // To suppress missing implicit constructor warnings.
  factory TouchList._() { throw new UnsupportedError("Not supported"); }

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!document.createTouchList');

  @DomName('TouchList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  Touch operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("Touch", "#[#]", this, index);
  }
  void operator[]=(int index, Touch value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Touch> mixins.
  // Touch is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Touch get first {
    if (this.length > 0) {
      return JS('Touch', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Touch get last {
    int len = this.length;
    if (len > 0) {
      return JS('Touch', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Touch get single {
    int len = this.length;
    if (len == 1) {
      return JS('Touch', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Touch elementAt(int index) => this[index];
  // -- end List<Touch> mixins.

  @DomName('TouchList.item')
  @DocsEditable()
  Touch item(int index) native;

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


@DocsEditable()
@DomName('HTMLTrackElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#the-track-element
@Experimental()
class TrackElement extends HtmlElement native "HTMLTrackElement" {
  // To suppress missing implicit constructor warnings.
  factory TrackElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLTrackElement.HTMLTrackElement')
  @DocsEditable()
  factory TrackElement() => document.createElement("track");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TrackElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('track');

  @DomName('HTMLTrackElement.ERROR')
  @DocsEditable()
  static const int ERROR = 3;

  @DomName('HTMLTrackElement.LOADED')
  @DocsEditable()
  static const int LOADED = 2;

  @DomName('HTMLTrackElement.LOADING')
  @DocsEditable()
  static const int LOADING = 1;

  @DomName('HTMLTrackElement.NONE')
  @DocsEditable()
  static const int NONE = 0;

  @JSName('default')
  @DomName('HTMLTrackElement.default')
  @DocsEditable()
  bool defaultValue;

  @DomName('HTMLTrackElement.kind')
  @DocsEditable()
  String kind;

  @DomName('HTMLTrackElement.label')
  @DocsEditable()
  String label;

  @DomName('HTMLTrackElement.readyState')
  @DocsEditable()
  final int readyState;

  @DomName('HTMLTrackElement.src')
  @DocsEditable()
  String src;

  @DomName('HTMLTrackElement.srclang')
  @DocsEditable()
  String srclang;

  @DomName('HTMLTrackElement.track')
  @DocsEditable()
  final TextTrack track;
}
// 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.


@DocsEditable()
@DomName('TrackEvent')
@Unstable()
class TrackEvent extends Event native "TrackEvent" {
  // To suppress missing implicit constructor warnings.
  factory TrackEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('TrackEvent.track')
  @DocsEditable()
  @Creates('Null')
  final Object track;
}
// 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.


@DocsEditable()
@DomName('TransitionEvent')
class TransitionEvent extends Event native "TransitionEvent,WebKitTransitionEvent" {
  // To suppress missing implicit constructor warnings.
  factory TransitionEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('TransitionEvent.elapsedTime')
  @DocsEditable()
  final double elapsedTime;

  @DomName('TransitionEvent.propertyName')
  @DocsEditable()
  final String propertyName;

  @DomName('TransitionEvent.pseudoElement')
  @DocsEditable()
  final String pseudoElement;
}
// 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.


@DomName('TreeWalker')
@Unstable()
class TreeWalker extends Interceptor native "TreeWalker" {
  factory TreeWalker(Node root, int whatToShow) {
    return document._createTreeWalker(root, whatToShow, null);
  }
  // To suppress missing implicit constructor warnings.
  factory TreeWalker._() { throw new UnsupportedError("Not supported"); }

  @DomName('TreeWalker.currentNode')
  @DocsEditable()
  Node currentNode;

  @DomName('TreeWalker.filter')
  @DocsEditable()
  final NodeFilter filter;

  @DomName('TreeWalker.root')
  @DocsEditable()
  final Node root;

  @DomName('TreeWalker.whatToShow')
  @DocsEditable()
  final int whatToShow;

  @DomName('TreeWalker.firstChild')
  @DocsEditable()
  Node firstChild() native;

  @DomName('TreeWalker.lastChild')
  @DocsEditable()
  Node lastChild() native;

  @DomName('TreeWalker.nextNode')
  @DocsEditable()
  Node nextNode() native;

  @DomName('TreeWalker.nextSibling')
  @DocsEditable()
  Node nextSibling() native;

  @DomName('TreeWalker.parentNode')
  @DocsEditable()
  Node parentNode() native;

  @DomName('TreeWalker.previousNode')
  @DocsEditable()
  Node previousNode() native;

  @DomName('TreeWalker.previousSibling')
  @DocsEditable()
  Node previousSibling() native;

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


@DomName('UIEvent')
class UIEvent extends Event native "UIEvent" {
  // In JS, canBubble and cancelable are technically required parameters to
  // init*Event. In practice, though, if they aren't provided they simply
  // default to false (since that's Boolean(undefined)).
  //
  // Contrary to JS, we default canBubble and cancelable to true, since that's
  // what people want most of the time anyway.
  factory UIEvent(String type,
      {Window view, int detail: 0, bool canBubble: true,
      bool cancelable: true}) {
    if (view == null) {
      view = window;
    }
    final e = document._createEvent("UIEvent");
    e._initUIEvent(type, canBubble, cancelable, view, detail);
    return e;
  }
  // To suppress missing implicit constructor warnings.
  factory UIEvent._() { throw new UnsupportedError("Not supported"); }

  @JSName('charCode')
  @DomName('UIEvent.charCode')
  @DocsEditable()
  @Unstable()
  final int _charCode;

  @DomName('UIEvent.detail')
  @DocsEditable()
  final int detail;

  @JSName('keyCode')
  @DomName('UIEvent.keyCode')
  @DocsEditable()
  @Unstable()
  final int _keyCode;

  @JSName('layerX')
  @DomName('UIEvent.layerX')
  @DocsEditable()
  // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-mouseevents
  @Experimental() // nonstandard
  final int _layerX;

  @JSName('layerY')
  @DomName('UIEvent.layerY')
  @DocsEditable()
  // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-mouseevents
  @Experimental() // nonstandard
  final int _layerY;

  @JSName('pageX')
  @DomName('UIEvent.pageX')
  @DocsEditable()
  // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-mouseevents
  @Experimental() // nonstandard
  final int _pageX;

  @JSName('pageY')
  @DomName('UIEvent.pageY')
  @DocsEditable()
  // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-mouseevents
  @Experimental() // nonstandard
  final int _pageY;

  @DomName('UIEvent.view')
  @DocsEditable()
  WindowBase get view => _convertNativeToDart_Window(this._get_view);
  @JSName('view')
  @DomName('UIEvent.view')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_view;

  @DomName('UIEvent.which')
  @DocsEditable()
  @Unstable()
  final int which;

  @JSName('initUIEvent')
  @DomName('UIEvent.initUIEvent')
  @DocsEditable()
  void _initUIEvent(String type, bool canBubble, bool cancelable, Window view, int detail) native;


  @DomName('UIEvent.layerX')
  @DomName('UIEvent.layerY')
  Point get layer => new Point(_layerX, _layerY);

  @DomName('UIEvent.pageX')
  @DomName('UIEvent.pageY')
  Point get page => new Point(_pageX, _pageY);
}
// 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.


@DocsEditable()
@DomName('HTMLUListElement')
class UListElement extends HtmlElement native "HTMLUListElement" {
  // To suppress missing implicit constructor warnings.
  factory UListElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLUListElement.HTMLUListElement')
  @DocsEditable()
  factory UListElement() => document.createElement("ul");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  UListElement.created() : super.created();
}
// 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.


@DocsEditable()
@DomName('HTMLUnknownElement')
class UnknownElement extends HtmlElement native "HTMLUnknownElement" {
  // To suppress missing implicit constructor warnings.
  factory UnknownElement._() { throw new UnsupportedError("Not supported"); }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  UnknownElement.created() : super.created();
}
// 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.


@DomName('URL')
class Url extends Interceptor implements UrlUtils native "URL" {

  static String createObjectUrl(blob_OR_source_OR_stream) =>
      JS('String',
         '(self.URL || self.webkitURL).createObjectURL(#)',
          blob_OR_source_OR_stream);

  static String createObjectUrlFromSource(MediaSource source) =>
      JS('String', '(self.URL || self.webkitURL).createObjectURL(#)', source);
  
  static String createObjectUrlFromStream(MediaStream stream) =>
      JS('String', '(self.URL || self.webkitURL).createObjectURL(#)', stream);
  
  static String createObjectUrlFromBlob(Blob blob) =>
      JS('String', '(self.URL || self.webkitURL).createObjectURL(#)', blob);

  static void revokeObjectUrl(String url) =>
      JS('void',
         '(self.URL || self.webkitURL).revokeObjectURL(#)', url);
  // To suppress missing implicit constructor warnings.
  factory Url._() { throw new UnsupportedError("Not supported"); }

  // From URLUtils

  @DomName('URL.hash')
  @DocsEditable()
  @Experimental() // untriaged
  String hash;

  @DomName('URL.host')
  @DocsEditable()
  @Experimental() // untriaged
  String host;

  @DomName('URL.hostname')
  @DocsEditable()
  @Experimental() // untriaged
  String hostname;

  @DomName('URL.href')
  @DocsEditable()
  @Experimental() // untriaged
  String href;

  @DomName('URL.origin')
  @DocsEditable()
  @Experimental() // untriaged
  final String origin;

  @DomName('URL.password')
  @DocsEditable()
  @Experimental() // untriaged
  String password;

  @DomName('URL.pathname')
  @DocsEditable()
  @Experimental() // untriaged
  String pathname;

  @DomName('URL.port')
  @DocsEditable()
  @Experimental() // untriaged
  String port;

  @DomName('URL.protocol')
  @DocsEditable()
  @Experimental() // untriaged
  String protocol;

  @DomName('URL.search')
  @DocsEditable()
  @Experimental() // untriaged
  String search;

  @DomName('URL.username')
  @DocsEditable()
  @Experimental() // untriaged
  String username;

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


@DocsEditable()
@DomName('URLUtils')
@Experimental() // untriaged
abstract class UrlUtils extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory UrlUtils._() { throw new UnsupportedError("Not supported"); }

  String hash;

  String host;

  String hostname;

  String href;

  final String origin;

  String password;

  String pathname;

  String port;

  String protocol;

  String search;

  String username;

  String toString();
}
// 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.


@DocsEditable()
@DomName('URLUtilsReadOnly')
@Experimental() // untriaged
abstract class UrlUtilsReadOnly extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory UrlUtilsReadOnly._() { throw new UnsupportedError("Not supported"); }

  final String hash;

  final String host;

  final String hostname;

  final String href;

  final String pathname;

  final String port;

  final String protocol;

  final String search;

  String toString();
}
// 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.


@DocsEditable()
@DomName('ValidityState')
class ValidityState extends Interceptor native "ValidityState" {
  // To suppress missing implicit constructor warnings.
  factory ValidityState._() { throw new UnsupportedError("Not supported"); }

  @DomName('ValidityState.badInput')
  @DocsEditable()
  final bool badInput;

  @DomName('ValidityState.customError')
  @DocsEditable()
  final bool customError;

  @DomName('ValidityState.patternMismatch')
  @DocsEditable()
  final bool patternMismatch;

  @DomName('ValidityState.rangeOverflow')
  @DocsEditable()
  final bool rangeOverflow;

  @DomName('ValidityState.rangeUnderflow')
  @DocsEditable()
  final bool rangeUnderflow;

  @DomName('ValidityState.stepMismatch')
  @DocsEditable()
  final bool stepMismatch;

  @DomName('ValidityState.tooLong')
  @DocsEditable()
  final bool tooLong;

  @DomName('ValidityState.typeMismatch')
  @DocsEditable()
  final bool typeMismatch;

  @DomName('ValidityState.valid')
  @DocsEditable()
  final bool valid;

  @DomName('ValidityState.valueMissing')
  @DocsEditable()
  final bool valueMissing;
}
// 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.


@DomName('HTMLVideoElement')
class VideoElement extends MediaElement implements CanvasImageSource native "HTMLVideoElement" {
  // To suppress missing implicit constructor warnings.
  factory VideoElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLVideoElement.HTMLVideoElement')
  @DocsEditable()
  factory VideoElement() => document.createElement("video");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  VideoElement.created() : super.created();

  @DomName('HTMLVideoElement.height')
  @DocsEditable()
  int height;

  @DomName('HTMLVideoElement.poster')
  @DocsEditable()
  String poster;

  @DomName('HTMLVideoElement.videoHeight')
  @DocsEditable()
  final int videoHeight;

  @DomName('HTMLVideoElement.videoWidth')
  @DocsEditable()
  final int videoWidth;

  @JSName('webkitDecodedFrameCount')
  @DomName('HTMLVideoElement.webkitDecodedFrameCount')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  final int decodedFrameCount;

  @JSName('webkitDroppedFrameCount')
  @DomName('HTMLVideoElement.webkitDroppedFrameCount')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  final int droppedFrameCount;

  @DomName('HTMLVideoElement.width')
  @DocsEditable()
  int width;

  @DomName('HTMLVideoElement.getVideoPlaybackQuality')
  @DocsEditable()
  @Experimental() // untriaged
  VideoPlaybackQuality getVideoPlaybackQuality() native;

  @JSName('webkitEnterFullscreen')
  @DomName('HTMLVideoElement.webkitEnterFullscreen')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  void enterFullscreen() native;

  @JSName('webkitExitFullscreen')
  @DomName('HTMLVideoElement.webkitExitFullscreen')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#dom-document-exitfullscreen
  void exitFullscreen() native;

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


@DocsEditable()
@DomName('VideoPlaybackQuality')
@Experimental() // untriaged
class VideoPlaybackQuality extends Interceptor native "VideoPlaybackQuality" {
  // To suppress missing implicit constructor warnings.
  factory VideoPlaybackQuality._() { throw new UnsupportedError("Not supported"); }

  @DomName('VideoPlaybackQuality.corruptedVideoFrames')
  @DocsEditable()
  @Experimental() // untriaged
  final int corruptedVideoFrames;

  @DomName('VideoPlaybackQuality.creationTime')
  @DocsEditable()
  @Experimental() // untriaged
  final double creationTime;

  @DomName('VideoPlaybackQuality.droppedVideoFrames')
  @DocsEditable()
  @Experimental() // untriaged
  final int droppedVideoFrames;

  @DomName('VideoPlaybackQuality.totalVideoFrames')
  @DocsEditable()
  @Experimental() // untriaged
  final int totalVideoFrames;
}
// 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.


@DomName('VoidCallback')
// http://www.w3.org/TR/file-system-api/#the-voidcallback-interface
@Experimental()
typedef void VoidCallback();
// 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.


@DocsEditable()
@DomName('VTTCue')
@Experimental() // untriaged
class VttCue extends TextTrackCue native "VTTCue" {
  // To suppress missing implicit constructor warnings.
  factory VttCue._() { throw new UnsupportedError("Not supported"); }

  @DomName('VTTCue.VTTCue')
  @DocsEditable()
  factory VttCue(num startTime, num endTime, String text) {
    return VttCue._create_1(startTime, endTime, text);
  }
  static VttCue _create_1(startTime, endTime, text) => JS('VttCue', 'new VTTCue(#,#,#)', startTime, endTime, text);

  @DomName('VTTCue.align')
  @DocsEditable()
  @Experimental() // untriaged
  String align;

  @DomName('VTTCue.line')
  @DocsEditable()
  @Experimental() // untriaged
  int line;

  @DomName('VTTCue.position')
  @DocsEditable()
  @Experimental() // untriaged
  int position;

  @DomName('VTTCue.regionId')
  @DocsEditable()
  @Experimental() // untriaged
  String regionId;

  @DomName('VTTCue.size')
  @DocsEditable()
  @Experimental() // untriaged
  int size;

  @DomName('VTTCue.snapToLines')
  @DocsEditable()
  @Experimental() // untriaged
  bool snapToLines;

  @DomName('VTTCue.text')
  @DocsEditable()
  @Experimental() // untriaged
  String text;

  @DomName('VTTCue.vertical')
  @DocsEditable()
  @Experimental() // untriaged
  String vertical;

  @JSName('getCueAsHTML')
  @DomName('VTTCue.getCueAsHTML')
  @DocsEditable()
  @Experimental() // untriaged
  DocumentFragment getCueAsHtml() native;
}
// 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.


@DocsEditable()
@DomName('VTTRegion')
@Experimental() // untriaged
class VttRegion extends Interceptor native "VTTRegion" {
  // To suppress missing implicit constructor warnings.
  factory VttRegion._() { throw new UnsupportedError("Not supported"); }

  @DomName('VTTRegion.VTTRegion')
  @DocsEditable()
  factory VttRegion() {
    return VttRegion._create_1();
  }
  static VttRegion _create_1() => JS('VttRegion', 'new VTTRegion()');

  @DomName('VTTRegion.height')
  @DocsEditable()
  @Experimental() // untriaged
  int height;

  @DomName('VTTRegion.id')
  @DocsEditable()
  @Experimental() // untriaged
  String id;

  @DomName('VTTRegion.regionAnchorX')
  @DocsEditable()
  @Experimental() // untriaged
  num regionAnchorX;

  @DomName('VTTRegion.regionAnchorY')
  @DocsEditable()
  @Experimental() // untriaged
  num regionAnchorY;

  @DomName('VTTRegion.scroll')
  @DocsEditable()
  @Experimental() // untriaged
  String scroll;

  @DomName('VTTRegion.track')
  @DocsEditable()
  @Experimental() // untriaged
  final TextTrack track;

  @DomName('VTTRegion.viewportAnchorX')
  @DocsEditable()
  @Experimental() // untriaged
  num viewportAnchorX;

  @DomName('VTTRegion.viewportAnchorY')
  @DocsEditable()
  @Experimental() // untriaged
  num viewportAnchorY;

  @DomName('VTTRegion.width')
  @DocsEditable()
  @Experimental() // untriaged
  num width;
}
// 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.


@DocsEditable()
@DomName('VTTRegionList')
@Experimental() // untriaged
class VttRegionList extends Interceptor native "VTTRegionList" {
  // To suppress missing implicit constructor warnings.
  factory VttRegionList._() { throw new UnsupportedError("Not supported"); }

  @DomName('VTTRegionList.length')
  @DocsEditable()
  @Experimental() // untriaged
  final int length;

  @DomName('VTTRegionList.getRegionById')
  @DocsEditable()
  @Experimental() // untriaged
  VttRegion getRegionById(String id) native;

  @DomName('VTTRegionList.item')
  @DocsEditable()
  @Experimental() // untriaged
  VttRegion item(int index) native;
}
// 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.


@DocsEditable()
/**
 * Use the WebSocket interface to connect to a WebSocket,
 * and to send and receive data on that WebSocket.
 *
 * To use a WebSocket in your web app, first create a WebSocket object,
 * passing the WebSocket URL as an argument to the constructor.
 *
 *     var webSocket = new WebSocket('ws://127.0.0.1:1337/ws');
 *
 * To send data on the WebSocket, use the [send] method.
 *
 *     if (webSocket != null && webSocket.readyState == WebSocket.OPEN) {
 *       webSocket.send(data);
 *     } else {
 *       print('WebSocket not connected, message $data not sent');
 *     }
 *
 * To receive data on the WebSocket, register a listener for message events.
 *
 *     webSocket.onMessage.listen((MessageEvent e) {
 *       receivedData(e.data);
 *     });
 *
 * The message event handler receives a [MessageEvent] object
 * as its sole argument.
 * You can also define open, close, and error handlers,
 * as specified by [WebSocketEvents].
 *
 * For more information, see the
 * [WebSockets](http://www.dartlang.org/docs/library-tour/#html-websockets)
 * section of the library tour and
 * [Introducing WebSockets](http://www.html5rocks.com/en/tutorials/websockets/basics/),
 * an HTML5Rocks.com tutorial.
 */
@DomName('WebSocket')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
class WebSocket extends EventTarget native "WebSocket" {
  // To suppress missing implicit constructor warnings.
  factory WebSocket._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `close` events to event
   * handlers that are not necessarily instances of [WebSocket].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('WebSocket.closeEvent')
  @DocsEditable()
  static const EventStreamProvider<CloseEvent> closeEvent = const EventStreamProvider<CloseEvent>('close');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [WebSocket].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('WebSocket.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [WebSocket].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('WebSocket.messageEvent')
  @DocsEditable()
  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');

  /**
   * Static factory designed to expose `open` events to event
   * handlers that are not necessarily instances of [WebSocket].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('WebSocket.openEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> openEvent = const EventStreamProvider<Event>('open');

  @DomName('WebSocket.WebSocket')
  @DocsEditable()
  factory WebSocket(String url, [protocol_OR_protocols]) {
    if ((url is String || url == null) && protocol_OR_protocols == null) {
      return WebSocket._create_1(url);
    }
    if ((protocol_OR_protocols is List<String> || protocol_OR_protocols == null) && (url is String || url == null)) {
      return WebSocket._create_2(url, protocol_OR_protocols);
    }
    if ((protocol_OR_protocols is String || protocol_OR_protocols == null) && (url is String || url == null)) {
      return WebSocket._create_3(url, protocol_OR_protocols);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static WebSocket _create_1(url) => JS('WebSocket', 'new WebSocket(#)', url);
  static WebSocket _create_2(url, protocol_OR_protocols) => JS('WebSocket', 'new WebSocket(#,#)', url, protocol_OR_protocols);
  static WebSocket _create_3(url, protocol_OR_protocols) => JS('WebSocket', 'new WebSocket(#,#)', url, protocol_OR_protocols);

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', 'typeof window.WebSocket != "undefined"');

  @DomName('WebSocket.CLOSED')
  @DocsEditable()
  static const int CLOSED = 3;

  @DomName('WebSocket.CLOSING')
  @DocsEditable()
  static const int CLOSING = 2;

  @DomName('WebSocket.CONNECTING')
  @DocsEditable()
  static const int CONNECTING = 0;

  @DomName('WebSocket.OPEN')
  @DocsEditable()
  static const int OPEN = 1;

  @DomName('WebSocket.binaryType')
  @DocsEditable()
  String binaryType;

  @DomName('WebSocket.bufferedAmount')
  @DocsEditable()
  final int bufferedAmount;

  @DomName('WebSocket.extensions')
  @DocsEditable()
  final String extensions;

  @DomName('WebSocket.protocol')
  @DocsEditable()
  final String protocol;

  @DomName('WebSocket.readyState')
  @DocsEditable()
  final int readyState;

  @DomName('WebSocket.url')
  @DocsEditable()
  final String url;

  @DomName('WebSocket.close')
  @DocsEditable()
  void close([int code, String reason]) native;

  /**
   * Transmit data to the server over this connection.
   *
   * This method accepts data of type [Blob], [ByteBuffer], [String], or
   * [TypedData]. Named variants [sendBlob], [sendByteBuffer], [sendString],
   * or [sendTypedData], in constrast, only accept data of the specified type.
   */
  @DomName('WebSocket.send')
  @DocsEditable()
  void send(data) native;

  @JSName('send')
  /**
   * Transmit data to the server over this connection.
   *
   * This method accepts data of type [Blob], [ByteBuffer], [String], or
   * [TypedData]. Named variants [sendBlob], [sendByteBuffer], [sendString],
   * or [sendTypedData], in constrast, only accept data of the specified type.
   */
  @DomName('WebSocket.send')
  @DocsEditable()
  void sendBlob(Blob data) native;

  @JSName('send')
  /**
   * Transmit data to the server over this connection.
   *
   * This method accepts data of type [Blob], [ByteBuffer], [String], or
   * [TypedData]. Named variants [sendBlob], [sendByteBuffer], [sendString],
   * or [sendTypedData], in constrast, only accept data of the specified type.
   */
  @DomName('WebSocket.send')
  @DocsEditable()
  void sendByteBuffer(ByteBuffer data) native;

  @JSName('send')
  /**
   * Transmit data to the server over this connection.
   *
   * This method accepts data of type [Blob], [ByteBuffer], [String], or
   * [TypedData]. Named variants [sendBlob], [sendByteBuffer], [sendString],
   * or [sendTypedData], in constrast, only accept data of the specified type.
   */
  @DomName('WebSocket.send')
  @DocsEditable()
  void sendString(String data) native;

  @JSName('send')
  /**
   * Transmit data to the server over this connection.
   *
   * This method accepts data of type [Blob], [ByteBuffer], [String], or
   * [TypedData]. Named variants [sendBlob], [sendByteBuffer], [sendString],
   * or [sendTypedData], in constrast, only accept data of the specified type.
   */
  @DomName('WebSocket.send')
  @DocsEditable()
  void sendTypedData(TypedData data) native;

  /// Stream of `close` events handled by this [WebSocket].
  @DomName('WebSocket.onclose')
  @DocsEditable()
  Stream<CloseEvent> get onClose => closeEvent.forTarget(this);

  /// Stream of `error` events handled by this [WebSocket].
  @DomName('WebSocket.onerror')
  @DocsEditable()
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `message` events handled by this [WebSocket].
  @DomName('WebSocket.onmessage')
  @DocsEditable()
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  /// Stream of `open` events handled by this [WebSocket].
  @DomName('WebSocket.onopen')
  @DocsEditable()
  Stream<Event> get onOpen => openEvent.forTarget(this);
}
// 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.


@DomName('WheelEvent')
class WheelEvent extends MouseEvent native "WheelEvent,MouseWheelEvent,MouseScrollEvent" {

  factory WheelEvent(String type,
      {Window view, int deltaX: 0, int deltaY: 0,
      int detail: 0, int screenX: 0, int screenY: 0, int clientX: 0,
      int clientY: 0, int button: 0, bool canBubble: true,
      bool cancelable: true, bool ctrlKey: false, bool altKey: false,
      bool shiftKey: false, bool metaKey: false, EventTarget relatedTarget}) {

    if (view == null) {
      view = window;
    }
    var eventType = 'WheelEvent';
    if (Device.isFirefox) {
      eventType = 'MouseScrollEvents';
    }
    final event = document._createEvent(eventType);
    // If polyfilling, then flip these because we'll flip them back to match
    // the W3C standard:
    // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-WheelEvent-deltaY
    if (JS('bool', '#.deltaY === undefined', event)) {
      deltaX = -deltaX;
      deltaY = -deltaY;
    }
    if (event._hasInitWheelEvent) {
      var modifiers = [];
      if (ctrlKey) {
        modifiers.push('Control');
      }
      if (altKey) {
        modifiers.push('Alt');
      }
      if (shiftKey) {
        modifiers.push('Shift');
      }
      if (metaKey) {
        modifiers.push('Meta');
      }
      event._initWheelEvent(type, canBubble, cancelable, view, detail, screenX,
          screenY, clientX, clientY, button, relatedTarget, modifiers.join(' '),
          deltaX, deltaY, 0, 0);
    } else if (event._hasInitMouseScrollEvent) {
      var axis = 0;
      var detail = 0;
      if (deltaX != 0 && deltaY != 0) {
        throw new UnsupportedError(
            'Cannot modify deltaX and deltaY simultaneously');
      }
      if (deltaY != 0) {
        detail = deltaY;
        axis = JS('int', 'MouseScrollEvent.VERTICAL_AXIS');
      } else if (deltaX != 0) {
        detail = deltaX;
        axis = JS('int', 'MouseScrollEvent.HORIZONTAL_AXIS');
      }
      event._initMouseScrollEvent(type, canBubble, cancelable, view, detail,
          screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey,
          metaKey, button, relatedTarget, axis);
    } else {
      // Chrome does an auto-convert to pixels.
      deltaY = deltaY ~/ 120;
      // Fallthrough for Dartium.
      event._initMouseEvent(type, canBubble, cancelable, view, detail,
          screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey,
          metaKey, button, relatedTarget);
      event._initWebKitWheelEvent(deltaX, deltaY,
          view, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey,
          metaKey);
    }

    return event;
  }

  // To suppress missing implicit constructor warnings.
  factory WheelEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('WheelEvent.DOM_DELTA_LINE')
  @DocsEditable()
  static const int DOM_DELTA_LINE = 0x01;

  @DomName('WheelEvent.DOM_DELTA_PAGE')
  @DocsEditable()
  static const int DOM_DELTA_PAGE = 0x02;

  @DomName('WheelEvent.DOM_DELTA_PIXEL')
  @DocsEditable()
  static const int DOM_DELTA_PIXEL = 0x00;

  @JSName('deltaX')
  @DomName('WheelEvent.deltaX')
  @DocsEditable()
  @Experimental() // untriaged
  final double _deltaX;

  @JSName('deltaY')
  @DomName('WheelEvent.deltaY')
  @DocsEditable()
  @Experimental() // untriaged
  final double _deltaY;

  @DomName('WheelEvent.deltaZ')
  @DocsEditable()
  @Experimental() // untriaged
  final double deltaZ;

  @JSName('webkitDirectionInvertedFromDevice')
  @DomName('WheelEvent.webkitDirectionInvertedFromDevice')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  final bool directionInvertedFromDevice;

  @JSName('initWebKitWheelEvent')
  @DomName('WheelEvent.initWebKitWheelEvent')
  @DocsEditable()
  @Experimental()
  void _initWebKitWheelEvent(int wheelDeltaX, int wheelDeltaY, Window view, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey) native;


  /**
   * The amount that is expected to scroll vertically, in units determined by
   * [deltaMode].
   *
   * See also:
   *
   * * [WheelEvent.deltaY](http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-WheelEvent-deltaY) from the W3C.
   */
  @DomName('WheelEvent.deltaY')
  num get deltaY {
    if (JS('bool', '#.deltaY !== undefined', this)) {
      // W3C WheelEvent
      return this._deltaY;
    } else if (JS('bool', '#.wheelDelta !== undefined', this)) {
      // Chrome and IE
      return -this._wheelDelta;
    } else if (JS('bool', '#.detail !== undefined', this)) {
      // Firefox

      // Handle DOMMouseScroll case where it uses detail and the axis to
      // differentiate.
      if (JS('bool', '#.axis == MouseScrollEvent.VERTICAL_AXIS', this)) {
        var detail = this._detail;
        // Firefox is normally the number of lines to scale (normally 3)
        // so multiply it by 40 to get pixels to move, matching IE & WebKit.
        if (detail.abs() < 100) {
          return -detail * 40;
        }
        return -detail;
      }
      return 0;
    }
    throw new UnsupportedError(
        'deltaY is not supported');
  }

  /**
   * The amount that is expected to scroll horizontally, in units determined by
   * [deltaMode].
   *
   * See also:
   *
   * * [WheelEvent.deltaX](http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-WheelEvent-deltaX) from the W3C.
   */
  @DomName('WheelEvent.deltaX')
  num get deltaX {
    if (JS('bool', '#.deltaX !== undefined', this)) {
      // W3C WheelEvent
      return this._deltaX;
    } else if (JS('bool', '#.wheelDeltaX !== undefined', this)) {
      // Chrome
      return -this._wheelDeltaX;
    } else if (JS('bool', '#.detail !== undefined', this)) {
      // Firefox and IE.
      // IE will have detail set but will not set axis.

      // Handle DOMMouseScroll case where it uses detail and the axis to
      // differentiate.
      if (JS('bool', '#.axis !== undefined && '
        '#.axis == MouseScrollEvent.HORIZONTAL_AXIS', this, this)) {
        var detail = this._detail;
        // Firefox is normally the number of lines to scale (normally 3)
        // so multiply it by 40 to get pixels to move, matching IE & WebKit.
        if (detail < 100) {
          return -detail * 40;
        }
        return -detail;
      }
      return 0;
    }
    throw new UnsupportedError(
        'deltaX is not supported');
  }

  @DomName('WheelEvent.deltaMode')
  int get deltaMode {
    if (JS('bool', '!!(#.deltaMode)', this)) {
      return JS('int', '#.deltaMode', this);
    }
    // If not available then we're poly-filling and doing pixel scroll.
    return 0;
  }

  num get _wheelDelta => JS('num', '#.wheelDelta', this);
  num get _wheelDeltaX => JS('num', '#.wheelDeltaX', this);
  num get _detail => JS('num', '#.detail', this);

  bool get _hasInitMouseScrollEvent =>
      JS('bool', '!!(#.initMouseScrollEvent)', this);

  @JSName('initMouseScrollEvent')
  void _initMouseScrollEvent(
      String type,
      bool canBubble,
      bool cancelable,
      Window view,
      int detail,
      int screenX,
      int screenY,
      int clientX,
      int clientY,
      bool ctrlKey,
      bool altKey,
      bool shiftKey,
      bool metaKey,
      int button,
      EventTarget relatedTarget,
      int axis) native;

  bool get _hasInitWheelEvent =>
      JS('bool', '!!(#.initWheelEvent)', this);
  @JSName('initWheelEvent')
  void _initWheelEvent(
      String eventType,
      bool canBubble,
      bool cancelable,
      Window view,
      int detail,
      int screenX,
      int screenY,
      int clientX,
      int clientY,
      int button,
      EventTarget relatedTarget,
      String modifiersList,
      int deltaX,
      int deltaY,
      int deltaZ,
      int deltaMode) native;

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


@DocsEditable()
/**
 * Top-level container for the current browser tab or window.
 *
 * In a web browser, each window has a [Window] object, but within the context
 * of a script, this object represents only the current window.
 * Each other window, tab, and iframe has its own [Window] object.
 *
 * Each window contains a [Document] object, which contains all of the window's
 * content.
 *
 * Use the top-level `window` object to access the current window.
 * For example:
 *
 *     // Draw a scene when the window repaints.
 *     drawScene(num delta) {...}
 *     window.animationFrame.then(drawScene);.
 *
 *     // Write to the console.
 *     window.console.log('Jinkies!');
 *     window.console.error('Jeepers!');
 *
 * **Note:** This class represents only the current window, while [WindowBase]
 * is a representation of any window, including other tabs, windows, and frames.
 *
 * ## See also
 *
 * * [WindowBase]
 *
 * ## Other resources
 *
 * * [DOM Window](https://developer.mozilla.org/en-US/docs/DOM/window) from MDN.
 * * [Window](http://www.w3.org/TR/Window/) from the W3C.
 */
@DomName('Window')
class Window extends EventTarget implements WindowEventHandlers, WindowBase, GlobalEventHandlers, _WindowTimers, WindowBase64 native "Window,DOMWindow" {

  /**
   * Returns a Future that completes just before the window is about to
   * repaint so the user can draw an animation frame.
   *
   * If you need to later cancel this animation, use [requestAnimationFrame]
   * instead.
   *
   * The [Future] completes to a timestamp that represents a floating
   * point value of the number of milliseconds that have elapsed since the page
   * started to load (which is also the timestamp at this call to
   * animationFrame).
   *
   * Note: The code that runs when the future completes should call
   * [animationFrame] again for the animation to continue.
   */
  Future<num> get animationFrame {
    var completer = new Completer<num>.sync();
    requestAnimationFrame((time) {
      completer.complete(time);
    });
    return completer.future;
  }

  /**
   * The newest document in this window.
   *
   * ## Other resources
   *
   * * [Loading web pages]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html)
   * from WHATWG.
   */
  Document get document => JS('Document', '#.document', this);

  WindowBase _open2(url, name) => JS('Window', '#.open(#,#)', this, url, name);

  WindowBase _open3(url, name, options) =>
      JS('Window', '#.open(#,#,#)', this, url, name, options);

  /**
   * Opens a new window.
   *
   * ## Other resources
   *
   * * [Window.open]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.open) from MDN.
   * * [Window open]
   * (http://docs.webplatform.org/wiki/dom/methods/open) from WebPlatform.org.
   */
  WindowBase open(String url, String name, [String options]) {
    if (options == null) {
      return _DOMWindowCrossFrame._createSafe(_open2(url, name));
    } else {
      return _DOMWindowCrossFrame._createSafe(_open3(url, name, options));
    }
  }

  // API level getter and setter for Location.
  // TODO: The cross domain safe wrapper can be inserted here.
  /**
   * The current location of this window.
   *
   *     Location currentLocation = window.location;
   *     print(currentLocation.href); // 'http://www.example.com:80/'
   */
  Location get location => _location;

  // TODO: consider forcing users to do: window.location.assign('string').
  /**
   * Sets the window's location, which causes the browser to navigate to the new
   * location. [value] may be a Location object or a String.
   */
  void set location(value) {
    _location = value;
  }

  // Native getter and setter to access raw Location object.
  dynamic get _location => JS('Location|Null', '#.location', this);
  void set _location(value) {
    JS('void', '#.location = #', this, value);
  }

  /**
   * Called to draw an animation frame and then request the window to repaint
   * after [callback] has finished (creating the animation).
   *
   * Use this method only if you need to later call [cancelAnimationFrame]. If
   * not, the preferred Dart idiom is to set animation frames by calling
   * [animationFrame], which returns a Future.
   *
   * Returns a non-zero valued integer to represent the request id for this
   * request. This value only needs to be saved if you intend to call
   * [cancelAnimationFrame] so you can specify the particular animation to
   * cancel.
   *
   * Note: The supplied [callback] needs to call [requestAnimationFrame] again
   * for the animation to continue.
   */
  @DomName('Window.requestAnimationFrame')
  int requestAnimationFrame(RequestAnimationFrameCallback callback) {
    _ensureRequestAnimationFrame();
    return _requestAnimationFrame(_wrapZone(callback));
  }

  /**
   * Cancels an animation frame request.
   *
   * ## Other resources
   *
   * * [Window.cancelAnimationFrame]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.cancelAnimationFrame) from MDN.
   */
  void cancelAnimationFrame(int id) {
    _ensureRequestAnimationFrame();
    _cancelAnimationFrame(id);
  }

  @JSName('requestAnimationFrame')
  int _requestAnimationFrame(RequestAnimationFrameCallback callback) native;

  @JSName('cancelAnimationFrame')
  void _cancelAnimationFrame(int id) native;

  _ensureRequestAnimationFrame() {
    if (JS('bool',
           '!!(#.requestAnimationFrame && #.cancelAnimationFrame)', this, this))
      return;

    JS('void',
       r"""
  (function($this) {
   var vendors = ['ms', 'moz', 'webkit', 'o'];
   for (var i = 0; i < vendors.length && !$this.requestAnimationFrame; ++i) {
     $this.requestAnimationFrame = $this[vendors[i] + 'RequestAnimationFrame'];
     $this.cancelAnimationFrame =
         $this[vendors[i]+'CancelAnimationFrame'] ||
         $this[vendors[i]+'CancelRequestAnimationFrame'];
   }
   if ($this.requestAnimationFrame && $this.cancelAnimationFrame) return;
   $this.requestAnimationFrame = function(callback) {
      return window.setTimeout(function() {
        callback(Date.now());
      }, 16 /* 16ms ~= 60fps */);
   };
   $this.cancelAnimationFrame = function(id) { clearTimeout(id); }
  })(#)""",
       this);
  }

  /**
   * Gets an instance of the Indexed DB factory to being using Indexed DB.
   *
   * Use [indexed_db.IdbFactory.supported] to check if Indexed DB is supported on the
   * current platform.
   */
  @SupportedBrowser(SupportedBrowser.CHROME, '23.0')
  @SupportedBrowser(SupportedBrowser.FIREFOX, '15.0')
  @SupportedBrowser(SupportedBrowser.IE, '10.0')
  @Experimental()
  IdbFactory get indexedDB =>
      JS('IdbFactory|Null',  // If not supported, returns null.
         '#.indexedDB || #.webkitIndexedDB || #.mozIndexedDB',
         this, this, this);

  /// The debugging console for this window.
  @DomName('Window.console')
  Console get console => Console._safeConsole;


  /**
   * Access a sandboxed file system of the specified `size`. If `persistent` is
   * true, the application will request permission from the user to create
   * lasting storage. This storage cannot be freed without the user's
   * permission. Returns a [Future] whose value stores a reference to the
   * sandboxed file system for use. Because the file system is sandboxed,
   * applications cannot access file systems created in other web pages.
   */
  Future<FileSystem> requestFileSystem(int size, {bool persistent: false}) {
    return _requestFileSystem(persistent? 1 : 0, size);
  }

  /**
   * Converts a point from node coordinates to this window's coordinates.
   *
   * ## Other resources
   *
   * * [webkitConvertPointFromPageToNode]
   * (https://developer.apple.com/library/safari/documentation/DataManagement/Reference/DOMWindowAdditionsReference/DOMWindowAdditions/DOMWindowAdditions.html#//apple_ref/javascript/instm/DOMWindow/webkitConvertPointFromNodeToPage)
   * from Safari Development Library.
   */
  @DomName('Window.convertPointFromNodeToPage')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  Point convertPointFromNodeToPage(Node node, Point point) {
    var result = _convertPointFromNodeToPage(node,
        new _DomPoint(point.x, point.y));
    return new Point(result.x, result.y);
  }

  /**
   * Converts a point from this window's coordinates to node coordinates.
   *
   * ## Other resources
   *
   * * [webkitConvertPointFromPageToNode]
   * (https://developer.apple.com/library/safari/documentation/DataManagement/Reference/DOMWindowAdditionsReference/DOMWindowAdditions/DOMWindowAdditions.html#//apple_ref/javascript/instm/DOMWindow/webkitConvertPointFromPageToNode)
   * from Safari Development Library.
   */
  @DomName('Window.convertPointFromPageToNode')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  Point convertPointFromPageToNode(Node node, Point point) {
    var result = _convertPointFromPageToNode(node,
        new _DomPoint(point.x, point.y));
    return new Point(result.x, result.y);
  }

  /**
   * Checks whether [convertPointFromNodeToPage] and
   * [convertPointFromPageToNode] are supported on the current platform.
   */
  static bool get supportsPointConversions => _DomPoint.supported;
  // To suppress missing implicit constructor warnings.
  factory Window._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `contentloaded` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.DOMContentLoadedEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> contentLoadedEvent = const EventStreamProvider<Event>('DOMContentLoaded');

  /**
   * Static factory designed to expose `devicemotion` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.devicemotionEvent')
  @DocsEditable()
  // http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
  @Experimental()
  static const EventStreamProvider<DeviceMotionEvent> deviceMotionEvent = const EventStreamProvider<DeviceMotionEvent>('devicemotion');

  /**
   * Static factory designed to expose `deviceorientation` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.deviceorientationEvent')
  @DocsEditable()
  // http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
  @Experimental()
  static const EventStreamProvider<DeviceOrientationEvent> deviceOrientationEvent = const EventStreamProvider<DeviceOrientationEvent>('deviceorientation');

  /**
   * Static factory designed to expose `hashchange` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.hashchangeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> hashChangeEvent = const EventStreamProvider<Event>('hashchange');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.messageEvent')
  @DocsEditable()
  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');

  /**
   * Static factory designed to expose `offline` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.offlineEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> offlineEvent = const EventStreamProvider<Event>('offline');

  /**
   * Static factory designed to expose `online` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.onlineEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> onlineEvent = const EventStreamProvider<Event>('online');

  /**
   * Static factory designed to expose `pagehide` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.pagehideEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> pageHideEvent = const EventStreamProvider<Event>('pagehide');

  /**
   * Static factory designed to expose `pageshow` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.pageshowEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> pageShowEvent = const EventStreamProvider<Event>('pageshow');

  /**
   * Static factory designed to expose `popstate` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.popstateEvent')
  @DocsEditable()
  static const EventStreamProvider<PopStateEvent> popStateEvent = const EventStreamProvider<PopStateEvent>('popstate');

  /**
   * Static factory designed to expose `storage` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.storageEvent')
  @DocsEditable()
  static const EventStreamProvider<StorageEvent> storageEvent = const EventStreamProvider<StorageEvent>('storage');

  /**
   * Static factory designed to expose `unload` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.unloadEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> unloadEvent = const EventStreamProvider<Event>('unload');

  /**
   * Static factory designed to expose `animationend` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.webkitAnimationEndEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  static const EventStreamProvider<AnimationEvent> animationEndEvent = const EventStreamProvider<AnimationEvent>('webkitAnimationEnd');

  /**
   * Static factory designed to expose `animationiteration` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.webkitAnimationIterationEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  static const EventStreamProvider<AnimationEvent> animationIterationEvent = const EventStreamProvider<AnimationEvent>('webkitAnimationIteration');

  /**
   * Static factory designed to expose `animationstart` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.webkitAnimationStartEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  static const EventStreamProvider<AnimationEvent> animationStartEvent = const EventStreamProvider<AnimationEvent>('webkitAnimationStart');

  /**
   * Indicates that file system data cannot be cleared unless given user
   * permission.
   *
   * ## Other resources
   *
   * * [Exploring the FileSystem APIs]
   * (http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.
   * * [File API]
   * (http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem) from W3C.
   */
  @DomName('Window.PERSISTENT')
  @DocsEditable()
  // http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem
  @Experimental()
  static const int PERSISTENT = 1;

  /**
   * Indicates that file system data can be cleared at any time.
   *
   * ## Other resources
   *
   * * [Exploring the FileSystem APIs]
   * (http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.
   * * [File API]
   * (http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem) from W3C.
   */
  @DomName('Window.TEMPORARY')
  @DocsEditable()
  // http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem
  @Experimental()
  static const int TEMPORARY = 0;

  @JSName('CSS')
  /**
   * Entrypoint for CSS-related functions.
   *
   * ## Other resources
   *
   * * [The CSS interface](http://dev.w3.org/csswg/css-conditional/#the-css-interface) from W3C.
   */
  @DomName('Window.CSS')
  @DocsEditable()
  final Css css;

  /**
   * The application cache for this window.
   *
   * ## Other resources
   *
   * * [A beginner's guide to using the application cache]
   * (http://www.html5rocks.com/en/tutorials/appcache/beginner) from HTML5Rocks.
   * * [Application cache API]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html#application-cache-api)
   * from WHATWG.
   */
  @DomName('Window.applicationCache')
  @DocsEditable()
  final ApplicationCache applicationCache;

  @DomName('Window.closed')
  @DocsEditable()
  final bool closed;

  /**
   * Entrypoint for the browser's cryptographic functions.
   *
   * ## Other resources
   *
   * * [Web cryptography API](http://www.w3.org/TR/WebCryptoAPI/) from W3C.
   */
  @DomName('Window.crypto')
  @DocsEditable()
  // http://www.w3.org/TR/WebCryptoAPI/
  @Experimental()
  final Crypto crypto;

  /// *Deprecated*.
  @DomName('Window.defaultStatus')
  @DocsEditable()
  @Experimental() // non-standard
  String defaultStatus;

  /// *Deprecated*.
  @DomName('Window.defaultstatus')
  @DocsEditable()
  @Experimental() // non-standard
  String defaultstatus;

  /**
   * The ratio between physical pixels and logical CSS pixels.
   *
   * ## Other resources
   *
   * * [devicePixelRatio]
   * (http://www.quirksmode.org/blog/archives/2012/06/devicepixelrati.html) from
   * quirksmode.
   * * [More about devicePixelRatio]
   * (http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html) from
   * quirksmode.
   */
  @DomName('Window.devicePixelRatio')
  @DocsEditable()
  // http://www.quirksmode.org/blog/archives/2012/06/devicepixelrati.html
  @Experimental() // non-standard
  final double devicePixelRatio;

  /**
   * The current session history for this window's newest document.
   *
   * ## Other resources
   *
   * * [Loading web pages]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html)
   * from WHATWG.
   */
  @DomName('Window.history')
  @DocsEditable()
  final History history;

  /**
   * The height of the viewport including scrollbars.
   *
   * ## Other resources
   *
   * * [innerHeight]
   * (http://docs.webplatform.org/wiki/css/cssom/properties/innerHeight) from
   * WebPlatform.org.
   */
  @DomName('Window.innerHeight')
  @DocsEditable()
  final int innerHeight;

  /**
   * The width of the viewport including scrollbars.
   *
   * ## Other resources
   *
   * * [innerWidth]
   * (http://docs.webplatform.org/wiki/css/cssom/properties/innerWidth) from
   * WebPlatform.org.
   */
  @DomName('Window.innerWidth')
  @DocsEditable()
  final int innerWidth;

  /**
   * Storage for this window that persists across sessions.
   *
   * ## Other resources
   *
   * * [DOM storage guide]
   * (https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage) from
   * MDN.
   * * [The past, present & future of local storage for web applications]
   * (http://diveintohtml5.info/storage.html) from Dive Into HTML5.
   * * [Local storage specification]
   * (http://www.w3.org/TR/webstorage/#the-localstorage-attribute) from W3C.
   */
  @DomName('Window.localStorage')
  @DocsEditable()
  final Storage localStorage;

  /**
   * This window's location bar, which displays the URL.
   *
   * ## Other resources
   *
   * * [Browser interface elements]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
   * from WHATWG.
   */
  @DomName('Window.locationbar')
  @DocsEditable()
  final BarProp locationbar;

  /**
   * This window's menu bar, which displays menu commands.
   *
   * ## Other resources
   *
   * * [Browser interface elements]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
   * from WHATWG.
   */
  @DomName('Window.menubar')
  @DocsEditable()
  final BarProp menubar;

  /**
   * The name of this window.
   *
   * ## Other resources
   *
   * * [Window name]
   * (http://docs.webplatform.org/wiki/html/attributes/name_(window)) from
   * WebPlatform.org.
   */
  @DomName('Window.name')
  @DocsEditable()
  String name;

  /**
   * The user agent accessing this window.
   *
   * ## Other resources
   *
   * * [The navigator object]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#the-navigator-object)
   * from WHATWG.
   */
  @DomName('Window.navigator')
  @DocsEditable()
  final Navigator navigator;

  /**
   * Whether objects are drawn offscreen before being displayed.
   *
   * ## Other resources
   *
   * * [offscreenBuffering]
   * (http://docs.webplatform.org/wiki/dom/properties/offscreenBuffering) from
   * WebPlatform.org.
   */
  @DomName('Window.offscreenBuffering')
  @DocsEditable()
  @Experimental() // non-standard
  final bool offscreenBuffering;

  @DomName('Window.opener')
  @DocsEditable()
  WindowBase get opener => _convertNativeToDart_Window(this._get_opener);
  @JSName('opener')
  @DomName('Window.opener')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_opener;

  void set opener(Window value) {
    JS("void", "#.opener = #", this, value);
  }

  @DomName('Window.orientation')
  @DocsEditable()
  @Experimental() // untriaged
  final int orientation;

  /**
   * The height of this window including all user interface elements.
   *
   * ## Other resources
   *
   * * [outerHeight]
   * (http://docs.webplatform.org/wiki/css/cssom/properties/outerHeight) from
   * WebPlatform.org.
   */
  @DomName('Window.outerHeight')
  @DocsEditable()
  final int outerHeight;

  /**
   * The width of the window including all user interface elements.
   *
   * ## Other resources
   *
   * * [outerWidth]
   * (http://docs.webplatform.org/wiki/css/cssom/properties/outerWidth) from
   * WebPlatform.org.
   */
  @DomName('Window.outerWidth')
  @DocsEditable()
  final int outerWidth;

  /**
   * The distance this window has been scrolled horizontally.
   *
   * This attribute is an alias for [scrollX].
   *
   * ## Other resources
   *
   * * [The Screen interface specification]
   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
   * * [scrollX and pageXOffset]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX) from MDN.
   */
  @DomName('Window.pageXOffset')
  @DocsEditable()
  final int pageXOffset;

  /**
   * The distance this window has been scrolled vertically.
   *
   * This attribute is an alias for [scrollY].
   *
   * ## Other resources
   *
   * * [The Screen interface specification]
   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
   * * [scrollY and pageYOffset]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY) from MDN.
   */
  @DomName('Window.pageYOffset')
  @DocsEditable()
  final int pageYOffset;

  @DomName('Window.parent')
  @DocsEditable()
  WindowBase get parent => _convertNativeToDart_Window(this._get_parent);
  @JSName('parent')
  @DomName('Window.parent')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_parent;

  /**
   * Timing and navigation data for this window.
   *
   * ## Other resources
   *
   * * [Measuring page load speed with navigation timeing]
   * (http://www.html5rocks.com/en/tutorials/webperformance/basics/) from
   * HTML5Rocks.
   * * [Navigation timing specification]
   * (http://www.w3.org/TR/navigation-timing/) from W3C.
   */
  @DomName('Window.performance')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE)
  final Performance performance;

  /**
   * Information about the screen displaying this window.
   *
   * ## Other resources
   *
   * * [The Screen interface specification]
   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
   */
  @DomName('Window.screen')
  @DocsEditable()
  final Screen screen;

  /**
   * The distance from the left side of the screen to the left side of this
   * window.
   *
   * ## Other resources
   *
   * * [The Screen interface specification]
   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
   */
  @DomName('Window.screenLeft')
  @DocsEditable()
  final int screenLeft;

  /**
   * The distance from the top of the screen to the top of this window.
   *
   * ## Other resources
   *
   * * [The Screen interface specification]
   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
   */
  @DomName('Window.screenTop')
  @DocsEditable()
  final int screenTop;

  /**
   * The distance from the left side of the screen to the mouse pointer.
   *
   * ## Other resources
   *
   * * [The Screen interface specification]
   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
   */
  @DomName('Window.screenX')
  @DocsEditable()
  final int screenX;

  /**
   * The distance from the top of the screen to the mouse pointer.
   *
   * ## Other resources
   *
   * * [The Screen interface specification]
   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
   */
  @DomName('Window.screenY')
  @DocsEditable()
  final int screenY;

  /**
   * This window's scroll bars.
   *
   * ## Other resources
   *
   * * [Browser interface elements]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
   * from WHATWG.
   */
  @DomName('Window.scrollbars')
  @DocsEditable()
  final BarProp scrollbars;

  /**
   * The current window.
   *
   * ## Other resources
   *
   * * [Window.self]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.self) from MDN.
   */
  @DomName('Window.self')
  @DocsEditable()
  WindowBase get self => _convertNativeToDart_Window(this._get_self);
  @JSName('self')
  /**
   * The current window.
   *
   * ## Other resources
   *
   * * [Window.self]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.self) from MDN.
   */
  @DomName('Window.self')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_self;

  /**
   * Storage for this window that is cleared when this session ends.
   *
   * ## Other resources
   *
   * * [DOM storage guide]
   * (https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage) from
   * MDN.
   * * [The past, present & future of local storage for web applications]
   * (http://diveintohtml5.info/storage.html) from Dive Into HTML5.
   * * [Local storage specification]
   * (http://www.w3.org/TR/webstorage/#dom-sessionstorage) from W3C.
   */
  @DomName('Window.sessionStorage')
  @DocsEditable()
  final Storage sessionStorage;

  /**
   * Access to speech synthesis in the browser.
   *
   * ## Other resources
   *
   * * [Web speech specification]
   * (https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section)
   * from W3C.
   */
  @DomName('Window.speechSynthesis')
  @DocsEditable()
  // https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section
  @Experimental()
  final SpeechSynthesis speechSynthesis;

  /// *Deprecated*.
  @DomName('Window.status')
  @DocsEditable()
  String status;

  /**
   * This window's status bar.
   *
   * ## Other resources
   *
   * * [Browser interface elements]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
   * from WHATWG.
   */
  @DomName('Window.statusbar')
  @DocsEditable()
  final BarProp statusbar;

  /**
   * Access to CSS media queries.
   *
   * ## Other resources
   *
   * * [StyleMedia class reference]
   * (https://developer.apple.com/library/safari/documentation/SafariDOMAdditions/Reference/StyleMedia/StyleMedia/StyleMedia.html)
   * from Safari Developer Library.
   */
  @DomName('Window.styleMedia')
  @DocsEditable()
  // http://developer.apple.com/library/safari/#documentation/SafariDOMAdditions/Reference/StyleMedia/StyleMedia/StyleMedia.html
  @Experimental() // nonstandard
  final StyleMedia styleMedia;

  /**
   * This window's tool bar.
   *
   * ## Other resources
   *
   * * [Browser interface elements]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
   * from WHATWG.
   */
  @DomName('Window.toolbar')
  @DocsEditable()
  final BarProp toolbar;

  @DomName('Window.top')
  @DocsEditable()
  WindowBase get top => _convertNativeToDart_Window(this._get_top);
  @JSName('top')
  @DomName('Window.top')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_top;

  /**
   * The current window.
   *
   * ## Other resources
   *
   * * [Window.window]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.window) from MDN.
   */
  @DomName('Window.window')
  @DocsEditable()
  WindowBase get window => _convertNativeToDart_Window(this._get_window);
  @JSName('window')
  /**
   * The current window.
   *
   * ## Other resources
   *
   * * [Window.window]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.window) from MDN.
   */
  @DomName('Window.window')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_window;

  @DomName('Window.__getter__')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  WindowBase __getter__(index_OR_name) {
    if ((index_OR_name is int || index_OR_name == null)) {
      return _convertNativeToDart_Window(__getter___1(index_OR_name));
    }
    if ((index_OR_name is String || index_OR_name == null)) {
      return _convertNativeToDart_Window(__getter___2(index_OR_name));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  @JSName('__getter__')
  @DomName('Window.__getter__')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  __getter___1(int index) native;
  @JSName('__getter__')
  @DomName('Window.__getter__')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  __getter___2(String name) native;

  /**
   * Displays a modal alert to the user.
   *
   * ## Other resources
   *
   * * [User prompts]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#user-prompts)
   * from WHATWG.
   */
  @DomName('Window.alert')
  @DocsEditable()
  void alert(String message) native;

  @DomName('Window.close')
  @DocsEditable()
  void close() native;

  /**
   * Displays a modal OK/Cancel prompt to the user.
   *
   * ## Other resources
   *
   * * [User prompts]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#user-prompts)
   * from WHATWG.
   */
  @DomName('Window.confirm')
  @DocsEditable()
  bool confirm(String message) native;

  /**
   * Finds text in this window.
   *
   * ## Other resources
   *
   * * [Window.find]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.find) from MDN.
   */
  @DomName('Window.find')
  @DocsEditable()
  @Experimental() // non-standard
  bool find(String string, bool caseSensitive, bool backwards, bool wrap, bool wholeWord, bool searchInFrames, bool showDialog) native;

  @JSName('getComputedStyle')
  @DomName('Window.getComputedStyle')
  @DocsEditable()
  CssStyleDeclaration _getComputedStyle(Element element, String pseudoElement) native;

  @JSName('getMatchedCSSRules')
  /**
   * Returns all CSS rules that apply to the element's pseudo-element.
   */
  @DomName('Window.getMatchedCSSRules')
  @DocsEditable()
  @Experimental() // non-standard
  @Returns('_CssRuleList')
  @Creates('_CssRuleList')
  List<CssRule> getMatchedCssRules(Element element, String pseudoElement) native;

  /**
   * Returns the currently selected text.
   *
   * ## Other resources
   *
   * * [Window.getSelection]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.getSelection)
   * from MDN.
   */
  @DomName('Window.getSelection')
  @DocsEditable()
  Selection getSelection() native;

  /**
   * Returns a list of media queries for the given query string.
   *
   * ## Other resources
   *
   * * [Testing media queries]
   * (https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Testing_media_queries)
   * from MDN.
   * * [The MediaQueryList specification]
   * (http://www.w3.org/TR/cssom-view/#the-mediaquerylist-interface) from W3C.
   */
  @DomName('Window.matchMedia')
  @DocsEditable()
  MediaQueryList matchMedia(String query) native;

  /**
   * Moves this window.
   *
   * x and y can be negative.
   *
   * ## Other resources
   *
   * * [Window.moveBy]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.moveBy) from MDN.
   * * [Window.moveBy]
   * (http://dev.w3.org/csswg/cssom-view/#dom-window-moveby) from W3C.
   */
  @DomName('Window.moveBy')
  @DocsEditable()
  void moveBy(num x, num y) native;

  @JSName('moveTo')
  @DomName('Window.moveTo')
  @DocsEditable()
  void _moveTo(num x, num y) native;

  /// *Deprecated.*
  @DomName('Window.openDatabase')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.w3.org/TR/webdatabase/
  @Experimental() // deprecated
  @Creates('SqlDatabase')
  SqlDatabase openDatabase(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) native;

  @DomName('Window.postMessage')
  @DocsEditable()
  void postMessage(/*SerializedScriptValue*/ message, String targetOrigin, [List<MessagePort> messagePorts]) {
    if (messagePorts != null) {
      var message_1 = convertDartToNative_SerializedScriptValue(message);
      _postMessage_1(message_1, targetOrigin, messagePorts);
      return;
    }
    var message_2 = convertDartToNative_SerializedScriptValue(message);
    _postMessage_2(message_2, targetOrigin);
    return;
  }
  @JSName('postMessage')
  @DomName('Window.postMessage')
  @DocsEditable()
  void _postMessage_1(message, targetOrigin, List<MessagePort> messagePorts) native;
  @JSName('postMessage')
  @DomName('Window.postMessage')
  @DocsEditable()
  void _postMessage_2(message, targetOrigin) native;

  /**
   * Opens the print dialog for this window.
   *
   * ## Other resources
   *
   * * [Window.print]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.print) from MDN.
   */
  @DomName('Window.print')
  @DocsEditable()
  void print() native;

  /**
   * Resizes this window by an offset.
   *
   * ## Other resources
   *
   * * [Window resizeBy] (http://docs.webplatform.org/wiki/dom/methods/resizeBy)
   * from WebPlatform.org.
   */
  @DomName('Window.resizeBy')
  @DocsEditable()
  void resizeBy(num x, num y) native;

  /**
   * Resizes this window to a specific width and height.
   *
   * ## Other resources
   *
   * * [Window resizeTo] (http://docs.webplatform.org/wiki/dom/methods/resizeTo)
   * from WebPlatform.org.
   */
  @DomName('Window.resizeTo')
  @DocsEditable()
  void resizeTo(num width, num height) native;

  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scrollTo].
   *
   * ## Other resources
   *
   * * [Window scroll] (http://docs.webplatform.org/wiki/dom/methods/scroll)
   * from WebPlatform.org.
   */
  @DomName('Window.scroll')
  @DocsEditable()
  void scroll(int x, int y, [Map scrollOptions]) {
    if (scrollOptions != null) {
      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
      _scroll_1(x, y, scrollOptions_1);
      return;
    }
    _scroll_2(x, y);
    return;
  }
  @JSName('scroll')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scrollTo].
   *
   * ## Other resources
   *
   * * [Window scroll] (http://docs.webplatform.org/wiki/dom/methods/scroll)
   * from WebPlatform.org.
   */
  @DomName('Window.scroll')
  @DocsEditable()
  void _scroll_1(x, y, scrollOptions) native;
  @JSName('scroll')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scrollTo].
   *
   * ## Other resources
   *
   * * [Window scroll] (http://docs.webplatform.org/wiki/dom/methods/scroll)
   * from WebPlatform.org.
   */
  @DomName('Window.scroll')
  @DocsEditable()
  void _scroll_2(x, y) native;

  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window scrollBy] (http://docs.webplatform.org/wiki/dom/methods/scrollBy)
   * from WebPlatform.org.
   */
  @DomName('Window.scrollBy')
  @DocsEditable()
  void scrollBy(int x, int y, [Map scrollOptions]) {
    if (scrollOptions != null) {
      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
      _scrollBy_1(x, y, scrollOptions_1);
      return;
    }
    _scrollBy_2(x, y);
    return;
  }
  @JSName('scrollBy')
  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window scrollBy] (http://docs.webplatform.org/wiki/dom/methods/scrollBy)
   * from WebPlatform.org.
   */
  @DomName('Window.scrollBy')
  @DocsEditable()
  void _scrollBy_1(x, y, scrollOptions) native;
  @JSName('scrollBy')
  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window scrollBy] (http://docs.webplatform.org/wiki/dom/methods/scrollBy)
   * from WebPlatform.org.
   */
  @DomName('Window.scrollBy')
  @DocsEditable()
  void _scrollBy_2(x, y) native;

  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scroll].
   *
   * ## Other resources
   *
   * * [Window scrollTo] (http://docs.webplatform.org/wiki/dom/methods/scrollTo)
   * from WebPlatform.org.
   */
  @DomName('Window.scrollTo')
  @DocsEditable()
  void scrollTo(int x, int y, [Map scrollOptions]) {
    if (scrollOptions != null) {
      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
      _scrollTo_1(x, y, scrollOptions_1);
      return;
    }
    _scrollTo_2(x, y);
    return;
  }
  @JSName('scrollTo')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scroll].
   *
   * ## Other resources
   *
   * * [Window scrollTo] (http://docs.webplatform.org/wiki/dom/methods/scrollTo)
   * from WebPlatform.org.
   */
  @DomName('Window.scrollTo')
  @DocsEditable()
  void _scrollTo_1(x, y, scrollOptions) native;
  @JSName('scrollTo')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scroll].
   *
   * ## Other resources
   *
   * * [Window scrollTo] (http://docs.webplatform.org/wiki/dom/methods/scrollTo)
   * from WebPlatform.org.
   */
  @DomName('Window.scrollTo')
  @DocsEditable()
  void _scrollTo_2(x, y) native;

  /**
   * Opens a new page as a modal dialog.
   *
   * ## Other resources
   *
   * * [Dialogs implemented using separate documents]
   * (http://www.w3.org/html/wg/drafts/html/master/webappapis.html#dialogs-implemented-using-separate-documents)
   * from W3C.
   */
  @DomName('Window.showModalDialog')
  @DocsEditable()
  @Creates('Null')
  Object showModalDialog(String url, [Object dialogArgs, String featureArgs]) native;

  /**
   * Stops the window from loading.
   *
   * ## Other resources
   *
   * * [The Window object]
   * (http://www.w3.org/html/wg/drafts/html/master/browsers.html#the-window-object)
   * from W3C.
   */
  @DomName('Window.stop')
  @DocsEditable()
  void stop() native;

  @DomName('Window.toString')
  @DocsEditable()
  String toString() native;

  @JSName('webkitConvertPointFromNodeToPage')
  @DomName('Window.webkitConvertPointFromNodeToPage')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://developer.apple.com/library/safari/#documentation/DataManagement/Reference/DOMWindowAdditionsReference/DOMWindowAdditions/DOMWindowAdditions.html
  _DomPoint _convertPointFromNodeToPage(Node node, _DomPoint p) native;

  @JSName('webkitConvertPointFromPageToNode')
  @DomName('Window.webkitConvertPointFromPageToNode')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://developer.apple.com/library/safari/#documentation/DataManagement/Reference/DOMWindowAdditionsReference/DOMWindowAdditions/DOMWindowAdditions.html
  _DomPoint _convertPointFromPageToNode(Node node, _DomPoint p) native;

  @JSName('webkitRequestFileSystem')
  @DomName('Window.webkitRequestFileSystem')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @Experimental()
  // http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem
  void __requestFileSystem(int type, int size, _FileSystemCallback successCallback, [_ErrorCallback errorCallback]) native;

  @JSName('webkitRequestFileSystem')
  @DomName('Window.webkitRequestFileSystem')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @Experimental()
  // http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem
  Future<FileSystem> _requestFileSystem(int type, int size) {
    var completer = new Completer<FileSystem>();
    __requestFileSystem(type, size,
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  @JSName('webkitResolveLocalFileSystemURL')
  /**
   * Asynchronously retrieves a local filesystem entry.
   *
   * ## Other resources
   *
   * * [Obtaining access to file system entry points]
   * (http://www.w3.org/TR/file-system-api/#obtaining-access-to-file-system-entry-points)
   * from W3C.
   */
  @DomName('Window.webkitResolveLocalFileSystemURL')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @Experimental()
  // http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem
  void _resolveLocalFileSystemUrl(String url, _EntryCallback successCallback, [_ErrorCallback errorCallback]) native;

  @JSName('webkitResolveLocalFileSystemURL')
  /**
   * Asynchronously retrieves a local filesystem entry.
   *
   * ## Other resources
   *
   * * [Obtaining access to file system entry points]
   * (http://www.w3.org/TR/file-system-api/#obtaining-access-to-file-system-entry-points)
   * from W3C.
   */
  @DomName('Window.webkitResolveLocalFileSystemURL')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @Experimental()
  // http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem
  Future<Entry> resolveLocalFileSystemUrl(String url) {
    var completer = new Completer<Entry>();
    _resolveLocalFileSystemUrl(url,
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  // From WindowBase64

  @DomName('Window.atob')
  @DocsEditable()
  String atob(String string) native;

  @DomName('Window.btoa')
  @DocsEditable()
  String btoa(String string) native;

  // From WindowTimers

  @JSName('clearInterval')
  @DomName('Window.clearInterval')
  @DocsEditable()
  void _clearInterval(int handle) native;

  @JSName('clearTimeout')
  @DomName('Window.clearTimeout')
  @DocsEditable()
  void _clearTimeout(int handle) native;

  @JSName('setInterval')
  @DomName('Window.setInterval')
  @DocsEditable()
  int _setInterval(Object handler, int timeout) native;

  @JSName('setTimeout')
  @DomName('Window.setTimeout')
  @DocsEditable()
  int _setTimeout(Object handler, int timeout) native;

  /// Stream of `contentloaded` events handled by this [Window].
  @DomName('Window.onDOMContentLoaded')
  @DocsEditable()
  Stream<Event> get onContentLoaded => contentLoadedEvent.forTarget(this);

  /// Stream of `abort` events handled by this [Window].
  @DomName('Window.onabort')
  @DocsEditable()
  Stream<Event> get onAbort => Element.abortEvent.forTarget(this);

  /// Stream of `blur` events handled by this [Window].
  @DomName('Window.onblur')
  @DocsEditable()
  Stream<Event> get onBlur => Element.blurEvent.forTarget(this);

  /// Stream of `change` events handled by this [Window].
  @DomName('Window.onchange')
  @DocsEditable()
  Stream<Event> get onChange => Element.changeEvent.forTarget(this);

  /// Stream of `click` events handled by this [Window].
  @DomName('Window.onclick')
  @DocsEditable()
  Stream<MouseEvent> get onClick => Element.clickEvent.forTarget(this);

  /// Stream of `contextmenu` events handled by this [Window].
  @DomName('Window.oncontextmenu')
  @DocsEditable()
  Stream<MouseEvent> get onContextMenu => Element.contextMenuEvent.forTarget(this);

  /// Stream of `doubleclick` events handled by this [Window].
  @DomName('Window.ondblclick')
  @DocsEditable()
  Stream<Event> get onDoubleClick => Element.doubleClickEvent.forTarget(this);

  /// Stream of `devicemotion` events handled by this [Window].
  @DomName('Window.ondevicemotion')
  @DocsEditable()
  // http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
  @Experimental()
  Stream<DeviceMotionEvent> get onDeviceMotion => deviceMotionEvent.forTarget(this);

  /// Stream of `deviceorientation` events handled by this [Window].
  @DomName('Window.ondeviceorientation')
  @DocsEditable()
  // http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
  @Experimental()
  Stream<DeviceOrientationEvent> get onDeviceOrientation => deviceOrientationEvent.forTarget(this);

  /// Stream of `drag` events handled by this [Window].
  @DomName('Window.ondrag')
  @DocsEditable()
  Stream<MouseEvent> get onDrag => Element.dragEvent.forTarget(this);

  /// Stream of `dragend` events handled by this [Window].
  @DomName('Window.ondragend')
  @DocsEditable()
  Stream<MouseEvent> get onDragEnd => Element.dragEndEvent.forTarget(this);

  /// Stream of `dragenter` events handled by this [Window].
  @DomName('Window.ondragenter')
  @DocsEditable()
  Stream<MouseEvent> get onDragEnter => Element.dragEnterEvent.forTarget(this);

  /// Stream of `dragleave` events handled by this [Window].
  @DomName('Window.ondragleave')
  @DocsEditable()
  Stream<MouseEvent> get onDragLeave => Element.dragLeaveEvent.forTarget(this);

  /// Stream of `dragover` events handled by this [Window].
  @DomName('Window.ondragover')
  @DocsEditable()
  Stream<MouseEvent> get onDragOver => Element.dragOverEvent.forTarget(this);

  /// Stream of `dragstart` events handled by this [Window].
  @DomName('Window.ondragstart')
  @DocsEditable()
  Stream<MouseEvent> get onDragStart => Element.dragStartEvent.forTarget(this);

  /// Stream of `drop` events handled by this [Window].
  @DomName('Window.ondrop')
  @DocsEditable()
  Stream<MouseEvent> get onDrop => Element.dropEvent.forTarget(this);

  /// Stream of `error` events handled by this [Window].
  @DomName('Window.onerror')
  @DocsEditable()
  Stream<Event> get onError => Element.errorEvent.forTarget(this);

  /// Stream of `focus` events handled by this [Window].
  @DomName('Window.onfocus')
  @DocsEditable()
  Stream<Event> get onFocus => Element.focusEvent.forTarget(this);

  /// Stream of `hashchange` events handled by this [Window].
  @DomName('Window.onhashchange')
  @DocsEditable()
  Stream<Event> get onHashChange => hashChangeEvent.forTarget(this);

  /// Stream of `input` events handled by this [Window].
  @DomName('Window.oninput')
  @DocsEditable()
  Stream<Event> get onInput => Element.inputEvent.forTarget(this);

  /// Stream of `invalid` events handled by this [Window].
  @DomName('Window.oninvalid')
  @DocsEditable()
  Stream<Event> get onInvalid => Element.invalidEvent.forTarget(this);

  /// Stream of `keydown` events handled by this [Window].
  @DomName('Window.onkeydown')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyDown => Element.keyDownEvent.forTarget(this);

  /// Stream of `keypress` events handled by this [Window].
  @DomName('Window.onkeypress')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyPress => Element.keyPressEvent.forTarget(this);

  /// Stream of `keyup` events handled by this [Window].
  @DomName('Window.onkeyup')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyUp => Element.keyUpEvent.forTarget(this);

  /// Stream of `load` events handled by this [Window].
  @DomName('Window.onload')
  @DocsEditable()
  Stream<Event> get onLoad => Element.loadEvent.forTarget(this);

  /// Stream of `message` events handled by this [Window].
  @DomName('Window.onmessage')
  @DocsEditable()
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  /// Stream of `mousedown` events handled by this [Window].
  @DomName('Window.onmousedown')
  @DocsEditable()
  Stream<MouseEvent> get onMouseDown => Element.mouseDownEvent.forTarget(this);

  /// Stream of `mouseenter` events handled by this [Window].
  @DomName('Window.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseEnter => Element.mouseEnterEvent.forTarget(this);

  /// Stream of `mouseleave` events handled by this [Window].
  @DomName('Window.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseLeave => Element.mouseLeaveEvent.forTarget(this);

  /// Stream of `mousemove` events handled by this [Window].
  @DomName('Window.onmousemove')
  @DocsEditable()
  Stream<MouseEvent> get onMouseMove => Element.mouseMoveEvent.forTarget(this);

  /// Stream of `mouseout` events handled by this [Window].
  @DomName('Window.onmouseout')
  @DocsEditable()
  Stream<MouseEvent> get onMouseOut => Element.mouseOutEvent.forTarget(this);

  /// Stream of `mouseover` events handled by this [Window].
  @DomName('Window.onmouseover')
  @DocsEditable()
  Stream<MouseEvent> get onMouseOver => Element.mouseOverEvent.forTarget(this);

  /// Stream of `mouseup` events handled by this [Window].
  @DomName('Window.onmouseup')
  @DocsEditable()
  Stream<MouseEvent> get onMouseUp => Element.mouseUpEvent.forTarget(this);

  /// Stream of `mousewheel` events handled by this [Window].
  @DomName('Window.onmousewheel')
  @DocsEditable()
  Stream<WheelEvent> get onMouseWheel => Element.mouseWheelEvent.forTarget(this);

  /// Stream of `offline` events handled by this [Window].
  @DomName('Window.onoffline')
  @DocsEditable()
  Stream<Event> get onOffline => offlineEvent.forTarget(this);

  /// Stream of `online` events handled by this [Window].
  @DomName('Window.ononline')
  @DocsEditable()
  Stream<Event> get onOnline => onlineEvent.forTarget(this);

  /// Stream of `pagehide` events handled by this [Window].
  @DomName('Window.onpagehide')
  @DocsEditable()
  Stream<Event> get onPageHide => pageHideEvent.forTarget(this);

  /// Stream of `pageshow` events handled by this [Window].
  @DomName('Window.onpageshow')
  @DocsEditable()
  Stream<Event> get onPageShow => pageShowEvent.forTarget(this);

  /// Stream of `popstate` events handled by this [Window].
  @DomName('Window.onpopstate')
  @DocsEditable()
  Stream<PopStateEvent> get onPopState => popStateEvent.forTarget(this);

  /// Stream of `reset` events handled by this [Window].
  @DomName('Window.onreset')
  @DocsEditable()
  Stream<Event> get onReset => Element.resetEvent.forTarget(this);

  /// Stream of `resize` events handled by this [Window].
  @DomName('Window.onresize')
  @DocsEditable()
  Stream<Event> get onResize => Element.resizeEvent.forTarget(this);

  /// Stream of `scroll` events handled by this [Window].
  @DomName('Window.onscroll')
  @DocsEditable()
  Stream<Event> get onScroll => Element.scrollEvent.forTarget(this);

  /// Stream of `search` events handled by this [Window].
  @DomName('Window.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  Stream<Event> get onSearch => Element.searchEvent.forTarget(this);

  /// Stream of `select` events handled by this [Window].
  @DomName('Window.onselect')
  @DocsEditable()
  Stream<Event> get onSelect => Element.selectEvent.forTarget(this);

  /// Stream of `storage` events handled by this [Window].
  @DomName('Window.onstorage')
  @DocsEditable()
  Stream<StorageEvent> get onStorage => storageEvent.forTarget(this);

  /// Stream of `submit` events handled by this [Window].
  @DomName('Window.onsubmit')
  @DocsEditable()
  Stream<Event> get onSubmit => Element.submitEvent.forTarget(this);

  /// Stream of `touchcancel` events handled by this [Window].
  @DomName('Window.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchCancel => Element.touchCancelEvent.forTarget(this);

  /// Stream of `touchend` events handled by this [Window].
  @DomName('Window.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchEnd => Element.touchEndEvent.forTarget(this);

  /// Stream of `touchmove` events handled by this [Window].
  @DomName('Window.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchMove => Element.touchMoveEvent.forTarget(this);

  /// Stream of `touchstart` events handled by this [Window].
  @DomName('Window.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchStart => Element.touchStartEvent.forTarget(this);

  /// Stream of `transitionend` events handled by this [Window].
  @DomName('Window.ontransitionend')
  @DocsEditable()
  Stream<TransitionEvent> get onTransitionEnd => Element.transitionEndEvent.forTarget(this);

  /// Stream of `unload` events handled by this [Window].
  @DomName('Window.onunload')
  @DocsEditable()
  Stream<Event> get onUnload => unloadEvent.forTarget(this);

  /// Stream of `animationend` events handled by this [Window].
  @DomName('Window.onwebkitAnimationEnd')
  @DocsEditable()
  @Experimental()
  Stream<AnimationEvent> get onAnimationEnd => animationEndEvent.forTarget(this);

  /// Stream of `animationiteration` events handled by this [Window].
  @DomName('Window.onwebkitAnimationIteration')
  @DocsEditable()
  @Experimental()
  Stream<AnimationEvent> get onAnimationIteration => animationIterationEvent.forTarget(this);

  /// Stream of `animationstart` events handled by this [Window].
  @DomName('Window.onwebkitAnimationStart')
  @DocsEditable()
  @Experimental()
  Stream<AnimationEvent> get onAnimationStart => animationStartEvent.forTarget(this);


  /**
   * Static factory designed to expose `beforeunload` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.beforeunloadEvent')
  static const EventStreamProvider<BeforeUnloadEvent> beforeUnloadEvent =
      const _BeforeUnloadEventStreamProvider('beforeunload');

  /// Stream of `beforeunload` events handled by this [Window].
  @DomName('Window.onbeforeunload')
  Stream<Event> get onBeforeUnload => beforeUnloadEvent.forTarget(this);

  /**
   * Moves this window to a specific position.
   *
   * x and y can be negative.
   *
   * ## Other resources
   *
   * * [Window.moveTo]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.moveTo) from MDN.
   * * [Window.moveTo]
   * (http://dev.w3.org/csswg/cssom-view/#dom-window-moveto) from W3C.
   */
  void moveTo(Point p) {
    _moveTo(p.x, p.y);
  }

  /**
   * The distance this window has been scrolled horizontally.
   *
   * ## Other resources
   *
   * * [The Screen interface specification]
   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
   * * [scrollX]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX) from MDN.
   */
  int get scrollX => JS('bool', '("scrollX" in #)', this) ? JS('int',
      '#.scrollX', this) : document.documentElement.scrollLeft;

  /**
   * The distance this window has been scrolled vertically.
   *
   * ## Other resources
   *
   * * [The Screen interface specification]
   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
   * * [scrollY]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY) from MDN.
   */
  int get scrollY => JS('bool', '("scrollY" in #)', this) ? JS('int',
      '#.scrollY', this) : document.documentElement.scrollTop;
}

class _BeforeUnloadEvent extends _WrappedEvent implements BeforeUnloadEvent {
  String _returnValue;

  _BeforeUnloadEvent(Event base): super(base);

  String get returnValue => _returnValue;

  void set returnValue(String value) {
    _returnValue = value;
    // FF and IE use the value as the return value, Chrome will return this from
    // the event callback function.
    if (JS('bool', '("returnValue" in #)', wrapped)) {
      JS('void', '#.returnValue = #', wrapped, value);
    }
  }
}

class _BeforeUnloadEventStreamProvider implements
    EventStreamProvider<BeforeUnloadEvent> {
  final String _eventType;

  const _BeforeUnloadEventStreamProvider(this._eventType);

  Stream<BeforeUnloadEvent> forTarget(EventTarget e, {bool useCapture: false}) {
    var stream = new _EventStream(e, _eventType, useCapture);
    var controller = new StreamController(sync: true);

    stream.listen((event) {
      var wrapped = new _BeforeUnloadEvent(event);
      controller.add(wrapped);
      return wrapped.returnValue;
    });

    return controller.stream;
  }

  String getEventType(EventTarget target) {
    return _eventType;
  }

  ElementStream<BeforeUnloadEvent> forElement(Element e, {bool useCapture: false}) {
    return new _ElementEventStreamImpl(e, _eventType, useCapture);
  }

  ElementStream<BeforeUnloadEvent> _forElementList(ElementList e,
      {bool useCapture: false}) {
    return new _ElementListEventStreamImpl(e, _eventType, useCapture);
  }
}
// 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.


@DocsEditable()
@DomName('WindowBase64')
@Experimental() // untriaged
abstract class WindowBase64 extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory WindowBase64._() { throw new UnsupportedError("Not supported"); }

  String atob(String string);

  String btoa(String string);
}
// 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.


@DocsEditable()
@DomName('WindowEventHandlers')
@Experimental() // untriaged
abstract class WindowEventHandlers extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory WindowEventHandlers._() { throw new UnsupportedError("Not supported"); }

  @DomName('WindowEventHandlers.hashchangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> hashChangeEvent = const EventStreamProvider<Event>('hashchange');

  @DomName('WindowEventHandlers.messageEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');

  @DomName('WindowEventHandlers.offlineEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> offlineEvent = const EventStreamProvider<Event>('offline');

  @DomName('WindowEventHandlers.onlineEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> onlineEvent = const EventStreamProvider<Event>('online');

  @DomName('WindowEventHandlers.popstateEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<PopStateEvent> popStateEvent = const EventStreamProvider<PopStateEvent>('popstate');

  @DomName('WindowEventHandlers.storageEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<StorageEvent> storageEvent = const EventStreamProvider<StorageEvent>('storage');

  @DomName('WindowEventHandlers.unloadEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> unloadEvent = const EventStreamProvider<Event>('unload');

  @DomName('WindowEventHandlers.onhashchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onHashChange => hashChangeEvent.forTarget(this);

  @DomName('WindowEventHandlers.onmessage')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  @DomName('WindowEventHandlers.onoffline')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onOffline => offlineEvent.forTarget(this);

  @DomName('WindowEventHandlers.ononline')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onOnline => onlineEvent.forTarget(this);

  @DomName('WindowEventHandlers.onpopstate')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<PopStateEvent> get onPopState => popStateEvent.forTarget(this);

  @DomName('WindowEventHandlers.onstorage')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<StorageEvent> get onStorage => storageEvent.forTarget(this);

  @DomName('WindowEventHandlers.onunload')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onUnload => unloadEvent.forTarget(this);
}
// 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.


@DocsEditable()
@DomName('Worker')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
// http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#worker
@Experimental() // stable
class Worker extends EventTarget implements AbstractWorker native "Worker" {
  // To suppress missing implicit constructor warnings.
  factory Worker._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [Worker].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Worker.errorEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [Worker].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Worker.messageEvent')
  @DocsEditable()
  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');

  @DomName('Worker.Worker')
  @DocsEditable()
  factory Worker(String scriptUrl) {
    return Worker._create_1(scriptUrl);
  }
  static Worker _create_1(scriptUrl) => JS('Worker', 'new Worker(#)', scriptUrl);

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '(typeof window.Worker != "undefined")');

  @DomName('Worker.postMessage')
  @DocsEditable()
  void postMessage(/*SerializedScriptValue*/ message, [List<MessagePort> messagePorts]) native;

  @DomName('Worker.terminate')
  @DocsEditable()
  void terminate() native;

  /// Stream of `error` events handled by this [Worker].
  @DomName('Worker.onerror')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `message` events handled by this [Worker].
  @DomName('Worker.onmessage')
  @DocsEditable()
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
}
// 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.


@DocsEditable()
@DomName('WorkerConsole')
@Experimental() // untriaged
class WorkerConsole extends ConsoleBase native "WorkerConsole" {
  // To suppress missing implicit constructor warnings.
  factory WorkerConsole._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('WorkerCrypto')
@Experimental() // untriaged
class WorkerCrypto extends Interceptor native "WorkerCrypto" {
  // To suppress missing implicit constructor warnings.
  factory WorkerCrypto._() { throw new UnsupportedError("Not supported"); }

  @DomName('WorkerCrypto.getRandomValues')
  @DocsEditable()
  @Experimental() // untriaged
  @Creates('TypedData')
  @Returns('TypedData|Null')
  TypedData getRandomValues(TypedData array) native;
}
// 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.


@DocsEditable()
@DomName('WorkerGlobalScope')
@Experimental() // untriaged
class WorkerGlobalScope extends EventTarget implements _WindowTimers, WindowBase64 native "WorkerGlobalScope" {
  // To suppress missing implicit constructor warnings.
  factory WorkerGlobalScope._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [WorkerGlobalScope].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('WorkerGlobalScope.errorEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  @DomName('WorkerGlobalScope.PERSISTENT')
  @DocsEditable()
  @Experimental() // untriaged
  static const int PERSISTENT = 1;

  @DomName('WorkerGlobalScope.TEMPORARY')
  @DocsEditable()
  @Experimental() // untriaged
  static const int TEMPORARY = 0;

  @DomName('WorkerGlobalScope.console')
  @DocsEditable()
  @Experimental() // untriaged
  final WorkerConsole console;

  @DomName('WorkerGlobalScope.crypto')
  @DocsEditable()
  @Experimental() // untriaged
  final WorkerCrypto crypto;

  @DomName('WorkerGlobalScope.indexedDB')
  @DocsEditable()
  @Experimental() // untriaged
  final IdbFactory indexedDB;

  @DomName('WorkerGlobalScope.location')
  @DocsEditable()
  @Experimental() // untriaged
  final _WorkerLocation location;

  @DomName('WorkerGlobalScope.navigator')
  @DocsEditable()
  @Experimental() // untriaged
  final _WorkerNavigator navigator;

  @DomName('WorkerGlobalScope.performance')
  @DocsEditable()
  @Experimental() // untriaged
  final WorkerPerformance performance;

  @DomName('WorkerGlobalScope.self')
  @DocsEditable()
  @Experimental() // untriaged
  final WorkerGlobalScope self;

  @JSName('webkitNotifications')
  @DomName('WorkerGlobalScope.webkitNotifications')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // untriaged
  final _NotificationCenter _webkitNotifications;

  @DomName('WorkerGlobalScope.close')
  @DocsEditable()
  @Experimental() // untriaged
  void close() native;

  @DomName('WorkerGlobalScope.openDatabase')
  @DocsEditable()
  @Experimental() // untriaged
  SqlDatabase openDatabase(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) native;

  @DomName('WorkerGlobalScope.openDatabaseSync')
  @DocsEditable()
  @Experimental() // untriaged
  _DatabaseSync openDatabaseSync(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) native;

  @JSName('webkitRequestFileSystem')
  @DomName('WorkerGlobalScope.webkitRequestFileSystem')
  @DocsEditable()
  @Experimental() // untriaged
  void _webkitRequestFileSystem(int type, int size, [_FileSystemCallback successCallback, _ErrorCallback errorCallback]) native;

  @JSName('webkitRequestFileSystem')
  @DomName('WorkerGlobalScope.webkitRequestFileSystem')
  @DocsEditable()
  @Experimental() // untriaged
  Future<FileSystem> webkitRequestFileSystem(int type, int size) {
    var completer = new Completer<FileSystem>();
    _webkitRequestFileSystem(type, size,
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  @JSName('webkitRequestFileSystemSync')
  @DomName('WorkerGlobalScope.webkitRequestFileSystemSync')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // untriaged
  _DOMFileSystemSync requestFileSystemSync(int type, int size) native;

  @JSName('webkitResolveLocalFileSystemSyncURL')
  @DomName('WorkerGlobalScope.webkitResolveLocalFileSystemSyncURL')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // untriaged
  _EntrySync resolveLocalFileSystemSyncUrl(String url) native;

  @JSName('webkitResolveLocalFileSystemURL')
  @DomName('WorkerGlobalScope.webkitResolveLocalFileSystemURL')
  @DocsEditable()
  @Experimental() // untriaged
  void _webkitResolveLocalFileSystemUrl(String url, _EntryCallback successCallback, [_ErrorCallback errorCallback]) native;

  @JSName('webkitResolveLocalFileSystemURL')
  @DomName('WorkerGlobalScope.webkitResolveLocalFileSystemURL')
  @DocsEditable()
  @Experimental() // untriaged
  Future<Entry> webkitResolveLocalFileSystemUrl(String url) {
    var completer = new Completer<Entry>();
    _webkitResolveLocalFileSystemUrl(url,
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  // From WindowBase64

  @DomName('WorkerGlobalScope.atob')
  @DocsEditable()
  @Experimental() // untriaged
  String atob(String string) native;

  @DomName('WorkerGlobalScope.btoa')
  @DocsEditable()
  @Experimental() // untriaged
  String btoa(String string) native;

  // From WindowTimers

  @JSName('clearInterval')
  @DomName('WorkerGlobalScope.clearInterval')
  @DocsEditable()
  @Experimental() // untriaged
  void _clearInterval(int handle) native;

  @JSName('clearTimeout')
  @DomName('WorkerGlobalScope.clearTimeout')
  @DocsEditable()
  @Experimental() // untriaged
  void _clearTimeout(int handle) native;

  @JSName('setInterval')
  @DomName('WorkerGlobalScope.setInterval')
  @DocsEditable()
  @Experimental() // untriaged
  int _setInterval(Object handler, int timeout) native;

  @JSName('setTimeout')
  @DomName('WorkerGlobalScope.setTimeout')
  @DocsEditable()
  @Experimental() // untriaged
  int _setTimeout(Object handler, int timeout) native;

  /// Stream of `error` events handled by this [WorkerGlobalScope].
  @DomName('WorkerGlobalScope.onerror')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onError => errorEvent.forTarget(this);
}
// 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.


@DocsEditable()
@DomName('WorkerPerformance')
@Experimental() // untriaged
class WorkerPerformance extends Interceptor native "WorkerPerformance" {
  // To suppress missing implicit constructor warnings.
  factory WorkerPerformance._() { throw new UnsupportedError("Not supported"); }

  @DomName('WorkerPerformance.now')
  @DocsEditable()
  @Experimental() // untriaged
  double now() native;
}
// 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.


@DocsEditable()
@DomName('XPathEvaluator')
// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathEvaluator
@deprecated // experimental
class XPathEvaluator extends Interceptor native "XPathEvaluator" {
  // To suppress missing implicit constructor warnings.
  factory XPathEvaluator._() { throw new UnsupportedError("Not supported"); }

  @DomName('XPathEvaluator.XPathEvaluator')
  @DocsEditable()
  factory XPathEvaluator() {
    return XPathEvaluator._create_1();
  }
  static XPathEvaluator _create_1() => JS('XPathEvaluator', 'new XPathEvaluator()');

  @DomName('XPathEvaluator.createExpression')
  @DocsEditable()
  XPathExpression createExpression(String expression, XPathNSResolver resolver) native;

  @DomName('XPathEvaluator.createNSResolver')
  @DocsEditable()
  XPathNSResolver createNSResolver(Node nodeResolver) native;

  @DomName('XPathEvaluator.evaluate')
  @DocsEditable()
  XPathResult evaluate(String expression, Node contextNode, XPathNSResolver resolver, int type, XPathResult inResult) native;
}
// 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.


@DocsEditable()
@DomName('XPathExpression')
// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathExpression
@deprecated // experimental
class XPathExpression extends Interceptor native "XPathExpression" {
  // To suppress missing implicit constructor warnings.
  factory XPathExpression._() { throw new UnsupportedError("Not supported"); }

  @DomName('XPathExpression.evaluate')
  @DocsEditable()
  XPathResult evaluate(Node contextNode, int type, XPathResult inResult) native;
}
// 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.


@DocsEditable()
@DomName('XPathNSResolver')
// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathNSResolver
@deprecated // experimental
class XPathNSResolver extends Interceptor native "XPathNSResolver" {
  // To suppress missing implicit constructor warnings.
  factory XPathNSResolver._() { throw new UnsupportedError("Not supported"); }

  @JSName('lookupNamespaceURI')
  @DomName('XPathNSResolver.lookupNamespaceURI')
  @DocsEditable()
  String lookupNamespaceUri(String prefix) native;
}
// 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.


@DocsEditable()
@DomName('XPathResult')
// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathResult
@deprecated // experimental
class XPathResult extends Interceptor native "XPathResult" {
  // To suppress missing implicit constructor warnings.
  factory XPathResult._() { throw new UnsupportedError("Not supported"); }

  @DomName('XPathResult.ANY_TYPE')
  @DocsEditable()
  static const int ANY_TYPE = 0;

  @DomName('XPathResult.ANY_UNORDERED_NODE_TYPE')
  @DocsEditable()
  static const int ANY_UNORDERED_NODE_TYPE = 8;

  @DomName('XPathResult.BOOLEAN_TYPE')
  @DocsEditable()
  static const int BOOLEAN_TYPE = 3;

  @DomName('XPathResult.FIRST_ORDERED_NODE_TYPE')
  @DocsEditable()
  static const int FIRST_ORDERED_NODE_TYPE = 9;

  @DomName('XPathResult.NUMBER_TYPE')
  @DocsEditable()
  static const int NUMBER_TYPE = 1;

  @DomName('XPathResult.ORDERED_NODE_ITERATOR_TYPE')
  @DocsEditable()
  static const int ORDERED_NODE_ITERATOR_TYPE = 5;

  @DomName('XPathResult.ORDERED_NODE_SNAPSHOT_TYPE')
  @DocsEditable()
  static const int ORDERED_NODE_SNAPSHOT_TYPE = 7;

  @DomName('XPathResult.STRING_TYPE')
  @DocsEditable()
  static const int STRING_TYPE = 2;

  @DomName('XPathResult.UNORDERED_NODE_ITERATOR_TYPE')
  @DocsEditable()
  static const int UNORDERED_NODE_ITERATOR_TYPE = 4;

  @DomName('XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE')
  @DocsEditable()
  static const int UNORDERED_NODE_SNAPSHOT_TYPE = 6;

  @DomName('XPathResult.booleanValue')
  @DocsEditable()
  final bool booleanValue;

  @DomName('XPathResult.invalidIteratorState')
  @DocsEditable()
  final bool invalidIteratorState;

  @DomName('XPathResult.numberValue')
  @DocsEditable()
  final double numberValue;

  @DomName('XPathResult.resultType')
  @DocsEditable()
  final int resultType;

  @DomName('XPathResult.singleNodeValue')
  @DocsEditable()
  final Node singleNodeValue;

  @DomName('XPathResult.snapshotLength')
  @DocsEditable()
  final int snapshotLength;

  @DomName('XPathResult.stringValue')
  @DocsEditable()
  final String stringValue;

  @DomName('XPathResult.iterateNext')
  @DocsEditable()
  Node iterateNext() native;

  @DomName('XPathResult.snapshotItem')
  @DocsEditable()
  Node snapshotItem(int index) native;
}
// 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.


@DocsEditable()
@DomName('XMLDocument')
@Experimental() // untriaged
class XmlDocument extends Document native "XMLDocument" {
  // To suppress missing implicit constructor warnings.
  factory XmlDocument._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('XMLSerializer')
// http://domparsing.spec.whatwg.org/#the-xmlserializer-interface
@deprecated // stable
class XmlSerializer extends Interceptor native "XMLSerializer" {
  // To suppress missing implicit constructor warnings.
  factory XmlSerializer._() { throw new UnsupportedError("Not supported"); }

  @DomName('XMLSerializer.XMLSerializer')
  @DocsEditable()
  factory XmlSerializer() {
    return XmlSerializer._create_1();
  }
  static XmlSerializer _create_1() => JS('XmlSerializer', 'new XMLSerializer()');

  @DomName('XMLSerializer.serializeToString')
  @DocsEditable()
  String serializeToString(Node node) native;
}
// 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.


@DocsEditable()
@DomName('XSLTProcessor')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@deprecated // nonstandard
class XsltProcessor extends Interceptor native "XSLTProcessor" {
  // To suppress missing implicit constructor warnings.
  factory XsltProcessor._() { throw new UnsupportedError("Not supported"); }

  @DomName('XSLTProcessor.XSLTProcessor')
  @DocsEditable()
  factory XsltProcessor() {
    return XsltProcessor._create_1();
  }
  static XsltProcessor _create_1() => JS('XsltProcessor', 'new XSLTProcessor()');

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.XSLTProcessor)');

  @DomName('XSLTProcessor.clearParameters')
  @DocsEditable()
  void clearParameters() native;

  @DomName('XSLTProcessor.getParameter')
  @DocsEditable()
  String getParameter(String namespaceURI, String localName) native;

  @DomName('XSLTProcessor.importStylesheet')
  @DocsEditable()
  void importStylesheet(Node stylesheet) native;

  @DomName('XSLTProcessor.removeParameter')
  @DocsEditable()
  void removeParameter(String namespaceURI, String localName) native;

  @DomName('XSLTProcessor.reset')
  @DocsEditable()
  void reset() native;

  @DomName('XSLTProcessor.setParameter')
  @DocsEditable()
  void setParameter(String namespaceURI, String localName, String value) native;

  @DomName('XSLTProcessor.transformToDocument')
  @DocsEditable()
  Document transformToDocument(Node source) native;

  @DomName('XSLTProcessor.transformToFragment')
  @DocsEditable()
  DocumentFragment transformToFragment(Node source, Document docVal) native;
}
// 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.


@DocsEditable()
@DomName('Attr')
class _Attr extends Node native "Attr" {
  // To suppress missing implicit constructor warnings.
  factory _Attr._() { throw new UnsupportedError("Not supported"); }

  // Use implementation from Node.
  // final String _localName;

  @DomName('Attr.name')
  @DocsEditable()
  final String name;

  // Use implementation from Node.
  // final String _namespaceUri;

  @DomName('Attr.value')
  @DocsEditable()
  String value;
}
// 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.


@DocsEditable()
@DomName('CSSPrimitiveValue')
// http://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface
@deprecated // deprecated
abstract class _CSSPrimitiveValue extends _CSSValue native "CSSPrimitiveValue" {
  // To suppress missing implicit constructor warnings.
  factory _CSSPrimitiveValue._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('CSSUnknownRule')
// http://dev.w3.org/csswg/cssom/#the-cssstylesheet-interface
@deprecated // deprecated
abstract class _CSSUnknownRule extends CssRule native "CSSUnknownRule" {
  // To suppress missing implicit constructor warnings.
  factory _CSSUnknownRule._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('CSSValue')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
abstract class _CSSValue extends Interceptor native "CSSValue" {
  // To suppress missing implicit constructor warnings.
  factory _CSSValue._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('ClientRect')
class _ClientRect extends Interceptor implements Rectangle native "ClientRect,DOMRect" {

  // NOTE! All code below should be common with RectangleBase.
   String toString() {
    return 'Rectangle ($left, $top) $width x $height';
  }

  bool operator ==(other) {
    if (other is !Rectangle) return false;
    return left == other.left && top == other.top && width == other.width &&
        height == other.height;
  }

  int get hashCode => _JenkinsSmiHash.hash4(left.hashCode, top.hashCode,
      width.hashCode, height.hashCode);

  /**
   * Computes the intersection of `this` and [other].
   *
   * The intersection of two axis-aligned rectangles, if any, is always another
   * axis-aligned rectangle.
   *
   * Returns the intersection of this and `other`, or null if they don't
   * intersect.
   */
  Rectangle intersection(Rectangle other) {
    var x0 = max(left, other.left);
    var x1 = min(left + width, other.left + other.width);

    if (x0 <= x1) {
      var y0 = max(top, other.top);
      var y1 = min(top + height, other.top + other.height);

      if (y0 <= y1) {
        return new Rectangle(x0, y0, x1 - x0, y1 - y0);
      }
    }
    return null;
  }


  /**
   * Returns true if `this` intersects [other].
   */
  bool intersects(Rectangle<num> other) {
    return (left <= other.left + other.width &&
        other.left <= left + width &&
        top <= other.top + other.height &&
        other.top <= top + height);
  }

  /**
   * Returns a new rectangle which completely contains `this` and [other].
   */
  Rectangle boundingBox(Rectangle other) {
    var right = max(this.left + this.width, other.left + other.width);
    var bottom = max(this.top + this.height, other.top + other.height);

    var left = min(this.left, other.left);
    var top = min(this.top, other.top);

    return new Rectangle(left, top, right - left, bottom - top);
  }

  /**
   * Tests whether `this` entirely contains [another].
   */
  bool containsRectangle(Rectangle<num> another) {
    return left <= another.left &&
           left + width >= another.left + another.width &&
           top <= another.top &&
           top + height >= another.top + another.height;
  }

  /**
   * Tests whether [another] is inside or along the edges of `this`.
   */
  bool containsPoint(Point<num> another) {
    return another.x >= left &&
           another.x <= left + width &&
           another.y >= top &&
           another.y <= top + height;
  }

  Point get topLeft => new Point(this.left, this.top);
  Point get topRight => new Point(this.left + this.width, this.top);
  Point get bottomRight => new Point(this.left + this.width,
      this.top + this.height);
  Point get bottomLeft => new Point(this.left,
      this.top + this.height);

    // To suppress missing implicit constructor warnings.
  factory _ClientRect._() { throw new UnsupportedError("Not supported"); }

  @DomName('ClientRect.bottom')
  @DocsEditable()
  final double bottom;

  @DomName('ClientRect.height')
  @DocsEditable()
  final double height;

  @DomName('ClientRect.left')
  @DocsEditable()
  final double left;

  @DomName('ClientRect.right')
  @DocsEditable()
  final double right;

  @DomName('ClientRect.top')
  @DocsEditable()
  final double top;

  @DomName('ClientRect.width')
  @DocsEditable()
  final double width;
}

/**
 * This is the [Jenkins hash function][1] but using masking to keep
 * values in SMI range.
 *
 * [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function
 *
 * Use:
 * Hash each value with the hash of the previous value, then get the final
 * hash by calling finish.
 *
 *     var hash = 0;
 *     for (var value in values) {
 *       hash = JenkinsSmiHash.combine(hash, value.hashCode);
 *     }
 *     hash = JenkinsSmiHash.finish(hash);
 */
class _JenkinsSmiHash {
  // TODO(11617): This class should be optimized and standardized elsewhere.

  static int combine(int hash, int value) {
    hash = 0x1fffffff & (hash + value);
    hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
    return hash ^ (hash >> 6);
  }

  static int finish(int hash) {
    hash = 0x1fffffff & (hash + ((0x03ffffff & hash) <<  3));
    hash = hash ^ (hash >> 11);
    return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
  }

  static int hash2(a, b) => finish(combine(combine(0, a), b));

  static int hash4(a, b, c, d) =>
      finish(combine(combine(combine(combine(0, a), b), c), d));
}
// 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.


@DocsEditable()
@DomName('ClientRectList')
class _ClientRectList extends Interceptor with ListMixin<Rectangle>, ImmutableListMixin<Rectangle> implements List<Rectangle>, JavaScriptIndexingBehavior native "ClientRectList" {
  // To suppress missing implicit constructor warnings.
  factory _ClientRectList._() { throw new UnsupportedError("Not supported"); }

  @DomName('ClientRectList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  Rectangle operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("Rectangle", "#[#]", this, index);
  }
  void operator[]=(int index, Rectangle value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Rectangle> mixins.
  // Rectangle is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Rectangle get first {
    if (this.length > 0) {
      return JS('Rectangle', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Rectangle get last {
    int len = this.length;
    if (len > 0) {
      return JS('Rectangle', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Rectangle get single {
    int len = this.length;
    if (len == 1) {
      return JS('Rectangle', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Rectangle elementAt(int index) => this[index];
  // -- end List<Rectangle> mixins.

  @DomName('ClientRectList.item')
  @DocsEditable()
  Rectangle item(int index) native;
}
// 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.


@DocsEditable()
@DomName('Counter')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
abstract class _Counter extends Interceptor native "Counter" {
  // To suppress missing implicit constructor warnings.
  factory _Counter._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('CSSRuleList')
class _CssRuleList extends Interceptor with ListMixin<CssRule>, ImmutableListMixin<CssRule> implements JavaScriptIndexingBehavior, List<CssRule> native "CSSRuleList" {
  // To suppress missing implicit constructor warnings.
  factory _CssRuleList._() { throw new UnsupportedError("Not supported"); }

  @DomName('CSSRuleList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  CssRule operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("CssRule", "#[#]", this, index);
  }
  void operator[]=(int index, CssRule value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<CssRule> mixins.
  // CssRule is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  CssRule get first {
    if (this.length > 0) {
      return JS('CssRule', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  CssRule get last {
    int len = this.length;
    if (len > 0) {
      return JS('CssRule', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  CssRule get single {
    int len = this.length;
    if (len == 1) {
      return JS('CssRule', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  CssRule elementAt(int index) => this[index];
  // -- end List<CssRule> mixins.

  @DomName('CSSRuleList.item')
  @DocsEditable()
  CssRule item(int index) native;
}
// 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.


@DocsEditable()
@DomName('CSSValueList')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
class _CssValueList extends _CSSValue with ListMixin<_CSSValue>, ImmutableListMixin<_CSSValue> implements JavaScriptIndexingBehavior, List<_CSSValue> native "CSSValueList" {
  // To suppress missing implicit constructor warnings.
  factory _CssValueList._() { throw new UnsupportedError("Not supported"); }

  @DomName('CSSValueList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  _CSSValue operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("_CSSValue", "#[#]", this, index);
  }
  void operator[]=(int index, _CSSValue value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<_CSSValue> mixins.
  // _CSSValue is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  _CSSValue get first {
    if (this.length > 0) {
      return JS('_CSSValue', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  _CSSValue get last {
    int len = this.length;
    if (len > 0) {
      return JS('_CSSValue', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  _CSSValue get single {
    int len = this.length;
    if (len == 1) {
      return JS('_CSSValue', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  _CSSValue elementAt(int index) => this[index];
  // -- end List<_CSSValue> mixins.

  @DomName('CSSValueList.item')
  @DocsEditable()
  _CSSValue item(int index) native;
}
// 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.


@DocsEditable()
@DomName('DOMFileSystemSync')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://www.w3.org/TR/file-system-api/#the-filesystemsync-interface
abstract class _DOMFileSystemSync extends Interceptor native "DOMFileSystemSync" {
  // To suppress missing implicit constructor warnings.
  factory _DOMFileSystemSync._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('DatabaseSync')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
// http://www.w3.org/TR/webdatabase/#databasesync
@deprecated // deprecated
abstract class _DatabaseSync extends Interceptor native "DatabaseSync" {
  // To suppress missing implicit constructor warnings.
  factory _DatabaseSync._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('DirectoryEntrySync')
// http://www.w3.org/TR/file-system-api/#the-directoryentrysync-interface
@Experimental()
abstract class _DirectoryEntrySync extends _EntrySync native "DirectoryEntrySync" {
  // To suppress missing implicit constructor warnings.
  factory _DirectoryEntrySync._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('DirectoryReaderSync')
// http://www.w3.org/TR/file-system-api/#idl-def-DirectoryReaderSync
@Experimental()
abstract class _DirectoryReaderSync extends Interceptor native "DirectoryReaderSync" {
  // To suppress missing implicit constructor warnings.
  factory _DirectoryReaderSync._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('DocumentType')
// http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-412266927
@deprecated // stable
abstract class _DocumentType extends Node implements ChildNode native "DocumentType" {
  // To suppress missing implicit constructor warnings.
  factory _DocumentType._() { throw new UnsupportedError("Not supported"); }

  // From ChildNode
}
// 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.


@DocsEditable()
@DomName('WebKitPoint')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
// http://developer.apple.com/library/safari/#documentation/DataManagement/Reference/DOMWindowAdditionsReference/DOMWindowAdditions/DOMWindowAdditions.html
@Experimental() // non-standard
class _DomPoint extends Interceptor native "WebKitPoint" {
  // To suppress missing implicit constructor warnings.
  factory _DomPoint._() { throw new UnsupportedError("Not supported"); }

  @DomName('WebKitPoint.WebKitPoint')
  @DocsEditable()
  factory _DomPoint(num x, num y) {
    return _DomPoint._create_1(x, y);
  }
  static _DomPoint _create_1(x, y) => JS('_DomPoint', 'new WebKitPoint(#,#)', x, y);

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.WebKitPoint)');

  @DomName('WebKitPoint.x')
  @DocsEditable()
  num x;

  @DomName('WebKitPoint.y')
  @DocsEditable()
  num y;
}
// 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.


@DocsEditable()
@DomName('EntrySync')
// http://www.w3.org/TR/file-system-api/#idl-def-EntrySync
@Experimental()
abstract class _EntrySync extends Interceptor native "EntrySync" {
  // To suppress missing implicit constructor warnings.
  factory _EntrySync._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('FileEntrySync')
// http://www.w3.org/TR/file-system-api/#the-fileentrysync-interface
@Experimental()
abstract class _FileEntrySync extends _EntrySync native "FileEntrySync" {
  // To suppress missing implicit constructor warnings.
  factory _FileEntrySync._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('FileReaderSync')
// http://www.w3.org/TR/FileAPI/#FileReaderSync
@Experimental()
abstract class _FileReaderSync extends Interceptor native "FileReaderSync" {
  // To suppress missing implicit constructor warnings.
  factory _FileReaderSync._() { throw new UnsupportedError("Not supported"); }

  @DomName('FileReaderSync.FileReaderSync')
  @DocsEditable()
  factory _FileReaderSync() {
    return _FileReaderSync._create_1();
  }
  static _FileReaderSync _create_1() => JS('_FileReaderSync', 'new FileReaderSync()');
}
// 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.


@DocsEditable()
@DomName('FileWriterSync')
// http://www.w3.org/TR/file-writer-api/#idl-def-FileWriterSync
@Experimental()
abstract class _FileWriterSync extends Interceptor native "FileWriterSync" {
  // To suppress missing implicit constructor warnings.
  factory _FileWriterSync._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('GamepadList')
// https://dvcs.w3.org/hg/gamepad/raw-file/default/gamepad.html
@Experimental()
class _GamepadList extends Interceptor with ListMixin<Gamepad>, ImmutableListMixin<Gamepad> implements JavaScriptIndexingBehavior, List<Gamepad> native "GamepadList" {
  // To suppress missing implicit constructor warnings.
  factory _GamepadList._() { throw new UnsupportedError("Not supported"); }

  @DomName('GamepadList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  Gamepad operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("Gamepad", "#[#]", this, index);
  }
  void operator[]=(int index, Gamepad value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Gamepad> mixins.
  // Gamepad is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Gamepad get first {
    if (this.length > 0) {
      return JS('Gamepad', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Gamepad get last {
    int len = this.length;
    if (len > 0) {
      return JS('Gamepad', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Gamepad get single {
    int len = this.length;
    if (len == 1) {
      return JS('Gamepad', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Gamepad elementAt(int index) => this[index];
  // -- end List<Gamepad> mixins.

  @DomName('GamepadList.item')
  @DocsEditable()
  Gamepad item(int index) native;
}
// 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.


@DocsEditable()
@DomName('HTMLAllCollection')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#dom-document-all
@deprecated // deprecated
abstract class _HTMLAllCollection extends Interceptor native "HTMLAllCollection" {
  // To suppress missing implicit constructor warnings.
  factory _HTMLAllCollection._() { throw new UnsupportedError("Not supported"); }

  @JSName('item')
  @DomName('HTMLAllCollection.item')
  @DocsEditable()
  Element _item(int index) native;
}
// 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.


@DocsEditable()
@DomName('HTMLAppletElement')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#the-applet-element
@deprecated // deprecated
abstract class _HTMLAppletElement extends HtmlElement native "HTMLAppletElement" {
  // To suppress missing implicit constructor warnings.
  factory _HTMLAppletElement._() { throw new UnsupportedError("Not supported"); }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLAppletElement.created() : super.created();
}
// 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.


@DocsEditable()
@DomName('HTMLDirectoryElement')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#dir
@deprecated // deprecated
abstract class _HTMLDirectoryElement extends HtmlElement native "HTMLDirectoryElement" {
  // To suppress missing implicit constructor warnings.
  factory _HTMLDirectoryElement._() { throw new UnsupportedError("Not supported"); }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLDirectoryElement.created() : super.created();
}
// 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.


@DocsEditable()
@DomName('HTMLFontElement')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#htmlfontelement
@deprecated // deprecated
abstract class _HTMLFontElement extends HtmlElement native "HTMLFontElement" {
  // To suppress missing implicit constructor warnings.
  factory _HTMLFontElement._() { throw new UnsupportedError("Not supported"); }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLFontElement.created() : super.created();
}
// 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.


@DocsEditable()
@DomName('HTMLFrameElement')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#htmlframeelement
@deprecated // deprecated
abstract class _HTMLFrameElement extends HtmlElement native "HTMLFrameElement" {
  // To suppress missing implicit constructor warnings.
  factory _HTMLFrameElement._() { throw new UnsupportedError("Not supported"); }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLFrameElement.created() : super.created();
}
// 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.


@DocsEditable()
@DomName('HTMLFrameSetElement')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#frameset
@deprecated // deprecated
abstract class _HTMLFrameSetElement extends HtmlElement implements WindowEventHandlers native "HTMLFrameSetElement" {
  // To suppress missing implicit constructor warnings.
  factory _HTMLFrameSetElement._() { throw new UnsupportedError("Not supported"); }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLFrameSetElement.created() : super.created();
}
// 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.


@DocsEditable()
@DomName('HTMLMarqueeElement')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#the-marquee-element
@deprecated // deprecated
abstract class _HTMLMarqueeElement extends HtmlElement native "HTMLMarqueeElement" {
  // To suppress missing implicit constructor warnings.
  factory _HTMLMarqueeElement._() { throw new UnsupportedError("Not supported"); }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLMarqueeElement.created() : super.created();
}
// 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.


@DomName('MutationEvent')
// http://www.w3.org/TR/DOM-Level-3-Events/#events-mutationevents
@deprecated
abstract class _MutationEvent extends Event native "MutationEvent" {
  factory _MutationEvent(String type,
      {bool canBubble: false, bool cancelable: false, Node relatedNode,
      String prevValue, String newValue, String attrName, int attrChange: 0}) {

    var event = document._createEvent('MutationEvent');
    event._initMutationEvent(type, canBubble, cancelable, relatedNode,
        prevValue, newValue, attrName, attrChange);
    return event;
  }
  // To suppress missing implicit constructor warnings.
  factory _MutationEvent._() { throw new UnsupportedError("Not supported"); }

}



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


@DocsEditable()
@DomName('NamedNodeMap')
// http://dom.spec.whatwg.org/#namednodemap
@deprecated // deprecated
class _NamedNodeMap extends Interceptor with ListMixin<Node>, ImmutableListMixin<Node> implements JavaScriptIndexingBehavior, List<Node> native "NamedNodeMap,MozNamedAttrMap" {
  // To suppress missing implicit constructor warnings.
  factory _NamedNodeMap._() { throw new UnsupportedError("Not supported"); }

  @DomName('NamedNodeMap.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  Node operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("Node", "#[#]", this, index);
  }
  void operator[]=(int index, Node value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Node> mixins.
  // Node is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Node get first {
    if (this.length > 0) {
      return JS('Node', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Node get last {
    int len = this.length;
    if (len > 0) {
      return JS('Node', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Node get single {
    int len = this.length;
    if (len == 1) {
      return JS('Node', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Node elementAt(int index) => this[index];
  // -- end List<Node> mixins.

  @DomName('NamedNodeMap.__getter__')
  @DocsEditable()
  Node __getter__(String name) native;

  @DomName('NamedNodeMap.getNamedItem')
  @DocsEditable()
  Node getNamedItem(String name) native;

  @DomName('NamedNodeMap.getNamedItemNS')
  @DocsEditable()
  Node getNamedItemNS(String namespaceURI, String localName) native;

  @DomName('NamedNodeMap.item')
  @DocsEditable()
  Node item(int index) native;

  @DomName('NamedNodeMap.removeNamedItem')
  @DocsEditable()
  Node removeNamedItem(String name) native;

  @DomName('NamedNodeMap.removeNamedItemNS')
  @DocsEditable()
  Node removeNamedItemNS(String namespaceURI, String localName) native;

  @DomName('NamedNodeMap.setNamedItem')
  @DocsEditable()
  Node setNamedItem(Node node) native;

  @DomName('NamedNodeMap.setNamedItemNS')
  @DocsEditable()
  Node setNamedItemNS(Node node) native;
}
// 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.


@DocsEditable()
@DomName('Notation')
// http://dom.spec.whatwg.org/#notation
@deprecated // deprecated
abstract class _Notation extends Node native "Notation" {
  // To suppress missing implicit constructor warnings.
  factory _Notation._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('NotificationCenter')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
// http://www.w3.org/TR/notifications/#showing-a-notification
@deprecated // deprecated
abstract class _NotificationCenter extends Interceptor native "NotificationCenter" {
  // To suppress missing implicit constructor warnings.
  factory _NotificationCenter._() { throw new UnsupportedError("Not supported"); }

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.webkitNotifications)');
}
// 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.


@DocsEditable()
@DomName('PagePopupController')
@deprecated // nonstandard
abstract class _PagePopupController extends Interceptor native "PagePopupController" {
  // To suppress missing implicit constructor warnings.
  factory _PagePopupController._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('RGBColor')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
abstract class _RGBColor extends Interceptor native "RGBColor" {
  // To suppress missing implicit constructor warnings.
  factory _RGBColor._() { throw new UnsupportedError("Not supported"); }
}
// 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.


// Omit RadioNodeList for dart2js.  The Dart Form and FieldSet APIs don't
// currently expose an API the returns RadioNodeList.  The only use of a
// RadioNodeList is to get the selected value and it will be cleaner to
// introduce a different API for that purpose.
// 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.


@DocsEditable()
@DomName('Rect')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
abstract class _Rect extends Interceptor native "Rect" {
  // To suppress missing implicit constructor warnings.
  factory _Rect._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('ServiceWorker')
@Experimental() // untriaged
abstract class _ServiceWorker extends Interceptor native "ServiceWorker" {
  // To suppress missing implicit constructor warnings.
  factory _ServiceWorker._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('SpeechInputResultList')
// http://lists.w3.org/Archives/Public/public-xg-htmlspeech/2011Feb/att-0020/api-draft.html#speech_input_result_list_interface
@Experimental()
class _SpeechInputResultList extends Interceptor with ListMixin<SpeechInputResult>, ImmutableListMixin<SpeechInputResult> implements JavaScriptIndexingBehavior, List<SpeechInputResult> native "SpeechInputResultList" {
  // To suppress missing implicit constructor warnings.
  factory _SpeechInputResultList._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechInputResultList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  SpeechInputResult operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("SpeechInputResult", "#[#]", this, index);
  }
  void operator[]=(int index, SpeechInputResult value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<SpeechInputResult> mixins.
  // SpeechInputResult is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  SpeechInputResult get first {
    if (this.length > 0) {
      return JS('SpeechInputResult', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  SpeechInputResult get last {
    int len = this.length;
    if (len > 0) {
      return JS('SpeechInputResult', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  SpeechInputResult get single {
    int len = this.length;
    if (len == 1) {
      return JS('SpeechInputResult', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  SpeechInputResult elementAt(int index) => this[index];
  // -- end List<SpeechInputResult> mixins.

  @DomName('SpeechInputResultList.item')
  @DocsEditable()
  SpeechInputResult item(int index) native;
}
// 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.


@DocsEditable()
@DomName('SpeechRecognitionResultList')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechrecognitionresultlist
@Experimental()
class _SpeechRecognitionResultList extends Interceptor with ListMixin<SpeechRecognitionResult>, ImmutableListMixin<SpeechRecognitionResult> implements JavaScriptIndexingBehavior, List<SpeechRecognitionResult> native "SpeechRecognitionResultList" {
  // To suppress missing implicit constructor warnings.
  factory _SpeechRecognitionResultList._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechRecognitionResultList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  SpeechRecognitionResult operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("SpeechRecognitionResult", "#[#]", this, index);
  }
  void operator[]=(int index, SpeechRecognitionResult value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<SpeechRecognitionResult> mixins.
  // SpeechRecognitionResult is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  SpeechRecognitionResult get first {
    if (this.length > 0) {
      return JS('SpeechRecognitionResult', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  SpeechRecognitionResult get last {
    int len = this.length;
    if (len > 0) {
      return JS('SpeechRecognitionResult', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  SpeechRecognitionResult get single {
    int len = this.length;
    if (len == 1) {
      return JS('SpeechRecognitionResult', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  SpeechRecognitionResult elementAt(int index) => this[index];
  // -- end List<SpeechRecognitionResult> mixins.

  @DomName('SpeechRecognitionResultList.item')
  @DocsEditable()
  SpeechRecognitionResult item(int index) native;
}
// 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.


@DocsEditable()
@DomName('StyleSheetList')
class _StyleSheetList extends Interceptor with ListMixin<StyleSheet>, ImmutableListMixin<StyleSheet> implements JavaScriptIndexingBehavior, List<StyleSheet> native "StyleSheetList" {
  // To suppress missing implicit constructor warnings.
  factory _StyleSheetList._() { throw new UnsupportedError("Not supported"); }

  @DomName('StyleSheetList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  StyleSheet operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("StyleSheet", "#[#]", this, index);
  }
  void operator[]=(int index, StyleSheet value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<StyleSheet> mixins.
  // StyleSheet is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  StyleSheet get first {
    if (this.length > 0) {
      return JS('StyleSheet', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  StyleSheet get last {
    int len = this.length;
    if (len > 0) {
      return JS('StyleSheet', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  StyleSheet get single {
    int len = this.length;
    if (len == 1) {
      return JS('StyleSheet', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  StyleSheet elementAt(int index) => this[index];
  // -- end List<StyleSheet> mixins.

  @DomName('StyleSheetList.__getter__')
  @DocsEditable()
  CssStyleSheet __getter__(String name) native;

  @DomName('StyleSheetList.item')
  @DocsEditable()
  StyleSheet item(int index) native;
}
// 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.


@DocsEditable()
@DomName('SubtleCrypto')
@Experimental() // untriaged
abstract class _SubtleCrypto extends Interceptor native "SubtleCrypto" {
  // To suppress missing implicit constructor warnings.
  factory _SubtleCrypto._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('WebKitCSSFilterValue')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
abstract class _WebKitCSSFilterValue extends _CssValueList native "WebKitCSSFilterValue" {
  // To suppress missing implicit constructor warnings.
  factory _WebKitCSSFilterValue._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('WebKitCSSMatrix')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
abstract class _WebKitCSSMatrix extends Interceptor native "WebKitCSSMatrix" {
  // To suppress missing implicit constructor warnings.
  factory _WebKitCSSMatrix._() { throw new UnsupportedError("Not supported"); }

  @DomName('WebKitCSSMatrix.WebKitCSSMatrix')
  @DocsEditable()
  factory _WebKitCSSMatrix([String cssValue]) {
    if (cssValue != null) {
      return _WebKitCSSMatrix._create_1(cssValue);
    }
    return _WebKitCSSMatrix._create_2();
  }
  static _WebKitCSSMatrix _create_1(cssValue) => JS('_WebKitCSSMatrix', 'new WebKitCSSMatrix(#)', cssValue);
  static _WebKitCSSMatrix _create_2() => JS('_WebKitCSSMatrix', 'new WebKitCSSMatrix()');
}
// 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.


@DocsEditable()
@DomName('WebKitCSSTransformValue')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
abstract class _WebKitCSSTransformValue extends _CssValueList native "WebKitCSSTransformValue" {
  // To suppress missing implicit constructor warnings.
  factory _WebKitCSSTransformValue._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('WebKitMediaSource')
@Experimental() // untriaged
abstract class _WebKitMediaSource extends EventTarget native "WebKitMediaSource" {
  // To suppress missing implicit constructor warnings.
  factory _WebKitMediaSource._() { throw new UnsupportedError("Not supported"); }

  @DomName('WebKitMediaSource.WebKitMediaSource')
  @DocsEditable()
  factory _WebKitMediaSource() {
    return _WebKitMediaSource._create_1();
  }
  static _WebKitMediaSource _create_1() => JS('_WebKitMediaSource', 'new WebKitMediaSource()');
}
// 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.


@DocsEditable()
@DomName('WebKitNotification')
@Experimental() // untriaged
abstract class _WebKitNotification extends EventTarget native "WebKitNotification" {
  // To suppress missing implicit constructor warnings.
  factory _WebKitNotification._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('WebKitSourceBuffer')
@Experimental() // untriaged
abstract class _WebKitSourceBuffer extends Interceptor native "WebKitSourceBuffer" {
  // To suppress missing implicit constructor warnings.
  factory _WebKitSourceBuffer._() { throw new UnsupportedError("Not supported"); }
}
// 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.


@DocsEditable()
@DomName('WebKitSourceBufferList')
@Experimental() // untriaged
abstract class _WebKitSourceBufferList extends EventTarget native "WebKitSourceBufferList" {
  // To suppress missing implicit constructor warnings.
  factory _WebKitSourceBufferList._() { throw new UnsupportedError("Not supported"); }

  @JSName('item')
  @DomName('WebKitSourceBufferList.item')
  @DocsEditable()
  @Experimental() // untriaged
  _WebKitSourceBuffer _item(int index) native;
}
// 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.


@DocsEditable()
@DomName('WindowTimers')
@Experimental() // untriaged
abstract class _WindowTimers extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _WindowTimers._() { throw new UnsupportedError("Not supported"); }

  void _clearInterval(int handle);

  void _clearTimeout(int handle);

  int _setInterval(Object handler, int timeout);

  int _setTimeout(Object handler, int timeout);
}
// 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.


@DocsEditable()
@DomName('WorkerLocation')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#workerlocation
@Experimental()
abstract class _WorkerLocation extends Interceptor implements UrlUtilsReadOnly native "WorkerLocation" {
  // To suppress missing implicit constructor warnings.
  factory _WorkerLocation._() { throw new UnsupportedError("Not supported"); }

  // From URLUtilsReadOnly
}
// 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.


@DocsEditable()
@DomName('WorkerNavigator')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#workernavigator
@Experimental()
abstract class _WorkerNavigator extends Interceptor implements NavigatorOnLine, NavigatorID native "WorkerNavigator" {
  // To suppress missing implicit constructor warnings.
  factory _WorkerNavigator._() { throw new UnsupportedError("Not supported"); }

  // From NavigatorID

  // From NavigatorOnLine
}
// 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.


@DocsEditable()
@DomName('XMLHttpRequestProgressEvent')
@Experimental() // nonstandard
abstract class _XMLHttpRequestProgressEvent extends ProgressEvent native "XMLHttpRequestProgressEvent" {
  // To suppress missing implicit constructor warnings.
  factory _XMLHttpRequestProgressEvent._() { throw new UnsupportedError("Not supported"); }
}
// 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.


abstract class _AttributeMap implements Map<String, String> {
  final Element _element;

  _AttributeMap(this._element);

  void addAll(Map<String, String> other) {
    other.forEach((k, v) { this[k] = v; });
  }

  bool containsValue(String value) {
    for (var v in this.values) {
      if (value == v) {
        return true;
      }
    }
    return false;
  }

  String putIfAbsent(String key, String ifAbsent()) {
    if (!containsKey(key)) {
      this[key] = ifAbsent();
    }
    return this[key];
  }

  void clear() {
    for (var key in keys) {
      remove(key);
    }
  }

  void forEach(void f(String key, String value)) {
    for (var key in keys) {
      var value = this[key];
      f(key, value);
    }
  }

  Iterable<String> get keys {
    // TODO: generate a lazy collection instead.
    var attributes = _element._attributes;
    var keys = new List<String>();
    for (int i = 0, len = attributes.length; i < len; i++) {
      if (_matches(attributes[i])) {
        keys.add(attributes[i].name);
      }
    }
    return keys;
  }

  Iterable<String> get values {
    // TODO: generate a lazy collection instead.
    var attributes = _element._attributes;
    var values = new List<String>();
    for (int i = 0, len = attributes.length; i < len; i++) {
      if (_matches(attributes[i])) {
        values.add(attributes[i].value);
      }
    }
    return values;
  }

  /**
   * Returns true if there is no {key, value} pair in the map.
   */
  bool get isEmpty {
    return length == 0;
  }

  /**
   * Returns true if there is at least one {key, value} pair in the map.
   */
  bool get isNotEmpty => !isEmpty;

  /**
   * Checks to see if the node should be included in this map.
   */
  bool _matches(Node node);
}

/**
 * Wrapper to expose [Element.attributes] as a typed map.
 */
class _ElementAttributeMap extends _AttributeMap {

  _ElementAttributeMap(Element element): super(element);

  bool containsKey(String key) {
    return _element._hasAttribute(key);
  }

  String operator [](String key) {
    return _element.getAttribute(key);
  }

  void operator []=(String key, String value) {
    _element.setAttribute(key, value);
  }

  String remove(String key) {
    String value = _element.getAttribute(key);
    _element._removeAttribute(key);
    return value;
  }

  /**
   * The number of {key, value} pairs in the map.
   */
  int get length {
    return keys.length;
  }

  bool _matches(Node node) => node._namespaceUri == null;
}

/**
 * Wrapper to expose namespaced attributes as a typed map.
 */
class _NamespacedAttributeMap extends _AttributeMap {

  final String _namespace;

  _NamespacedAttributeMap(Element element, this._namespace): super(element);

  bool containsKey(String key) {
    return _element._hasAttributeNS(_namespace, key);
  }

  String operator [](String key) {
    return _element.getAttributeNS(_namespace, key);
  }

  void operator []=(String key, String value) {
    _element.setAttributeNS(_namespace, key, value);
  }

  String remove(String key) {
    String value = this[key];
    _element._removeAttributeNS(_namespace, key);
    return value;
  }

  /**
   * The number of {key, value} pairs in the map.
   */
  int get length {
    return keys.length;
  }

  bool _matches(Node node) => node._namespaceUri == _namespace;
}


/**
 * Provides a Map abstraction on top of data-* attributes, similar to the
 * dataSet in the old DOM.
 */
class _DataAttributeMap implements Map<String, String> {

  final Map<String, String> _attributes;

  _DataAttributeMap(this._attributes);

  // interface Map

  void addAll(Map<String, String> other) {
    other.forEach((k, v) { this[k] = v; });
  }

  // TODO: Use lazy iterator when it is available on Map.
  bool containsValue(String value) => values.any((v) => v == value);

  bool containsKey(String key) => _attributes.containsKey(_attr(key));

  String operator [](String key) => _attributes[_attr(key)];

  void operator []=(String key, String value) {
    _attributes[_attr(key)] = value;
  }

  String putIfAbsent(String key, String ifAbsent()) =>
    _attributes.putIfAbsent(_attr(key), ifAbsent);

  String remove(String key) => _attributes.remove(_attr(key));

  void clear() {
    // Needs to operate on a snapshot since we are mutating the collection.
    for (String key in keys) {
      remove(key);
    }
  }

  void forEach(void f(String key, String value)) {
    _attributes.forEach((String key, String value) {
      if (_matches(key)) {
        f(_strip(key), value);
      }
    });
  }

  Iterable<String> get keys {
    final keys = new List<String>();
    _attributes.forEach((String key, String value) {
      if (_matches(key)) {
        keys.add(_strip(key));
      }
    });
    return keys;
  }

  Iterable<String> get values {
    final values = new List<String>();
    _attributes.forEach((String key, String value) {
      if (_matches(key)) {
        values.add(value);
      }
    });
    return values;
  }

  int get length => keys.length;

  // TODO: Use lazy iterator when it is available on Map.
  bool get isEmpty => length == 0;

  bool get isNotEmpty => !isEmpty;

  // Helpers.
  String _attr(String key) => 'data-${_toHyphenedName(key)}';
  bool _matches(String key) => key.startsWith('data-');
  String _strip(String key) => _toCamelCase(key.substring(5));

  /**
   * Converts a string name with hyphens into an identifier, by removing hyphens
   * and capitalizing the following letter. Optionally [startUppercase] to
   * captialize the first letter.
   */
  String _toCamelCase(String hyphenedName, {bool startUppercase: false}) {
    var segments = hyphenedName.split('-');
    int start = startUppercase ? 0 : 1;
    for (int i = start; i < segments.length; i++) {
      var segment = segments[i];
      if (segment.length > 0) {
        // Character between 'a'..'z' mapped to 'A'..'Z'
        segments[i] = '${segment[0].toUpperCase()}${segment.substring(1)}';
      }
    }
    return segments.join('');
  }

  /** Reverse of [toCamelCase]. */
  String _toHyphenedName(String word) {
    var sb = new StringBuffer();
    for (int i = 0; i < word.length; i++) {
      var lower = word[i].toLowerCase();
      if (word[i] != lower && i > 0) sb.write('-');
      sb.write(lower);
    }
    return sb.toString();
  }
}
// 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.


/**
 * An object that can be drawn to a 2D canvas rendering context.
 *
 * The image drawn to the canvas depends on the type of this object:
 *
 * * If this object is an [ImageElement], then this element's image is
 * drawn to the canvas. If this element is an animated image, then this
 * element's poster frame is drawn. If this element has no poster frame, then
 * the first frame of animation is drawn.
 *
 * * If this object is a [VideoElement], then the frame at this element's current
 * playback position is drawn to the canvas.
 *
 * * If this object is a [CanvasElement], then this element's bitmap is drawn to
 * the canvas.
 *
 * **Note:** Currently all versions of Internet Explorer do not support
 * drawing a video element to a canvas. You may also encounter problems drawing
 * a video to a canvas in Firefox if the source of the video is a data URL.
 *
 * ## See also
 *
 * * [CanvasRenderingContext2D.drawImage]
 * * [CanvasRenderingContext2D.drawImageToRect]
 * * [CanvasRenderingContext2D.drawImageScaled]
 * * [CanvasRenderingContext2D.drawImageScaledFromSource]
 *
 * ## Other resources
 *
 * * [Image sources for 2D rendering contexts]
 * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#image-sources-for-2d-rendering-contexts)
 * from WHATWG.
 * * [Drawing images]
 * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
 * from WHATWG.
 */
abstract class CanvasImageSource {}
// 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.


/**
 * Top-level container for a browser tab or window.
 *
 * In a web browser, a [WindowBase] object represents any browser window. This
 * object contains the window's state and its relation to other
 * windows, such as which window opened this window.
 *
 * **Note:** This class represents any window, while [Window] is
 * used to access the properties and content of the current window or tab.
 *
 * ## See also
 *
 * * [Window]
 *
 * ## Other resources
 *
 * * [DOM Window](https://developer.mozilla.org/en-US/docs/DOM/window) from MDN.
 * * [Window](http://www.w3.org/TR/Window/) from the W3C.
 */
abstract class WindowBase implements EventTarget {
  // Fields.

  /**
   * The current location of this window.
   *
   *     Location currentLocation = window.location;
   *     print(currentLocation.href); // 'http://www.example.com:80/'
   */
  LocationBase get location;

  /**
   * The current session history for this window.
   *
   * ## Other resources
   *
   * * [Session history and navigation specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html)
   * from WHATWG.
   */
  HistoryBase get history;

  /**
   * Indicates whether this window has been closed.
   *
   *     print(window.closed); // 'false'
   *     window.close();
   *     print(window.closed); // 'true'
   */
  bool get closed;

  /**
   * A reference to the window that opened this one.
   *
   *     Window thisWindow = window;
   *     WindowBase otherWindow = thisWindow.open('http://www.example.com/', 'foo');
   *     print(otherWindow.opener == thisWindow); // 'true'
   */
  WindowBase get opener;

  /**
   * A reference to the parent of this window.
   *
   * If this [WindowBase] has no parent, [parent] will return a reference to
   * the [WindowBase] itself.
   *
   *     IFrameElement myIFrame = new IFrameElement();
   *     window.document.body.elements.add(myIFrame);
   *     print(myIframe.contentWindow.parent == window) // 'true'
   *
   *     print(window.parent == window) // 'true'
   */
  WindowBase get parent;

  /**
   * A reference to the topmost window in the window hierarchy.
   *
   * If this [WindowBase] is the topmost [WindowBase], [top] will return a
   * reference to the [WindowBase] itself.
   *
   *     // Add an IFrame to the current window.
   *     IFrameElement myIFrame = new IFrameElement();
   *     window.document.body.elements.add(myIFrame);
   *
   *     // Add an IFrame inside of the other IFrame.
   *     IFrameElement innerIFrame = new IFrameElement();
   *     myIFrame.elements.add(innerIFrame);
   *
   *     print(myIframe.contentWindow.top == window) // 'true'
   *     print(innerIFrame.contentWindow.top == window) // 'true'
   *
   *     print(window.top == window) // 'true'
   */
  WindowBase get top;

  // Methods.
  /**
   * Closes the window.
   *
   * This method should only succeed if the [WindowBase] object is
   * **script-closeable** and the window calling [close] is allowed to navigate
   * the window.
   *
   * A window is script-closeable if it is either a window
   * that was opened by another window, or if it is a window with only one
   * document in its history.
   *
   * A window might not be allowed to navigate, and therefore close, another
   * window due to browser security features.
   *
   *     var other = window.open('http://www.example.com', 'foo');
   *     // Closes other window, as it is script-closeable.
   *     other.close();
   *     print(other.closed()); // 'true'
   *
   *     window.location('http://www.mysite.com', 'foo');
   *     // Does not close this window, as the history has changed.
   *     window.close();
   *     print(window.closed()); // 'false'
   *
   * See also:
   *
   * * [Window close discussion](http://www.w3.org/TR/html5/browsers.html#dom-window-close) from the W3C
   */
  void close();

  /**
   * Sends a cross-origin message.
   *
   * ## Other resources
   *
   * * [window.postMessage]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage) from
   * MDN.
   * * [Cross-document messaging]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/web-messaging.html)
   * from WHATWG.
   */
  void postMessage(var message, String targetOrigin, [List messagePorts]);
}

abstract class LocationBase {
  void set href(String val);
}

abstract class HistoryBase {
  void back();
  void forward();
  void go(int distance);
}
// 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.


/** A Set that stores the CSS class names for an element. */
abstract class CssClassSet implements Set<String> {

  /**
   * Adds the class [value] to the element if it is not on it, removes it if it
   * is.
   *
   * If [shouldAdd] is true, then we always add that [value] to the element. If
   * [shouldAdd] is false then we always remove [value] from the element.
   */
  bool toggle(String value, [bool shouldAdd]);

  /**
   * Returns [:true:] if classes cannot be added or removed from this
   * [:CssClassSet:].
   */
  bool get frozen;

  /**
   * Determine if this element contains the class [value].
   *
   * This is the Dart equivalent of jQuery's
   * [hasClass](http://api.jquery.com/hasClass/).
   */
  bool contains(String value);

  /**
   * Add the class [value] to element.
   *
   * This is the Dart equivalent of jQuery's
   * [addClass](http://api.jquery.com/addClass/).
   *
   * If this corresponds to one element. Returns true if [value] was added to
   * the set, otherwise false.
   *
   * If this corresponds to many elements, null is always returned.
   */
  bool add(String value);

  /**
   * Remove the class [value] from element, and return true on successful
   * removal.
   *
   * This is the Dart equivalent of jQuery's
   * [removeClass](http://api.jquery.com/removeClass/).
   */
  bool remove(Object value);

  /**
   * Add all classes specified in [iterable] to element.
   *
   * This is the Dart equivalent of jQuery's
   * [addClass](http://api.jquery.com/addClass/).
   */
  void addAll(Iterable<String> iterable);

  /**
   * Remove all classes specified in [iterable] from element.
   *
   * This is the Dart equivalent of jQuery's
   * [removeClass](http://api.jquery.com/removeClass/).
   */
  void removeAll(Iterable<String> iterable);

  /**
   * Toggles all classes specified in [iterable] on element.
   *
   * Iterate through [iterable]'s items, and add it if it is not on it, or
   * remove it if it is. This is the Dart equivalent of jQuery's
   * [toggleClass](http://api.jquery.com/toggleClass/).
   * If [shouldAdd] is true, then we always add all the classes in [iterable]
   * element. If [shouldAdd] is false then we always remove all the classes in
   * [iterable] from the element.
   */
  void toggleAll(Iterable<String> iterable, [bool shouldAdd]);
}

/**
 * A set (union) of the CSS classes that are present in a set of elements.
 * Implemented separately from _ElementCssClassSet for performance.
 */
class _MultiElementCssClassSet extends CssClassSetImpl {
  final Iterable<Element> _elementIterable;
  Iterable<_ElementCssClassSet> _elementCssClassSetIterable;

  _MultiElementCssClassSet(this._elementIterable) {
    _elementCssClassSetIterable = new List.from(_elementIterable).map(
        (e) => new _ElementCssClassSet(e));
  }

  Set<String> readClasses() {
    var s = new LinkedHashSet<String>();
    _elementCssClassSetIterable.forEach((e) => s.addAll(e.readClasses()));
    return s;
  }

  void writeClasses(Set<String> s) {
    var classes = new List.from(s).join(' ');
    for (Element e in _elementIterable) {
      e.className = classes;
    }
  }

  /**
   * Helper method used to modify the set of css classes on this element.
   *
   *   f - callback with:
   *   s - a Set of all the css class name currently on this element.
   *
   *   After f returns, the modified set is written to the
   *       className property of this element.
   */
  modify( f(Set<String> s)) {
    _elementCssClassSetIterable.forEach((e) => e.modify(f));
  }

  /**
   * Adds the class [value] to the element if it is not on it, removes it if it
   * is.
   */
  bool toggle(String value, [bool shouldAdd]) =>
      _modifyWithReturnValue((e) => e.toggle(value, shouldAdd));

  /**
   * Remove the class [value] from element, and return true on successful
   * removal.
   *
   * This is the Dart equivalent of jQuery's
   * [removeClass](http://api.jquery.com/removeClass/).
   */
  bool remove(Object value) => _modifyWithReturnValue((e) => e.remove(value));

  bool _modifyWithReturnValue(f) => _elementCssClassSetIterable.fold(
      false, (prevValue, element) => f(element) || prevValue);
}

class _ElementCssClassSet extends CssClassSetImpl {

  final Element _element;

  _ElementCssClassSet(this._element);

  Set<String> readClasses() {
    var s = new LinkedHashSet<String>();
    var classname = _element.className;

    for (String name in classname.split(' ')) {
      String trimmed = name.trim();
      if (!trimmed.isEmpty) {
        s.add(trimmed);
      }
    }
    return s;
  }

  void writeClasses(Set<String> s) {
    List list = new List.from(s);
    _element.className = s.join(' ');
  }
}
// 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.


/**
 * A rectangle representing all the content of the element in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _ContentCssRect extends CssRect {

  _ContentCssRect(element) : super(element);

  num get height => _element.offsetHeight +
      _addOrSubtractToBoxModel(_HEIGHT, _CONTENT);

  num get width => _element.offsetWidth +
      _addOrSubtractToBoxModel(_WIDTH, _CONTENT);

  /**
   * Set the height to `newHeight`.
   *
   * newHeight can be either a [num] representing the height in pixels or a
   * [Dimension] object. Values of newHeight that are less than zero are
   * converted to effectively setting the height to 0. This is equivalent to the
   * `height` function in jQuery and the calculated `height` CSS value,
   * converted to a num in pixels.
   */
  void set height(newHeight) {
    if (newHeight is Dimension) {
      if (newHeight.value < 0) newHeight = new Dimension.px(0);
      _element.style.height = newHeight.toString();
    } else {
      if (newHeight < 0) newHeight = 0;
      _element.style.height = '${newHeight}px';
    }
  }

  /**
   * Set the current computed width in pixels of this element.
   *
   * newWidth can be either a [num] representing the width in pixels or a
   * [Dimension] object. This is equivalent to the `width` function in jQuery
   * and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels.
   */
  void set width(newWidth) {
    if (newWidth is Dimension) {
      if (newWidth.value < 0) newWidth = new Dimension.px(0);
      _element.style.width = newWidth.toString();
    } else {
      if (newWidth < 0) newWidth = 0;
      _element.style.width = '${newWidth}px';
    }
  }

  num get left => _element.getBoundingClientRect().left -
      _addOrSubtractToBoxModel(['left'], _CONTENT);
  num get top => _element.getBoundingClientRect().top -
      _addOrSubtractToBoxModel(['top'], _CONTENT);
}

/**
 * A list of element content rectangles in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _ContentCssListRect extends _ContentCssRect {
  List<Element> _elementList;

  _ContentCssListRect(elementList) : super(elementList.first) {
    _elementList = elementList;
  }

  /**
   * Set the height to `newHeight`.
   *
   * Values of newHeight that are less than zero are converted to effectively
   * setting the height to 0. This is equivalent to the `height`
   * function in jQuery and the calculated `height` CSS value, converted to a
   * num in pixels.
   */
  void set height(newHeight) {
    _elementList.forEach((e) => e.contentEdge.height = newHeight);
  }

  /**
   * Set the current computed width in pixels of this element.
   *
   * This is equivalent to the `width` function in jQuery and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels.
   */
  void set width(newWidth) {
    _elementList.forEach((e) => e.contentEdge.width = newWidth);
  }
}

/**
 * A rectangle representing the dimensions of the space occupied by the
 * element's content + padding in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _PaddingCssRect extends CssRect {
  _PaddingCssRect(element) : super(element);
  num get height => _element.offsetHeight +
      _addOrSubtractToBoxModel(_HEIGHT, _PADDING);
  num get width => _element.offsetWidth +
      _addOrSubtractToBoxModel(_WIDTH, _PADDING);

  num get left => _element.getBoundingClientRect().left -
      _addOrSubtractToBoxModel(['left'], _PADDING);
  num get top => _element.getBoundingClientRect().top -
      _addOrSubtractToBoxModel(['top'], _PADDING);
}

/**
 * A rectangle representing the dimensions of the space occupied by the
 * element's content + padding + border in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _BorderCssRect extends CssRect {
  _BorderCssRect(element) : super(element);
  num get height => _element.offsetHeight;
  num get width => _element.offsetWidth;

  num get left => _element.getBoundingClientRect().left;
  num get top => _element.getBoundingClientRect().top;
}

/**
 * A rectangle representing the dimensions of the space occupied by the
 * element's content + padding + border + margin in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _MarginCssRect extends CssRect {
  _MarginCssRect(element) : super(element);
  num get height => _element.offsetHeight +
      _addOrSubtractToBoxModel(_HEIGHT, _MARGIN);
  num get width =>
      _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _MARGIN);

  num get left => _element.getBoundingClientRect().left -
      _addOrSubtractToBoxModel(['left'], _MARGIN);
  num get top => _element.getBoundingClientRect().top -
      _addOrSubtractToBoxModel(['top'], _MARGIN);
}

/**
 * A class for representing CSS dimensions.
 *
 * In contrast to the more general purpose [Rectangle] class, this class's
 * values are mutable, so one can change the height of an element
 * programmatically.
 *
 * _Important_ _note_: use of these methods will perform CSS calculations that
 * can trigger a browser reflow. Therefore, use of these properties _during_ an
 * animation frame is discouraged. See also:
 * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
 */
abstract class CssRect extends MutableRectangle<num> {
  Element _element;

  CssRect(this._element) : super(0, 0, 0, 0);

  num get left;

  num get top;

  /**
   * The height of this rectangle.
   *
   * This is equivalent to the `height` function in jQuery and the calculated
   * `height` CSS value, converted to a dimensionless num in pixels. Unlike
   * [getBoundingClientRect], `height` will return the same numerical width if
   * the element is hidden or not.
   */
  num get height;

  /**
   * The width of this rectangle.
   *
   * This is equivalent to the `width` function in jQuery and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels. Unlike
   * [getBoundingClientRect], `width` will return the same numerical width if
   * the element is hidden or not.
   */
  num get width;

  /**
   * Set the height to `newHeight`.
   *
   * newHeight can be either a [num] representing the height in pixels or a
   * [Dimension] object. Values of newHeight that are less than zero are
   * converted to effectively setting the height to 0. This is equivalent to the
   * `height` function in jQuery and the calculated `height` CSS value,
   * converted to a num in pixels.
   *
   * Note that only the content height can actually be set via this method.
   */
  void set height(newHeight) {
    throw new UnsupportedError("Can only set height for content rect.");
  }

  /**
   * Set the current computed width in pixels of this element.
   *
   * newWidth can be either a [num] representing the width in pixels or a
   * [Dimension] object. This is equivalent to the `width` function in jQuery
   * and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels.
   *
   * Note that only the content width can be set via this method.
   */
  void set width(newWidth) {
    throw new UnsupportedError("Can only set width for content rect.");
  }

  /**
   * Return a value that is used to modify the initial height or width
   * measurement of an element. Depending on the value (ideally an enum) passed
   * to augmentingMeasurement, we may need to add or subtract margin, padding,
   * or border values, depending on the measurement we're trying to obtain.
   */
  num _addOrSubtractToBoxModel(List<String> dimensions,
      String augmentingMeasurement) {
    // getComputedStyle always returns pixel values (hence, computed), so we're
    // always dealing with pixels in this method.
    var styles = _element.getComputedStyle();

    var val = 0;

    for (String measurement in dimensions) {
      // The border-box and default box model both exclude margin in the regular
      // height/width calculation, so add it if we want it for this measurement.
      if (augmentingMeasurement == _MARGIN) {
        val += new Dimension.css(styles.getPropertyValue(
            '$augmentingMeasurement-$measurement')).value;
      }

      // The border-box includes padding and border, so remove it if we want
      // just the content itself.
      if (augmentingMeasurement == _CONTENT) {
      	val -= new Dimension.css(
            styles.getPropertyValue('${_PADDING}-$measurement')).value;
      }

      // At this point, we don't wan't to augment with border or margin,
      // so remove border.
      if (augmentingMeasurement != _MARGIN) {
	      val -= new Dimension.css(styles.getPropertyValue(
            'border-${measurement}-width')).value;
      }
    }
    return val;
  }
}

final _HEIGHT = ['top', 'bottom'];
final _WIDTH = ['right', 'left'];
final _CONTENT = 'content';
final _PADDING = 'padding';
final _MARGIN = 'margin';

/**
 * Class representing a
 * [length measurement](https://developer.mozilla.org/en-US/docs/Web/CSS/length)
 * in CSS.
 */
@Experimental()
class Dimension {
  num _value;
  String _unit;

  /** Set this CSS Dimension to a percentage `value`. */
  Dimension.percent(this._value) : _unit = '%';

  /** Set this CSS Dimension to a pixel `value`. */
  Dimension.px(this._value) : _unit = 'px';

  /** Set this CSS Dimension to a pica `value`. */
  Dimension.pc(this._value) : _unit = 'pc';

  /** Set this CSS Dimension to a point `value`. */
  Dimension.pt(this._value) : _unit = 'pt';

  /** Set this CSS Dimension to an inch `value`. */
  Dimension.inch(this._value) : _unit = 'in';

  /** Set this CSS Dimension to a centimeter `value`. */
  Dimension.cm(this._value) : _unit = 'cm';

  /** Set this CSS Dimension to a millimeter `value`. */
  Dimension.mm(this._value) : _unit = 'mm';

  /**
   * Set this CSS Dimension to the specified number of ems.
   *
   * 1em is equal to the current font size. (So 2ems is equal to double the font
   * size). This is useful for producing website layouts that scale nicely with
   * the user's desired font size.
   */
  Dimension.em(this._value) : _unit = 'em';

  /**
   * Set this CSS Dimension to the specified number of x-heights.
   *
   * One ex is equal to the the x-height of a font's baseline to its mean line,
   * generally the height of the letter "x" in the font, which is usually about
   * half the font-size.
   */
  Dimension.ex(this._value) : _unit = 'ex';

  /**
   * Construct a Dimension object from the valid, simple CSS string `cssValue`
   * that represents a distance measurement.
   *
   * This constructor is intended as a convenience method for working with
   * simplistic CSS length measurements. Non-numeric values such as `auto` or
   * `inherit` or invalid CSS will cause this constructor to throw a
   * FormatError.
   */
  Dimension.css(String cssValue) {
    if (cssValue == '') cssValue = '0px';
    if (cssValue.endsWith('%')) {
      _unit = '%';
    } else {
      _unit = cssValue.substring(cssValue.length - 2);
    }
    if (cssValue.contains('.')) {
      _value = double.parse(cssValue.substring(0,
          cssValue.length - _unit.length));
    } else {
      _value = int.parse(cssValue.substring(0, cssValue.length - _unit.length));
    }
  }

  /** Print out the CSS String representation of this value. */
  String toString() {
    return '${_value}${_unit}';
  }

  /** Return a unitless, numerical value of this CSS value. */
  num get value => this._value;
}
// 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.


typedef EventListener(Event event);
// 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.


/**
 * A factory to expose DOM events as Streams.
 */
class EventStreamProvider<T extends Event> {
  final String _eventType;

  const EventStreamProvider(this._eventType);

  /**
   * Gets a [Stream] for this event type, on the specified target.
   *
   * This will always return a broadcast stream so multiple listeners can be
   * used simultaneously.
   *
   * This may be used to capture DOM events:
   *
   *     Element.keyDownEvent.forTarget(element, useCapture: true).listen(...);
   *
   *     // Alternate method:
   *     Element.keyDownEvent.forTarget(element).capture(...);
   *
   * Or for listening to an event which will bubble through the DOM tree:
   *
   *     MediaElement.pauseEvent.forTarget(document.body).listen(...);
   *
   * See also:
   *
   * [addEventListener](http://docs.webplatform.org/wiki/dom/methods/addEventListener)
   */
  Stream<T> forTarget(EventTarget e, {bool useCapture: false}) =>
    new _EventStream(e, _eventType, useCapture);

  /**
   * Gets an [ElementEventStream] for this event type, on the specified element.
   *
   * This will always return a broadcast stream so multiple listeners can be
   * used simultaneously.
   *
   * This may be used to capture DOM events:
   *
   *     Element.keyDownEvent.forElement(element, useCapture: true).listen(...);
   *
   *     // Alternate method:
   *     Element.keyDownEvent.forElement(element).capture(...);
   *
   * Or for listening to an event which will bubble through the DOM tree:
   *
   *     MediaElement.pauseEvent.forElement(document.body).listen(...);
   *
   * See also:
   *
   * [addEventListener](http://docs.webplatform.org/wiki/dom/methods/addEventListener)
   */
  ElementStream<T> forElement(Element e, {bool useCapture: false}) {
    return new _ElementEventStreamImpl(e, _eventType, useCapture);
  }

  /**
   * Gets an [ElementEventStream] for this event type, on the list of elements.
   *
   * This will always return a broadcast stream so multiple listeners can be
   * used simultaneously.
   *
   * This may be used to capture DOM events:
   *
   *     Element.keyDownEvent._forElementList(element, useCapture: true).listen(...);
   *
   * See also:
   *
   * [addEventListener](http://docs.webplatform.org/wiki/dom/methods/addEventListener)
   */
  ElementStream<T> _forElementList(ElementList e, {bool useCapture: false}) {
    return new _ElementListEventStreamImpl(e, _eventType, useCapture);
  }

  /**
   * Gets the type of the event which this would listen for on the specified
   * event target.
   *
   * The target is necessary because some browsers may use different event names
   * for the same purpose and the target allows differentiating browser support.
   */
  String getEventType(EventTarget target) {
    return _eventType;
  }
}

/** A specialized Stream available to [Element]s to enable event delegation. */
abstract class ElementStream<T extends Event> implements Stream<T> {
  /**
   * Return a stream that only fires when the particular event fires for
   * elements matching the specified CSS selector.
   *
   * This is the Dart equivalent to jQuery's
   * [delegate](http://api.jquery.com/delegate/).
   */
  Stream<T> matches(String selector);

  /**
   * Adds a capturing subscription to this stream.
   *
   * If the target of the event is a descendant of the element from which this
   * stream derives then [onData] is called before the event propagates down to
   * the target. This is the opposite of bubbling behavior, where the event
   * is first processed for the event target and then bubbles upward.
   *
   * ## Other resources
   *
   * * [Event Capture]
   * (http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture)
   * from the W3C DOM Events specification.
   */
  StreamSubscription<T> capture(void onData(T event));
}

/**
 * Adapter for exposing DOM events as Dart streams.
 */
class _EventStream<T extends Event> extends Stream<T> {
  final EventTarget _target;
  final String _eventType;
  final bool _useCapture;

  _EventStream(this._target, this._eventType, this._useCapture);

  // DOM events are inherently multi-subscribers.
  Stream<T> asBroadcastStream({void onListen(StreamSubscription subscription),
                               void onCancel(StreamSubscription subscription)})
      => this;
  bool get isBroadcast => true;

  StreamSubscription<T> listen(void onData(T event),
      { Function onError,
        void onDone(),
        bool cancelOnError}) {

    return new _EventStreamSubscription<T>(
        this._target, this._eventType, onData, this._useCapture);
  }
}

/**
 * Adapter for exposing DOM Element events as streams, while also allowing
 * event delegation.
 */
class _ElementEventStreamImpl<T extends Event> extends _EventStream<T>
    implements ElementStream<T> {
  _ElementEventStreamImpl(target, eventType, useCapture) :
      super(target, eventType, useCapture);

  Stream<T> matches(String selector) => this.where(
      (event) => event.target.matchesWithAncestors(selector)).map((e) {
        e._selector = selector;
        return e;
      });

  StreamSubscription<T> capture(void onData(T event)) =>
    new _EventStreamSubscription<T>(
        this._target, this._eventType, onData, true);
}

/**
 * Adapter for exposing events on a collection of DOM Elements as streams,
 * while also allowing event delegation.
 */
class _ElementListEventStreamImpl<T extends Event> extends Stream<T>
    implements ElementStream<T> {
  final Iterable<Element> _targetList;
  final bool _useCapture;
  final String _eventType;

  _ElementListEventStreamImpl(
      this._targetList, this._eventType, this._useCapture);

  Stream<T> matches(String selector) => this.where(
      (event) => event.target.matchesWithAncestors(selector)).map((e) {
        e._selector = selector;
        return e;
      });

  // Delegate all regular Stream behavior to a wrapped Stream.
  StreamSubscription<T> listen(void onData(T event),
      { Function onError,
        void onDone(),
        bool cancelOnError}) {
    var pool = new _StreamPool.broadcast();
    for (var target in _targetList) {
      pool.add(new _EventStream(target, _eventType, _useCapture));
    }
    return pool.stream.listen(onData, onError: onError, onDone: onDone,
          cancelOnError: cancelOnError);
  }

  StreamSubscription<T> capture(void onData(T event)) {
    var pool = new _StreamPool.broadcast();
    for (var target in _targetList) {
      pool.add(new _EventStream(target, _eventType, true));
    }
    return pool.stream.listen(onData);
  }

  Stream<T> asBroadcastStream({void onListen(StreamSubscription subscription),
                               void onCancel(StreamSubscription subscription)})
      => this;
  bool get isBroadcast => true;
}

class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> {
  int _pauseCount = 0;
  EventTarget _target;
  final String _eventType;
  var _onData;
  final bool _useCapture;

  _EventStreamSubscription(this._target, this._eventType, onData,
      this._useCapture) : _onData = _wrapZone(onData) {
    _tryResume();
  }

  Future cancel() {
    if (_canceled) return null;

    _unlisten();
    // Clear out the target to indicate this is complete.
    _target = null;
    _onData = null;
    return null;
  }

  bool get _canceled => _target == null;

  void onData(void handleData(T event)) {
    if (_canceled) {
      throw new StateError("Subscription has been canceled.");
    }
    // Remove current event listener.
    _unlisten();

    _onData = _wrapZone(handleData);
    _tryResume();
  }

  /// Has no effect.
  void onError(Function handleError) {}

  /// Has no effect.
  void onDone(void handleDone()) {}

  void pause([Future resumeSignal]) {
    if (_canceled) return;
    ++_pauseCount;
    _unlisten();

    if (resumeSignal != null) {
      resumeSignal.whenComplete(resume);
    }
  }

  bool get isPaused => _pauseCount > 0;

  void resume() {
    if (_canceled || !isPaused) return;
    --_pauseCount;
    _tryResume();
  }

  void _tryResume() {
    if (_onData != null && !isPaused) {
      _target.addEventListener(_eventType, _onData, _useCapture);
    }
  }

  void _unlisten() {
    if (_onData != null) {
      _target.removeEventListener(_eventType, _onData, _useCapture);
    }
  }

  Future asFuture([var futureValue]) {
    // We just need a future that will never succeed or fail.
    Completer completer = new Completer();
    return completer.future;
  }
}

/**
 * A stream of custom events, which enables the user to "fire" (add) their own
 * custom events to a stream.
 */
abstract class CustomStream<T extends Event> implements Stream<T> {
  /**
   * Add the following custom event to the stream for dispatching to interested
   * listeners.
   */
  void add(T event);
}

class _CustomEventStreamImpl<T extends Event> extends Stream<T>
    implements CustomStream<T> {
  StreamController<T> _streamController;
  /** The type of event this stream is providing (e.g. "keydown"). */
  String _type;

  _CustomEventStreamImpl(String type) {
    _type = type;
    _streamController = new StreamController.broadcast(sync: true);
  }

  // Delegate all regular Stream behavior to our wrapped Stream.
  StreamSubscription<T> listen(void onData(T event),
      { Function onError,
        void onDone(),
        bool cancelOnError}) {
    return _streamController.stream.listen(onData, onError: onError,
        onDone: onDone, cancelOnError: cancelOnError);
  }

  Stream<T> asBroadcastStream({void onListen(StreamSubscription subscription),
                               void onCancel(StreamSubscription subscription)})
      => _streamController.stream;

  bool get isBroadcast => true;

  void add(T event) {
    if (event.type == _type) _streamController.add(event);
  }
}

class _CustomKeyEventStreamImpl extends _CustomEventStreamImpl<KeyEvent>
    implements CustomStream<KeyEvent> {
  _CustomKeyEventStreamImpl(String type) : super(type);

  void add(KeyEvent event) {
    if (event.type == _type) {
      event.currentTarget.dispatchEvent(event._parent);
      _streamController.add(event);
    }
  }
}

/**
 * A pool of streams whose events are unified and emitted through a central
 * stream.
 */
// TODO (efortuna): Remove this when Issue 12218 is addressed.
class _StreamPool<T> {
  StreamController<T> _controller;

  /// Subscriptions to the streams that make up the pool.
  var _subscriptions = new Map<Stream<T>, StreamSubscription<T>>();

  /**
   * Creates a new stream pool where [stream] can be listened to more than
   * once.
   *
   * Any events from buffered streams in the pool will be emitted immediately,
   * regardless of whether [stream] has any subscribers.
   */
  _StreamPool.broadcast() {
    _controller = new StreamController<T>.broadcast(sync: true,
        onCancel: close);
  }

  /**
   * The stream through which all events from streams in the pool are emitted.
   */
  Stream<T> get stream => _controller.stream;

  /**
   * Adds [stream] as a member of this pool.
   *
   * Any events from [stream] will be emitted through [this.stream]. If
   * [stream] is sync, they'll be emitted synchronously; if [stream] is async,
   * they'll be emitted asynchronously.
   */
  void add(Stream<T> stream) {
    if (_subscriptions.containsKey(stream)) return;
    _subscriptions[stream] = stream.listen(_controller.add,
        onError: _controller.addError,
        onDone: () => remove(stream));
  }

  /** Removes [stream] as a member of this pool. */
  void remove(Stream<T> stream) {
    var subscription = _subscriptions.remove(stream);
    if (subscription != null) subscription.cancel();
  }

  /** Removes all streams from this pool and closes [stream]. */
  void close() {
    for (var subscription in _subscriptions.values) {
      subscription.cancel();
    }
    _subscriptions.clear();
    _controller.close();
  }
}

/**
 * A factory to expose DOM events as streams, where the DOM event name has to
 * be determined on the fly (for example, mouse wheel events).
 */
class _CustomEventStreamProvider<T extends Event>
    implements EventStreamProvider<T> {

  final _eventTypeGetter;
  const _CustomEventStreamProvider(this._eventTypeGetter);

  Stream<T> forTarget(EventTarget e, {bool useCapture: false}) {
    return new _EventStream(e, _eventTypeGetter(e), useCapture);
  }

  ElementStream<T> forElement(Element e, {bool useCapture: false}) {
    return new _ElementEventStreamImpl(e, _eventTypeGetter(e), useCapture);
  }

  ElementStream<T> _forElementList(ElementList e,
      {bool useCapture: false}) {
    return new _ElementListEventStreamImpl(e, _eventTypeGetter(e), useCapture);
  }

  String getEventType(EventTarget target) {
    return _eventTypeGetter(target);
  }

  String get _eventType =>
      throw new UnsupportedError('Access type through getEventType method.');
}
// DO NOT EDIT- this file is generated from running tool/generator.sh.

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


/**
 * A Dart DOM validator generated from Caja whitelists.
 *
 * This contains a whitelist of known HTML tagNames and attributes and will only
 * accept known good values.
 *
 * See also:
 *
 * * <https://code.google.com/p/google-caja/wiki/CajaWhitelists>
 */
class _Html5NodeValidator implements NodeValidator {

  static final Set<String> _allowedElements = new Set.from([
    'A',
    'ABBR',
    'ACRONYM',
    'ADDRESS',
    'AREA',
    'ARTICLE',
    'ASIDE',
    'AUDIO',
    'B',
    'BDI',
    'BDO',
    'BIG',
    'BLOCKQUOTE',
    'BR',
    'BUTTON',
    'CANVAS',
    'CAPTION',
    'CENTER',
    'CITE',
    'CODE',
    'COL',
    'COLGROUP',
    'COMMAND',
    'DATA',
    'DATALIST',
    'DD',
    'DEL',
    'DETAILS',
    'DFN',
    'DIR',
    'DIV',
    'DL',
    'DT',
    'EM',
    'FIELDSET',
    'FIGCAPTION',
    'FIGURE',
    'FONT',
    'FOOTER',
    'FORM',
    'H1',
    'H2',
    'H3',
    'H4',
    'H5',
    'H6',
    'HEADER',
    'HGROUP',
    'HR',
    'I',
    'IFRAME',
    'IMG',
    'INPUT',
    'INS',
    'KBD',
    'LABEL',
    'LEGEND',
    'LI',
    'MAP',
    'MARK',
    'MENU',
    'METER',
    'NAV',
    'NOBR',
    'OL',
    'OPTGROUP',
    'OPTION',
    'OUTPUT',
    'P',
    'PRE',
    'PROGRESS',
    'Q',
    'S',
    'SAMP',
    'SECTION',
    'SELECT',
    'SMALL',
    'SOURCE',
    'SPAN',
    'STRIKE',
    'STRONG',
    'SUB',
    'SUMMARY',
    'SUP',
    'TABLE',
    'TBODY',
    'TD',
    'TEXTAREA',
    'TFOOT',
    'TH',
    'THEAD',
    'TIME',
    'TR',
    'TRACK',
    'TT',
    'U',
    'UL',
    'VAR',
    'VIDEO',
    'WBR',
  ]);

  static const _standardAttributes = const <String>[
    '*::class',
    '*::dir',
    '*::draggable',
    '*::hidden',
    '*::id',
    '*::inert',
    '*::itemprop',
    '*::itemref',
    '*::itemscope',
    '*::lang',
    '*::spellcheck',
    '*::title',
    '*::translate',
    'A::accesskey',
    'A::coords',
    'A::hreflang',
    'A::name',
    'A::shape',
    'A::tabindex',
    'A::target',
    'A::type',
    'AREA::accesskey',
    'AREA::alt',
    'AREA::coords',
    'AREA::nohref',
    'AREA::shape',
    'AREA::tabindex',
    'AREA::target',
    'AUDIO::controls',
    'AUDIO::loop',
    'AUDIO::mediagroup',
    'AUDIO::muted',
    'AUDIO::preload',
    'BDO::dir',
    'BODY::alink',
    'BODY::bgcolor',
    'BODY::link',
    'BODY::text',
    'BODY::vlink',
    'BR::clear',
    'BUTTON::accesskey',
    'BUTTON::disabled',
    'BUTTON::name',
    'BUTTON::tabindex',
    'BUTTON::type',
    'BUTTON::value',
    'CANVAS::height',
    'CANVAS::width',
    'CAPTION::align',
    'COL::align',
    'COL::char',
    'COL::charoff',
    'COL::span',
    'COL::valign',
    'COL::width',
    'COLGROUP::align',
    'COLGROUP::char',
    'COLGROUP::charoff',
    'COLGROUP::span',
    'COLGROUP::valign',
    'COLGROUP::width',
    'COMMAND::checked',
    'COMMAND::command',
    'COMMAND::disabled',
    'COMMAND::label',
    'COMMAND::radiogroup',
    'COMMAND::type',
    'DATA::value',
    'DEL::datetime',
    'DETAILS::open',
    'DIR::compact',
    'DIV::align',
    'DL::compact',
    'FIELDSET::disabled',
    'FONT::color',
    'FONT::face',
    'FONT::size',
    'FORM::accept',
    'FORM::autocomplete',
    'FORM::enctype',
    'FORM::method',
    'FORM::name',
    'FORM::novalidate',
    'FORM::target',
    'FRAME::name',
    'H1::align',
    'H2::align',
    'H3::align',
    'H4::align',
    'H5::align',
    'H6::align',
    'HR::align',
    'HR::noshade',
    'HR::size',
    'HR::width',
    'HTML::version',
    'IFRAME::align',
    'IFRAME::frameborder',
    'IFRAME::height',
    'IFRAME::marginheight',
    'IFRAME::marginwidth',
    'IFRAME::width',
    'IMG::align',
    'IMG::alt',
    'IMG::border',
    'IMG::height',
    'IMG::hspace',
    'IMG::ismap',
    'IMG::name',
    'IMG::usemap',
    'IMG::vspace',
    'IMG::width',
    'INPUT::accept',
    'INPUT::accesskey',
    'INPUT::align',
    'INPUT::alt',
    'INPUT::autocomplete',
    'INPUT::checked',
    'INPUT::disabled',
    'INPUT::inputmode',
    'INPUT::ismap',
    'INPUT::list',
    'INPUT::max',
    'INPUT::maxlength',
    'INPUT::min',
    'INPUT::multiple',
    'INPUT::name',
    'INPUT::placeholder',
    'INPUT::readonly',
    'INPUT::required',
    'INPUT::size',
    'INPUT::step',
    'INPUT::tabindex',
    'INPUT::type',
    'INPUT::usemap',
    'INPUT::value',
    'INS::datetime',
    'KEYGEN::disabled',
    'KEYGEN::keytype',
    'KEYGEN::name',
    'LABEL::accesskey',
    'LABEL::for',
    'LEGEND::accesskey',
    'LEGEND::align',
    'LI::type',
    'LI::value',
    'LINK::sizes',
    'MAP::name',
    'MENU::compact',
    'MENU::label',
    'MENU::type',
    'METER::high',
    'METER::low',
    'METER::max',
    'METER::min',
    'METER::value',
    'OBJECT::typemustmatch',
    'OL::compact',
    'OL::reversed',
    'OL::start',
    'OL::type',
    'OPTGROUP::disabled',
    'OPTGROUP::label',
    'OPTION::disabled',
    'OPTION::label',
    'OPTION::selected',
    'OPTION::value',
    'OUTPUT::for',
    'OUTPUT::name',
    'P::align',
    'PRE::width',
    'PROGRESS::max',
    'PROGRESS::min',
    'PROGRESS::value',
    'SELECT::autocomplete',
    'SELECT::disabled',
    'SELECT::multiple',
    'SELECT::name',
    'SELECT::required',
    'SELECT::size',
    'SELECT::tabindex',
    'SOURCE::type',
    'TABLE::align',
    'TABLE::bgcolor',
    'TABLE::border',
    'TABLE::cellpadding',
    'TABLE::cellspacing',
    'TABLE::frame',
    'TABLE::rules',
    'TABLE::summary',
    'TABLE::width',
    'TBODY::align',
    'TBODY::char',
    'TBODY::charoff',
    'TBODY::valign',
    'TD::abbr',
    'TD::align',
    'TD::axis',
    'TD::bgcolor',
    'TD::char',
    'TD::charoff',
    'TD::colspan',
    'TD::headers',
    'TD::height',
    'TD::nowrap',
    'TD::rowspan',
    'TD::scope',
    'TD::valign',
    'TD::width',
    'TEXTAREA::accesskey',
    'TEXTAREA::autocomplete',
    'TEXTAREA::cols',
    'TEXTAREA::disabled',
    'TEXTAREA::inputmode',
    'TEXTAREA::name',
    'TEXTAREA::placeholder',
    'TEXTAREA::readonly',
    'TEXTAREA::required',
    'TEXTAREA::rows',
    'TEXTAREA::tabindex',
    'TEXTAREA::wrap',
    'TFOOT::align',
    'TFOOT::char',
    'TFOOT::charoff',
    'TFOOT::valign',
    'TH::abbr',
    'TH::align',
    'TH::axis',
    'TH::bgcolor',
    'TH::char',
    'TH::charoff',
    'TH::colspan',
    'TH::headers',
    'TH::height',
    'TH::nowrap',
    'TH::rowspan',
    'TH::scope',
    'TH::valign',
    'TH::width',
    'THEAD::align',
    'THEAD::char',
    'THEAD::charoff',
    'THEAD::valign',
    'TR::align',
    'TR::bgcolor',
    'TR::char',
    'TR::charoff',
    'TR::valign',
    'TRACK::default',
    'TRACK::kind',
    'TRACK::label',
    'TRACK::srclang',
    'UL::compact',
    'UL::type',
    'VIDEO::controls',
    'VIDEO::height',
    'VIDEO::loop',
    'VIDEO::mediagroup',
    'VIDEO::muted',
    'VIDEO::preload',
    'VIDEO::width',
  ];

  static const _uriAttributes = const <String>[
    'A::href',
    'AREA::href',
    'BLOCKQUOTE::cite',
    'BODY::background',
    'COMMAND::icon',
    'DEL::cite',
    'FORM::action',
    'IMG::src',
    'INPUT::src',
    'INS::cite',
    'Q::cite',
    'VIDEO::poster',
  ];

  final UriPolicy uriPolicy;

  static final Map<String, Function> _attributeValidators = {};

  /**
   * All known URI attributes will be validated against the UriPolicy, if
   * [uriPolicy] is null then a default UriPolicy will be used.
   */
  _Html5NodeValidator({UriPolicy uriPolicy})
      :uriPolicy = uriPolicy != null ? uriPolicy : new UriPolicy() {

    if (_attributeValidators.isEmpty) {
      for (var attr in _standardAttributes) {
        _attributeValidators[attr] = _standardAttributeValidator;
      }

      for (var attr in _uriAttributes) {
        _attributeValidators[attr] = _uriAttributeValidator;
      }
    }
  }

  bool allowsElement(Element element) {
    return _allowedElements.contains(element.tagName);
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    var tagName = element.tagName;
    var validator = _attributeValidators['$tagName::$attributeName'];
    if (validator == null) {
      validator = _attributeValidators['*::$attributeName'];
    }
    if (validator == null) {
      return false;
    }
    return validator(element, attributeName, value, this);
  }

  static bool _standardAttributeValidator(Element element, String attributeName,
      String value, _Html5NodeValidator context) {
    return true;
  }

  static bool _uriAttributeValidator(Element element, String attributeName,
      String value, _Html5NodeValidator context) {
    return context.uriPolicy.allowsUri(value);
  }
}
// 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.


abstract class ImmutableListMixin<E> implements List<E> {
  // From Iterable<$E>:
  Iterator<E> get iterator {
    // Note: NodeLists are not fixed size. And most probably length shouldn't
    // be cached in both iterator _and_ forEach method. For now caching it
    // for consistency.
    return new FixedSizeListIterator<E>(this);
  }

  // From Collection<E>:
  void add(E value) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  void addAll(Iterable<E> iterable) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  // From List<E>:
  void sort([int compare(E a, E b)]) {
    throw new UnsupportedError("Cannot sort immutable List.");
  }

  void shuffle([Random random]) {
    throw new UnsupportedError("Cannot shuffle immutable List.");
  }

  void insert(int index, E element) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  void insertAll(int index, Iterable<E> iterable) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  void setAll(int index, Iterable<E> iterable) {
    throw new UnsupportedError("Cannot modify an immutable List.");
  }

  E removeAt(int pos) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  E removeLast() {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  bool remove(Object object) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  void removeWhere(bool test(E element)) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  void retainWhere(bool test(E element)) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
    throw new UnsupportedError("Cannot setRange on immutable List.");
  }

  void removeRange(int start, int end) {
    throw new UnsupportedError("Cannot removeRange on immutable List.");
  }

  void replaceRange(int start, int end, Iterable<E> iterable) {
    throw new UnsupportedError("Cannot modify an immutable List.");
  }

  void fillRange(int start, int end, [E fillValue]) {
    throw new UnsupportedError("Cannot modify an immutable List.");
  }
}
// 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.


/**
 * Defines the keycode values for keys that are returned by
 * KeyboardEvent.keyCode.
 *
 * Important note: There is substantial divergence in how different browsers
 * handle keycodes and their variants in different locales/keyboard layouts. We
 * provide these constants to help make code processing keys more readable.
 */
abstract class KeyCode {
  // These constant names were borrowed from Closure's Keycode enumeration
  // class.
  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keycodes.js.source.html
  static const int WIN_KEY_FF_LINUX = 0;
  static const int MAC_ENTER = 3;
  static const int BACKSPACE = 8;
  static const int TAB = 9;
  /** NUM_CENTER is also NUMLOCK for FF and Safari on Mac. */
  static const int NUM_CENTER = 12;
  static const int ENTER = 13;
  static const int SHIFT = 16;
  static const int CTRL = 17;
  static const int ALT = 18;
  static const int PAUSE = 19;
  static const int CAPS_LOCK = 20;
  static const int ESC = 27;
  static const int SPACE = 32;
  static const int PAGE_UP = 33;
  static const int PAGE_DOWN = 34;
  static const int END = 35;
  static const int HOME = 36;
  static const int LEFT = 37;
  static const int UP = 38;
  static const int RIGHT = 39;
  static const int DOWN = 40;
  static const int NUM_NORTH_EAST = 33;
  static const int NUM_SOUTH_EAST = 34;
  static const int NUM_SOUTH_WEST = 35;
  static const int NUM_NORTH_WEST = 36;
  static const int NUM_WEST = 37;
  static const int NUM_NORTH = 38;
  static const int NUM_EAST = 39;
  static const int NUM_SOUTH = 40;
  static const int PRINT_SCREEN = 44;
  static const int INSERT = 45;
  static const int NUM_INSERT = 45;
  static const int DELETE = 46;
  static const int NUM_DELETE = 46;
  static const int ZERO = 48;
  static const int ONE = 49;
  static const int TWO = 50;
  static const int THREE = 51;
  static const int FOUR = 52;
  static const int FIVE = 53;
  static const int SIX = 54;
  static const int SEVEN = 55;
  static const int EIGHT = 56;
  static const int NINE = 57;
  static const int FF_SEMICOLON = 59;
  static const int FF_EQUALS = 61;
  /**
   * CAUTION: The question mark is for US-keyboard layouts. It varies
   * for other locales and keyboard layouts.
   */
  static const int QUESTION_MARK = 63;
  static const int A = 65;
  static const int B = 66;
  static const int C = 67;
  static const int D = 68;
  static const int E = 69;
  static const int F = 70;
  static const int G = 71;
  static const int H = 72;
  static const int I = 73;
  static const int J = 74;
  static const int K = 75;
  static const int L = 76;
  static const int M = 77;
  static const int N = 78;
  static const int O = 79;
  static const int P = 80;
  static const int Q = 81;
  static const int R = 82;
  static const int S = 83;
  static const int T = 84;
  static const int U = 85;
  static const int V = 86;
  static const int W = 87;
  static const int X = 88;
  static const int Y = 89;
  static const int Z = 90;
  static const int META = 91;
  static const int WIN_KEY_LEFT = 91;
  static const int WIN_KEY_RIGHT = 92;
  static const int CONTEXT_MENU = 93;
  static const int NUM_ZERO = 96;
  static const int NUM_ONE = 97;
  static const int NUM_TWO = 98;
  static const int NUM_THREE = 99;
  static const int NUM_FOUR = 100;
  static const int NUM_FIVE = 101;
  static const int NUM_SIX = 102;
  static const int NUM_SEVEN = 103;
  static const int NUM_EIGHT = 104;
  static const int NUM_NINE = 105;
  static const int NUM_MULTIPLY = 106;
  static const int NUM_PLUS = 107;
  static const int NUM_MINUS = 109;
  static const int NUM_PERIOD = 110;
  static const int NUM_DIVISION = 111;
  static const int F1 = 112;
  static const int F2 = 113;
  static const int F3 = 114;
  static const int F4 = 115;
  static const int F5 = 116;
  static const int F6 = 117;
  static const int F7 = 118;
  static const int F8 = 119;
  static const int F9 = 120;
  static const int F10 = 121;
  static const int F11 = 122;
  static const int F12 = 123;
  static const int NUMLOCK = 144;
  static const int SCROLL_LOCK = 145;

  // OS-specific media keys like volume controls and browser controls.
  static const int FIRST_MEDIA_KEY = 166;
  static const int LAST_MEDIA_KEY = 183;

  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int SEMICOLON = 186;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int DASH = 189;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int EQUALS = 187;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int COMMA = 188;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int PERIOD = 190;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int SLASH = 191;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int APOSTROPHE = 192;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int TILDE = 192;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int SINGLE_QUOTE = 222;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int OPEN_SQUARE_BRACKET = 219;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int BACKSLASH = 220;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int CLOSE_SQUARE_BRACKET = 221;
  static const int WIN_KEY = 224;
  static const int MAC_FF_META = 224;
  static const int WIN_IME = 229;

  /** A sentinel value if the keycode could not be determined. */
  static const int UNKNOWN = -1;

  /**
   * Returns true if the keyCode produces a (US keyboard) character.
   * Note: This does not (yet) cover characters on non-US keyboards (Russian,
   * Hebrew, etc.).
   */
  static bool isCharacterKey(int keyCode) {
    if ((keyCode >= ZERO && keyCode <= NINE) ||
        (keyCode >= NUM_ZERO && keyCode <= NUM_MULTIPLY) ||
        (keyCode >= A && keyCode <= Z)) {
      return true;
    }

    // Safari sends zero key code for non-latin characters.
    if (Device.isWebKit && keyCode == 0) {
      return true;
    }

    return (keyCode == SPACE || keyCode == QUESTION_MARK || keyCode == NUM_PLUS
        || keyCode == NUM_MINUS || keyCode == NUM_PERIOD ||
        keyCode == NUM_DIVISION || keyCode == SEMICOLON ||
        keyCode == FF_SEMICOLON || keyCode == DASH || keyCode == EQUALS ||
        keyCode == FF_EQUALS || keyCode == COMMA || keyCode == PERIOD ||
        keyCode == SLASH || keyCode == APOSTROPHE || keyCode == SINGLE_QUOTE ||
        keyCode == OPEN_SQUARE_BRACKET || keyCode == BACKSLASH ||
        keyCode == CLOSE_SQUARE_BRACKET);
  }

  /**
   * Experimental helper function for converting keyCodes to keyNames for the
   * keyIdentifier attribute still used in browsers not updated with current
   * spec. This is an imperfect conversion! It will need to be refined, but
   * hopefully it can just completely go away once all the browsers update to
   * follow the DOM3 spec.
   */
  static String _convertKeyCodeToKeyName(int keyCode) {
    switch(keyCode) {
      case KeyCode.ALT: return _KeyName.ALT;
      case KeyCode.BACKSPACE: return _KeyName.BACKSPACE;
      case KeyCode.CAPS_LOCK: return _KeyName.CAPS_LOCK;
      case KeyCode.CTRL: return _KeyName.CONTROL;
      case KeyCode.DELETE: return _KeyName.DEL;
      case KeyCode.DOWN: return _KeyName.DOWN;
      case KeyCode.END: return _KeyName.END;
      case KeyCode.ENTER: return _KeyName.ENTER;
      case KeyCode.ESC: return _KeyName.ESC;
      case KeyCode.F1: return _KeyName.F1;
      case KeyCode.F2: return _KeyName.F2;
      case KeyCode.F3: return _KeyName.F3;
      case KeyCode.F4: return _KeyName.F4;
      case KeyCode.F5: return _KeyName.F5;
      case KeyCode.F6: return _KeyName.F6;
      case KeyCode.F7: return _KeyName.F7;
      case KeyCode.F8: return _KeyName.F8;
      case KeyCode.F9: return _KeyName.F9;
      case KeyCode.F10: return _KeyName.F10;
      case KeyCode.F11: return _KeyName.F11;
      case KeyCode.F12: return _KeyName.F12;
      case KeyCode.HOME: return _KeyName.HOME;
      case KeyCode.INSERT: return _KeyName.INSERT;
      case KeyCode.LEFT: return _KeyName.LEFT;
      case KeyCode.META: return _KeyName.META;
      case KeyCode.NUMLOCK: return _KeyName.NUM_LOCK;
      case KeyCode.PAGE_DOWN: return _KeyName.PAGE_DOWN;
      case KeyCode.PAGE_UP: return _KeyName.PAGE_UP;
      case KeyCode.PAUSE: return _KeyName.PAUSE;
      case KeyCode.PRINT_SCREEN: return _KeyName.PRINT_SCREEN;
      case KeyCode.RIGHT: return _KeyName.RIGHT;
      case KeyCode.SCROLL_LOCK: return _KeyName.SCROLL;
      case KeyCode.SHIFT: return _KeyName.SHIFT;
      case KeyCode.SPACE: return _KeyName.SPACEBAR;
      case KeyCode.TAB: return _KeyName.TAB;
      case KeyCode.UP: return _KeyName.UP;
      case KeyCode.WIN_IME:
      case KeyCode.WIN_KEY:
      case KeyCode.WIN_KEY_LEFT:
      case KeyCode.WIN_KEY_RIGHT:
        return _KeyName.WIN;
      default: return _KeyName.UNIDENTIFIED;
    }
    return _KeyName.UNIDENTIFIED;
  }
}
// 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.


/**
 * Defines the standard key locations returned by
 * KeyboardEvent.getKeyLocation.
 */
abstract class KeyLocation {

  /**
   * The event key is not distinguished as the left or right version
   * of the key, and did not originate from the numeric keypad (or did not
   * originate with a virtual key corresponding to the numeric keypad).
   */
  static const int STANDARD = 0;

  /**
   * The event key is in the left key location.
   */
  static const int LEFT = 1;

  /**
   * The event key is in the right key location.
   */
  static const int RIGHT = 2;

  /**
   * The event key originated on the numeric keypad or with a virtual key
   * corresponding to the numeric keypad.
   */
  static const int NUMPAD = 3;

  /**
   * The event key originated on a mobile device, either on a physical
   * keypad or a virtual keyboard.
   */
  static const int MOBILE = 4;

  /**
   * The event key originated on a game controller or a joystick on a mobile
   * device.
   */
  static const int JOYSTICK = 5;
}
// 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.


/**
 * Defines the standard keyboard identifier names for keys that are returned
 * by KeyboardEvent.getKeyboardIdentifier when the key does not have a direct
 * unicode mapping.
 */
abstract class _KeyName {

  /** The Accept (Commit, OK) key */
  static const String ACCEPT = "Accept";

  /** The Add key */
  static const String ADD = "Add";

  /** The Again key */
  static const String AGAIN = "Again";

  /** The All Candidates key */
  static const String ALL_CANDIDATES = "AllCandidates";

  /** The Alphanumeric key */
  static const String ALPHANUMERIC = "Alphanumeric";

  /** The Alt (Menu) key */
  static const String ALT = "Alt";

  /** The Alt-Graph key */
  static const String ALT_GRAPH = "AltGraph";

  /** The Application key */
  static const String APPS = "Apps";

  /** The ATTN key */
  static const String ATTN = "Attn";

  /** The Browser Back key */
  static const String BROWSER_BACK = "BrowserBack";

  /** The Browser Favorites key */
  static const String BROWSER_FAVORTIES = "BrowserFavorites";

  /** The Browser Forward key */
  static const String BROWSER_FORWARD = "BrowserForward";

  /** The Browser Home key */
  static const String BROWSER_NAME = "BrowserHome";

  /** The Browser Refresh key */
  static const String BROWSER_REFRESH = "BrowserRefresh";

  /** The Browser Search key */
  static const String BROWSER_SEARCH = "BrowserSearch";

  /** The Browser Stop key */
  static const String BROWSER_STOP = "BrowserStop";

  /** The Camera key */
  static const String CAMERA = "Camera";

  /** The Caps Lock (Capital) key */
  static const String CAPS_LOCK = "CapsLock";

  /** The Clear key */
  static const String CLEAR = "Clear";

  /** The Code Input key */
  static const String CODE_INPUT = "CodeInput";

  /** The Compose key */
  static const String COMPOSE = "Compose";

  /** The Control (Ctrl) key */
  static const String CONTROL = "Control";

  /** The Crsel key */
  static const String CRSEL = "Crsel";

  /** The Convert key */
  static const String CONVERT = "Convert";

  /** The Copy key */
  static const String COPY = "Copy";

  /** The Cut key */
  static const String CUT = "Cut";

  /** The Decimal key */
  static const String DECIMAL = "Decimal";

  /** The Divide key */
  static const String DIVIDE = "Divide";

  /** The Down Arrow key */
  static const String DOWN = "Down";

  /** The diagonal Down-Left Arrow key */
  static const String DOWN_LEFT = "DownLeft";

  /** The diagonal Down-Right Arrow key */
  static const String DOWN_RIGHT = "DownRight";

  /** The Eject key */
  static const String EJECT = "Eject";

  /** The End key */
  static const String END = "End";

  /**
   * The Enter key. Note: This key value must also be used for the Return
   *  (Macintosh numpad) key
   */
  static const String ENTER = "Enter";

  /** The Erase EOF key */
  static const String ERASE_EOF= "EraseEof";

  /** The Execute key */
  static const String EXECUTE = "Execute";

  /** The Exsel key */
  static const String EXSEL = "Exsel";

  /** The Function switch key */
  static const String FN = "Fn";

  /** The F1 key */
  static const String F1 = "F1";

  /** The F2 key */
  static const String F2 = "F2";

  /** The F3 key */
  static const String F3 = "F3";

  /** The F4 key */
  static const String F4 = "F4";

  /** The F5 key */
  static const String F5 = "F5";

  /** The F6 key */
  static const String F6 = "F6";

  /** The F7 key */
  static const String F7 = "F7";

  /** The F8 key */
  static const String F8 = "F8";

  /** The F9 key */
  static const String F9 = "F9";

  /** The F10 key */
  static const String F10 = "F10";

  /** The F11 key */
  static const String F11 = "F11";

  /** The F12 key */
  static const String F12 = "F12";

  /** The F13 key */
  static const String F13 = "F13";

  /** The F14 key */
  static const String F14 = "F14";

  /** The F15 key */
  static const String F15 = "F15";

  /** The F16 key */
  static const String F16 = "F16";

  /** The F17 key */
  static const String F17 = "F17";

  /** The F18 key */
  static const String F18 = "F18";

  /** The F19 key */
  static const String F19 = "F19";

  /** The F20 key */
  static const String F20 = "F20";

  /** The F21 key */
  static const String F21 = "F21";

  /** The F22 key */
  static const String F22 = "F22";

  /** The F23 key */
  static const String F23 = "F23";

  /** The F24 key */
  static const String F24 = "F24";

  /** The Final Mode (Final) key used on some asian keyboards */
  static const String FINAL_MODE = "FinalMode";

  /** The Find key */
  static const String FIND = "Find";

  /** The Full-Width Characters key */
  static const String FULL_WIDTH = "FullWidth";

  /** The Half-Width Characters key */
  static const String HALF_WIDTH = "HalfWidth";

  /** The Hangul (Korean characters) Mode key */
  static const String HANGUL_MODE = "HangulMode";

  /** The Hanja (Korean characters) Mode key */
  static const String HANJA_MODE = "HanjaMode";

  /** The Help key */
  static const String HELP = "Help";

  /** The Hiragana (Japanese Kana characters) key */
  static const String HIRAGANA = "Hiragana";

  /** The Home key */
  static const String HOME = "Home";

  /** The Insert (Ins) key */
  static const String INSERT = "Insert";

  /** The Japanese-Hiragana key */
  static const String JAPANESE_HIRAGANA = "JapaneseHiragana";

  /** The Japanese-Katakana key */
  static const String JAPANESE_KATAKANA = "JapaneseKatakana";

  /** The Japanese-Romaji key */
  static const String JAPANESE_ROMAJI = "JapaneseRomaji";

  /** The Junja Mode key */
  static const String JUNJA_MODE = "JunjaMode";

  /** The Kana Mode (Kana Lock) key */
  static const String KANA_MODE = "KanaMode";

  /**
   * The Kanji (Japanese name for ideographic characters of Chinese origin)
   * Mode key
   */
  static const String KANJI_MODE = "KanjiMode";

  /** The Katakana (Japanese Kana characters) key */
  static const String KATAKANA = "Katakana";

  /** The Start Application One key */
  static const String LAUNCH_APPLICATION_1 = "LaunchApplication1";

  /** The Start Application Two key */
  static const String LAUNCH_APPLICATION_2 = "LaunchApplication2";

  /** The Start Mail key */
  static const String LAUNCH_MAIL = "LaunchMail";

  /** The Left Arrow key */
  static const String LEFT = "Left";

  /** The Menu key */
  static const String MENU = "Menu";

  /**
   * The Meta key. Note: This key value shall be also used for the Apple
   * Command key
   */
  static const String META = "Meta";

  /** The Media Next Track key */
  static const String MEDIA_NEXT_TRACK = "MediaNextTrack";

  /** The Media Play Pause key */
  static const String MEDIA_PAUSE_PLAY = "MediaPlayPause";

  /** The Media Previous Track key */
  static const String MEDIA_PREVIOUS_TRACK = "MediaPreviousTrack";

  /** The Media Stop key */
  static const String MEDIA_STOP = "MediaStop";

  /** The Mode Change key */
  static const String MODE_CHANGE = "ModeChange";

  /** The Next Candidate function key */
  static const String NEXT_CANDIDATE = "NextCandidate";

  /** The Nonconvert (Don't Convert) key */
  static const String NON_CONVERT = "Nonconvert";

  /** The Number Lock key */
  static const String NUM_LOCK = "NumLock";

  /** The Page Down (Next) key */
  static const String PAGE_DOWN = "PageDown";

  /** The Page Up key */
  static const String PAGE_UP = "PageUp";

  /** The Paste key */
  static const String PASTE = "Paste";

  /** The Pause key */
  static const String PAUSE = "Pause";

  /** The Play key */
  static const String PLAY = "Play";

  /**
   * The Power key. Note: Some devices may not expose this key to the
   * operating environment
   */
  static const String POWER = "Power";

  /** The Previous Candidate function key */
  static const String PREVIOUS_CANDIDATE = "PreviousCandidate";

  /** The Print Screen (PrintScrn, SnapShot) key */
  static const String PRINT_SCREEN = "PrintScreen";

  /** The Process key */
  static const String PROCESS = "Process";

  /** The Props key */
  static const String PROPS = "Props";

  /** The Right Arrow key */
  static const String RIGHT = "Right";

  /** The Roman Characters function key */
  static const String ROMAN_CHARACTERS = "RomanCharacters";

  /** The Scroll Lock key */
  static const String SCROLL = "Scroll";

  /** The Select key */
  static const String SELECT = "Select";

  /** The Select Media key */
  static const String SELECT_MEDIA = "SelectMedia";

  /** The Separator key */
  static const String SEPARATOR = "Separator";

  /** The Shift key */
  static const String SHIFT = "Shift";

  /** The Soft1 key */
  static const String SOFT_1 = "Soft1";

  /** The Soft2 key */
  static const String SOFT_2 = "Soft2";

  /** The Soft3 key */
  static const String SOFT_3 = "Soft3";

  /** The Soft4 key */
  static const String SOFT_4 = "Soft4";

  /** The Stop key */
  static const String STOP = "Stop";

  /** The Subtract key */
  static const String SUBTRACT = "Subtract";

  /** The Symbol Lock key */
  static const String SYMBOL_LOCK = "SymbolLock";

  /** The Up Arrow key */
  static const String UP = "Up";

  /** The diagonal Up-Left Arrow key */
  static const String UP_LEFT = "UpLeft";

  /** The diagonal Up-Right Arrow key */
  static const String UP_RIGHT = "UpRight";

  /** The Undo key */
  static const String UNDO = "Undo";

  /** The Volume Down key */
  static const String VOLUME_DOWN = "VolumeDown";

  /** The Volume Mute key */
  static const String VOLUMN_MUTE = "VolumeMute";

  /** The Volume Up key */
  static const String VOLUMN_UP = "VolumeUp";

  /** The Windows Logo key */
  static const String WIN = "Win";

  /** The Zoom key */
  static const String ZOOM = "Zoom";

  /**
   * The Backspace (Back) key. Note: This key value shall be also used for the
   * key labeled 'delete' MacOS keyboards when not modified by the 'Fn' key
   */
  static const String BACKSPACE = "Backspace";

  /** The Horizontal Tabulation (Tab) key */
  static const String TAB = "Tab";

  /** The Cancel key */
  static const String CANCEL = "Cancel";

  /** The Escape (Esc) key */
  static const String ESC = "Esc";

  /** The Space (Spacebar) key:   */
  static const String SPACEBAR = "Spacebar";

  /**
   * The Delete (Del) Key. Note: This key value shall be also used for the key
   * labeled 'delete' MacOS keyboards when modified by the 'Fn' key
   */
  static const String DEL = "Del";

  /** The Combining Grave Accent (Greek Varia, Dead Grave) key */
  static const String DEAD_GRAVE = "DeadGrave";

  /**
   * The Combining Acute Accent (Stress Mark, Greek Oxia, Tonos, Dead Eacute)
   * key
   */
  static const String DEAD_EACUTE = "DeadEacute";

  /** The Combining Circumflex Accent (Hat, Dead Circumflex) key */
  static const String DEAD_CIRCUMFLEX = "DeadCircumflex";

  /** The Combining Tilde (Dead Tilde) key */
  static const String DEAD_TILDE = "DeadTilde";

  /** The Combining Macron (Long, Dead Macron) key */
  static const String DEAD_MACRON = "DeadMacron";

  /** The Combining Breve (Short, Dead Breve) key */
  static const String DEAD_BREVE = "DeadBreve";

  /** The Combining Dot Above (Derivative, Dead Above Dot) key */
  static const String DEAD_ABOVE_DOT = "DeadAboveDot";

  /**
   * The Combining Diaeresis (Double Dot Abode, Umlaut, Greek Dialytika,
   * Double Derivative, Dead Diaeresis) key
   */
  static const String DEAD_UMLAUT = "DeadUmlaut";

  /** The Combining Ring Above (Dead Above Ring) key */
  static const String DEAD_ABOVE_RING = "DeadAboveRing";

  /** The Combining Double Acute Accent (Dead Doubleacute) key */
  static const String DEAD_DOUBLEACUTE = "DeadDoubleacute";

  /** The Combining Caron (Hacek, V Above, Dead Caron) key */
  static const String DEAD_CARON = "DeadCaron";

  /** The Combining Cedilla (Dead Cedilla) key */
  static const String DEAD_CEDILLA = "DeadCedilla";

  /** The Combining Ogonek (Nasal Hook, Dead Ogonek) key */
  static const String DEAD_OGONEK = "DeadOgonek";

  /**
   * The Combining Greek Ypogegrammeni (Greek Non-Spacing Iota Below, Iota
   * Subscript, Dead Iota) key
   */
  static const String DEAD_IOTA = "DeadIota";

  /**
   * The Combining Katakana-Hiragana Voiced Sound Mark (Dead Voiced Sound) key
   */
  static const String DEAD_VOICED_SOUND = "DeadVoicedSound";

  /**
   * The Combining Katakana-Hiragana Semi-Voiced Sound Mark (Dead Semivoiced
   * Sound) key
   */
  static const String DEC_SEMIVOICED_SOUND= "DeadSemivoicedSound";

  /**
   * Key value used when an implementation is unable to identify another key
   * value, due to either hardware, platform, or software constraints
   */
  static const String UNIDENTIFIED = "Unidentified";
}
// 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.


/**
 * Internal class that does the actual calculations to determine keyCode and
 * charCode for keydown, keypress, and keyup events for all browsers.
 */
class _KeyboardEventHandler extends EventStreamProvider<KeyEvent> {
  // This code inspired by Closure's KeyHandling library.
  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keyhandler.js.source.html

  /**
   * The set of keys that have been pressed down without seeing their
   * corresponding keyup event.
   */
  final List<KeyboardEvent> _keyDownList = <KeyboardEvent>[];

  /** The type of KeyEvent we are tracking (keyup, keydown, keypress). */
  final String _type;

  /** The element we are watching for events to happen on. */
  final EventTarget _target;

  // The distance to shift from upper case alphabet Roman letters to lower case.
  static final int _ROMAN_ALPHABET_OFFSET = "a".codeUnits[0] - "A".codeUnits[0];

  /** Custom Stream (Controller) to produce KeyEvents for the stream. */
  _CustomKeyEventStreamImpl _stream;

  static const _EVENT_TYPE = 'KeyEvent';

  /**
   * An enumeration of key identifiers currently part of the W3C draft for DOM3
   * and their mappings to keyCodes.
   * http://www.w3.org/TR/DOM-Level-3-Events/keyset.html#KeySet-Set
   */
  static const Map<String, int> _keyIdentifier = const {
    'Up': KeyCode.UP,
    'Down': KeyCode.DOWN,
    'Left': KeyCode.LEFT,
    'Right': KeyCode.RIGHT,
    'Enter': KeyCode.ENTER,
    'F1': KeyCode.F1,
    'F2': KeyCode.F2,
    'F3': KeyCode.F3,
    'F4': KeyCode.F4,
    'F5': KeyCode.F5,
    'F6': KeyCode.F6,
    'F7': KeyCode.F7,
    'F8': KeyCode.F8,
    'F9': KeyCode.F9,
    'F10': KeyCode.F10,
    'F11': KeyCode.F11,
    'F12': KeyCode.F12,
    'U+007F': KeyCode.DELETE,
    'Home': KeyCode.HOME,
    'End': KeyCode.END,
    'PageUp': KeyCode.PAGE_UP,
    'PageDown': KeyCode.PAGE_DOWN,
    'Insert': KeyCode.INSERT
  };

  /** Return a stream for KeyEvents for the specified target. */
  // Note: this actually functions like a factory constructor.
  CustomStream<KeyEvent> forTarget(EventTarget e, {bool useCapture: false}) {
    var handler = new _KeyboardEventHandler.initializeAllEventListeners(
        _type, e);
    return handler._stream;
  }

  /**
   * General constructor, performs basic initialization for our improved
   * KeyboardEvent controller.
   */
  _KeyboardEventHandler(this._type): super(_EVENT_TYPE),
      _stream = new _CustomKeyEventStreamImpl('event'), _target = null;

  /**
   * Hook up all event listeners under the covers so we can estimate keycodes
   * and charcodes when they are not provided.
   */
  _KeyboardEventHandler.initializeAllEventListeners(this._type, this._target) :
      super(_EVENT_TYPE) {
    Element.keyDownEvent.forTarget(_target, useCapture: true).listen(
        processKeyDown);
    Element.keyPressEvent.forTarget(_target, useCapture: true).listen(
        processKeyPress);
    Element.keyUpEvent.forTarget(_target, useCapture: true).listen(
        processKeyUp);
    _stream = new _CustomKeyEventStreamImpl(_type);
  }

  /** Determine if caps lock is one of the currently depressed keys. */
  bool get _capsLockOn =>
      _keyDownList.any((var element) => element.keyCode == KeyCode.CAPS_LOCK);

  /**
   * Given the previously recorded keydown key codes, see if we can determine
   * the keycode of this keypress [event]. (Generally browsers only provide
   * charCode information for keypress events, but with a little
   * reverse-engineering, we can also determine the keyCode.) Returns
   * KeyCode.UNKNOWN if the keycode could not be determined.
   */
  int _determineKeyCodeForKeypress(KeyboardEvent event) {
    // Note: This function is a work in progress. We'll expand this function
    // once we get more information about other keyboards.
    for (var prevEvent in _keyDownList) {
      if (prevEvent._shadowCharCode == event.charCode) {
        return prevEvent.keyCode;
      }
      if ((event.shiftKey || _capsLockOn) && event.charCode >= "A".codeUnits[0]
          && event.charCode <= "Z".codeUnits[0] && event.charCode +
          _ROMAN_ALPHABET_OFFSET == prevEvent._shadowCharCode) {
        return prevEvent.keyCode;
      }
    }
    return KeyCode.UNKNOWN;
  }

  /**
   * Given the charater code returned from a keyDown [event], try to ascertain
   * and return the corresponding charCode for the character that was pressed.
   * This information is not shown to the user, but used to help polyfill
   * keypress events.
   */
  int _findCharCodeKeyDown(KeyboardEvent event) {
    if (event.keyLocation == 3) { // Numpad keys.
      switch (event.keyCode) {
        case KeyCode.NUM_ZERO:
          // Even though this function returns _charCodes_, for some cases the
          // KeyCode == the charCode we want, in which case we use the keycode
          // constant for readability.
          return KeyCode.ZERO;
        case KeyCode.NUM_ONE:
          return KeyCode.ONE;
        case KeyCode.NUM_TWO:
          return KeyCode.TWO;
        case KeyCode.NUM_THREE:
          return KeyCode.THREE;
        case KeyCode.NUM_FOUR:
          return KeyCode.FOUR;
        case KeyCode.NUM_FIVE:
          return KeyCode.FIVE;
        case KeyCode.NUM_SIX:
          return KeyCode.SIX;
        case KeyCode.NUM_SEVEN:
          return KeyCode.SEVEN;
        case KeyCode.NUM_EIGHT:
          return KeyCode.EIGHT;
        case KeyCode.NUM_NINE:
          return KeyCode.NINE;
        case KeyCode.NUM_MULTIPLY:
          return 42; // Char code for *
        case KeyCode.NUM_PLUS:
          return 43; // +
        case KeyCode.NUM_MINUS:
          return 45; // -
        case KeyCode.NUM_PERIOD:
          return 46; // .
        case KeyCode.NUM_DIVISION:
          return 47; // /
      }
    } else if (event.keyCode >= 65 && event.keyCode <= 90) {
      // Set the "char code" for key down as the lower case letter. Again, this
      // will not show up for the user, but will be helpful in estimating
      // keyCode locations and other information during the keyPress event.
      return event.keyCode + _ROMAN_ALPHABET_OFFSET;
    }
    switch(event.keyCode) {
      case KeyCode.SEMICOLON:
        return KeyCode.FF_SEMICOLON;
      case KeyCode.EQUALS:
        return KeyCode.FF_EQUALS;
      case KeyCode.COMMA:
        return 44; // Ascii value for ,
      case KeyCode.DASH:
        return 45; // -
      case KeyCode.PERIOD:
        return 46; // .
      case KeyCode.SLASH:
        return 47; // /
      case KeyCode.APOSTROPHE:
        return 96; // `
      case KeyCode.OPEN_SQUARE_BRACKET:
        return 91; // [
      case KeyCode.BACKSLASH:
        return 92; // \
      case KeyCode.CLOSE_SQUARE_BRACKET:
        return 93; // ]
      case KeyCode.SINGLE_QUOTE:
        return 39; // '
    }
    return event.keyCode;
  }

  /**
   * Returns true if the key fires a keypress event in the current browser.
   */
  bool _firesKeyPressEvent(KeyEvent event) {
    if (!Device.isIE && !Device.isWebKit) {
      return true;
    }

    if (Device.userAgent.contains('Mac') && event.altKey) {
      return KeyCode.isCharacterKey(event.keyCode);
    }

    // Alt but not AltGr which is represented as Alt+Ctrl.
    if (event.altKey && !event.ctrlKey) {
      return false;
    }

    // Saves Ctrl or Alt + key for IE and WebKit, which won't fire keypress.
    if (!event.shiftKey &&
        (_keyDownList.last.keyCode == KeyCode.CTRL ||
         _keyDownList.last.keyCode == KeyCode.ALT ||
         Device.userAgent.contains('Mac') &&
         _keyDownList.last.keyCode == KeyCode.META)) {
      return false;
    }

    // Some keys with Ctrl/Shift do not issue keypress in WebKit.
    if (Device.isWebKit && event.ctrlKey && event.shiftKey && (
        event.keyCode == KeyCode.BACKSLASH ||
        event.keyCode == KeyCode.OPEN_SQUARE_BRACKET ||
        event.keyCode == KeyCode.CLOSE_SQUARE_BRACKET ||
        event.keyCode == KeyCode.TILDE ||
        event.keyCode == KeyCode.SEMICOLON || event.keyCode == KeyCode.DASH ||
        event.keyCode == KeyCode.EQUALS || event.keyCode == KeyCode.COMMA ||
        event.keyCode == KeyCode.PERIOD || event.keyCode == KeyCode.SLASH ||
        event.keyCode == KeyCode.APOSTROPHE ||
        event.keyCode == KeyCode.SINGLE_QUOTE)) {
      return false;
    }

    switch (event.keyCode) {
      case KeyCode.ENTER:
        // IE9 does not fire keypress on ENTER.
        return !Device.isIE;
      case KeyCode.ESC:
        return !Device.isWebKit;
    }

    return KeyCode.isCharacterKey(event.keyCode);
  }

  /**
   * Normalize the keycodes to the IE KeyCodes (this is what Chrome, IE, and
   * Opera all use).
   */
  int _normalizeKeyCodes(KeyboardEvent event) {
    // Note: This may change once we get input about non-US keyboards.
    if (Device.isFirefox) {
      switch(event.keyCode) {
        case KeyCode.FF_EQUALS:
          return KeyCode.EQUALS;
        case KeyCode.FF_SEMICOLON:
          return KeyCode.SEMICOLON;
        case KeyCode.MAC_FF_META:
          return KeyCode.META;
        case KeyCode.WIN_KEY_FF_LINUX:
          return KeyCode.WIN_KEY;
      }
    }
    return event.keyCode;
  }

  /** Handle keydown events. */
  void processKeyDown(KeyboardEvent e) {
    // Ctrl-Tab and Alt-Tab can cause the focus to be moved to another window
    // before we've caught a key-up event.  If the last-key was one of these
    // we reset the state.
    if (_keyDownList.length > 0 &&
        (_keyDownList.last.keyCode == KeyCode.CTRL && !e.ctrlKey ||
         _keyDownList.last.keyCode == KeyCode.ALT && !e.altKey ||
         Device.userAgent.contains('Mac') &&
         _keyDownList.last.keyCode == KeyCode.META && !e.metaKey)) {
      _keyDownList.clear();
    }

    var event = new KeyEvent.wrap(e);
    event._shadowKeyCode = _normalizeKeyCodes(event);
    // Technically a "keydown" event doesn't have a charCode. This is
    // calculated nonetheless to provide us with more information in giving
    // as much information as possible on keypress about keycode and also
    // charCode.
    event._shadowCharCode = _findCharCodeKeyDown(event);
    if (_keyDownList.length > 0 && event.keyCode != _keyDownList.last.keyCode &&
        !_firesKeyPressEvent(event)) {
      // Some browsers have quirks not firing keypress events where all other
      // browsers do. This makes them more consistent.
      processKeyPress(e);
    }
    _keyDownList.add(event);
    _stream.add(event);
  }

  /** Handle keypress events. */
  void processKeyPress(KeyboardEvent event) {
    var e = new KeyEvent.wrap(event);
    // IE reports the character code in the keyCode field for keypress events.
    // There are two exceptions however, Enter and Escape.
    if (Device.isIE) {
      if (e.keyCode == KeyCode.ENTER || e.keyCode == KeyCode.ESC) {
        e._shadowCharCode = 0;
      } else {
        e._shadowCharCode = e.keyCode;
      }
    } else if (Device.isOpera) {
      // Opera reports the character code in the keyCode field.
      e._shadowCharCode = KeyCode.isCharacterKey(e.keyCode) ? e.keyCode : 0;
    }
    // Now we guestimate about what the keycode is that was actually
    // pressed, given previous keydown information.
    e._shadowKeyCode = _determineKeyCodeForKeypress(e);

    // Correct the key value for certain browser-specific quirks.
    if (e._shadowKeyIdentifier != null &&
        _keyIdentifier.containsKey(e._shadowKeyIdentifier)) {
      // This is needed for Safari Windows because it currently doesn't give a
      // keyCode/which for non printable keys.
      e._shadowKeyCode = _keyIdentifier[e._shadowKeyIdentifier];
    }
    e._shadowAltKey = _keyDownList.any((var element) => element.altKey);
    _stream.add(e);
  }

  /** Handle keyup events. */
  void processKeyUp(KeyboardEvent event) {
    var e = new KeyEvent.wrap(event);
    KeyboardEvent toRemove = null;
    for (var key in _keyDownList) {
      if (key.keyCode == e.keyCode) {
        toRemove = key;
      }
    }
    if (toRemove != null) {
      _keyDownList.removeWhere((element) => element == toRemove);
    } else if (_keyDownList.length > 0) {
      // This happens when we've reached some international keyboard case we
      // haven't accounted for or we haven't correctly eliminated all browser
      // inconsistencies. Filing bugs on when this is reached is welcome!
      _keyDownList.removeLast();
    }
    _stream.add(e);
  }
}


/**
 * Records KeyboardEvents that occur on a particular element, and provides a
 * stream of outgoing KeyEvents with cross-browser consistent keyCode and
 * charCode values despite the fact that a multitude of browsers that have
 * varying keyboard default behavior.
 *
 * Example usage:
 *
 *     KeyboardEventStream.onKeyDown(document.body).listen(
 *         keydownHandlerTest);
 *
 * This class is very much a work in progress, and we'd love to get information
 * on how we can make this class work with as many international keyboards as
 * possible. Bugs welcome!
 */
class KeyboardEventStream {

  /** Named constructor to produce a stream for onKeyPress events. */
  static CustomStream<KeyEvent> onKeyPress(EventTarget target) =>
      new _KeyboardEventHandler('keypress').forTarget(target);

  /** Named constructor to produce a stream for onKeyUp events. */
  static CustomStream<KeyEvent> onKeyUp(EventTarget target) =>
      new _KeyboardEventHandler('keyup').forTarget(target);

  /** Named constructor to produce a stream for onKeyDown events. */
  static CustomStream<KeyEvent> onKeyDown(EventTarget target) =>
      new _KeyboardEventHandler('keydown').forTarget(target);
}
// 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.



/**
 * Class which helps construct standard node validation policies.
 *
 * By default this will not accept anything, but the 'allow*' functions can be
 * used to expand what types of elements or attributes are allowed.
 *
 * All allow functions are additive- elements will be accepted if they are
 * accepted by any specific rule.
 *
 * It is important to remember that sanitization is not just intended to prevent
 * cross-site scripting attacks, but also to prevent information from being
 * displayed in unexpected ways. For example something displaying basic
 * formatted text may not expect `<video>` tags to appear. In this case an
 * empty NodeValidatorBuilder with just [allowTextElements] might be
 * appropriate.
 */
class NodeValidatorBuilder implements NodeValidator {

  final List<NodeValidator> _validators = <NodeValidator>[];

  NodeValidatorBuilder() {
  }

  /**
   * Creates a new NodeValidatorBuilder which accepts common constructs.
   *
   * By default this will accept HTML5 elements and attributes with the default
   * [UriPolicy] and templating elements.
   *
   * Notable syntax which is filtered:
   *
   * * Only known-good HTML5 elements and attributes are allowed.
   * * All URLs must be same-origin, use [allowNavigation] and [allowImages] to
   * specify additional URI policies.
   * * Inline-styles are not allowed.
   * * Custom element tags are disallowed, use [allowCustomElement].
   * * Custom tags extensions are disallowed, use [allowTagExtension].
   * * SVG Elements are not allowed, use [allowSvg].
   *
   * For scenarios where the HTML should only contain formatted text
   * [allowTextElements] is more appropriate.
   *
   * Use [allowSvg] to allow SVG elements.
   */
  NodeValidatorBuilder.common() {
    allowHtml5();
    allowTemplating();
  }

  /**
   * Allows navigation elements- Form and Anchor tags, along with common
   * attributes.
   *
   * The UriPolicy can be used to restrict the locations the navigation elements
   * are allowed to direct to. By default this will use the default [UriPolicy].
   */
  void allowNavigation([UriPolicy uriPolicy]) {
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }
    add(new _SimpleNodeValidator.allowNavigation(uriPolicy));
  }

  /**
   * Allows image elements.
   *
   * The UriPolicy can be used to restrict the locations the images may be
   * loaded from. By default this will use the default [UriPolicy].
   */
  void allowImages([UriPolicy uriPolicy]) {
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }
    add(new _SimpleNodeValidator.allowImages(uriPolicy));
  }

  /**
   * Allow basic text elements.
   *
   * This allows a subset of HTML5 elements, specifically just these tags and
   * no attributes.
   *
   * * B
   * * BLOCKQUOTE
   * * BR
   * * EM
   * * H1
   * * H2
   * * H3
   * * H4
   * * H5
   * * H6
   * * HR
   * * I
   * * LI
   * * OL
   * * P
   * * SPAN
   * * UL
   */
  void allowTextElements() {
    add(new _SimpleNodeValidator.allowTextElements());
  }

  /**
   * Allow inline styles on elements.
   *
   * If [tagName] is not specified then this allows inline styles on all
   * elements. Otherwise tagName limits the styles to the specified elements.
   */
  void allowInlineStyles({String tagName}) {
    if (tagName == null) {
      tagName = '*';
    } else {
      tagName = tagName.toUpperCase();
    }
    add(new _SimpleNodeValidator(null, allowedAttributes: ['$tagName::style']));
  }

  /**
   * Allow common safe HTML5 elements and attributes.
   *
   * This list is based off of the Caja whitelists at:
   * https://code.google.com/p/google-caja/wiki/CajaWhitelists.
   *
   * Common things which are not allowed are script elements, style attributes
   * and any script handlers.
   */
  void allowHtml5({UriPolicy uriPolicy}) {
    add(new _Html5NodeValidator(uriPolicy: uriPolicy));
  }

  /**
   * Allow SVG elements and attributes except for known bad ones.
   */
  void allowSvg() {
    add(new _SvgNodeValidator());
  }

  /**
   * Allow custom elements with the specified tag name and specified attributes.
   *
   * This will allow the elements as custom tags (such as <x-foo></x-foo>),
   * but will not allow tag extensions. Use [allowTagExtension] to allow
   * tag extensions.
   */
  void allowCustomElement(String tagName,
      {UriPolicy uriPolicy,
      Iterable<String> attributes,
      Iterable<String> uriAttributes}) {

    var tagNameUpper = tagName.toUpperCase();
    var attrs;
    if (attributes != null) {
      attrs =
          attributes.map((name) => '$tagNameUpper::${name.toLowerCase()}');
    }
    var uriAttrs;
    if (uriAttributes != null) {
      uriAttrs =
          uriAttributes.map((name) => '$tagNameUpper::${name.toLowerCase()}');
    }
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }

    add(new _CustomElementNodeValidator(
        uriPolicy,
        [tagNameUpper],
        attrs,
        uriAttrs,
        false,
        true));
  }

  /**
   * Allow custom tag extensions with the specified type name and specified
   * attributes.
   *
   * This will allow tag extensions (such as <div is="x-foo"></div>),
   * but will not allow custom tags. Use [allowCustomElement] to allow
   * custom tags.
   */
  void allowTagExtension(String tagName, String baseName,
      {UriPolicy uriPolicy,
      Iterable<String> attributes,
      Iterable<String> uriAttributes}) {

    var baseNameUpper = baseName.toUpperCase();
    var tagNameUpper = tagName.toUpperCase();
    var attrs;
    if (attributes != null) {
      attrs =
          attributes.map((name) => '$baseNameUpper::${name.toLowerCase()}');
    }
    var uriAttrs;
    if (uriAttributes != null) {
      uriAttrs =
          uriAttributes.map((name) => '$baseNameUpper::${name.toLowerCase()}');
    }
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }

    add(new _CustomElementNodeValidator(
        uriPolicy,
        [tagNameUpper, baseNameUpper],
        attrs,
        uriAttrs,
        true,
        false));
  }

  void allowElement(String tagName, {UriPolicy uriPolicy,
    Iterable<String> attributes,
    Iterable<String> uriAttributes}) {

    allowCustomElement(tagName, uriPolicy: uriPolicy,
        attributes: attributes,
        uriAttributes: uriAttributes);
  }

  /**
   * Allow templating elements (such as <template> and template-related
   * attributes.
   *
   * This still requires other validators to allow regular attributes to be
   * bound (such as [allowHtml5]).
   */
  void allowTemplating() {
    add(new _TemplatingNodeValidator());
  }

  /**
   * Add an additional validator to the current list of validators.
   *
   * Elements and attributes will be accepted if they are accepted by any
   * validators.
   */
  void add(NodeValidator validator) {
    _validators.add(validator);
  }

  bool allowsElement(Element element) {
    return _validators.any((v) => v.allowsElement(element));
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    return _validators.any(
        (v) => v.allowsAttribute(element, attributeName, value));
  }
}

class _SimpleNodeValidator implements NodeValidator {
  final Set<String> allowedElements;
  final Set<String> allowedAttributes;
  final Set<String> allowedUriAttributes;
  final UriPolicy uriPolicy;

  factory _SimpleNodeValidator.allowNavigation(UriPolicy uriPolicy) {
    return new _SimpleNodeValidator(uriPolicy,
      allowedElements: [
        'A',
        'FORM'],
      allowedAttributes: [
        'A::accesskey',
        'A::coords',
        'A::hreflang',
        'A::name',
        'A::shape',
        'A::tabindex',
        'A::target',
        'A::type',
        'FORM::accept',
        'FORM::autocomplete',
        'FORM::enctype',
        'FORM::method',
        'FORM::name',
        'FORM::novalidate',
        'FORM::target',
      ],
      allowedUriAttributes: [
        'A::href',
        'FORM::action',
      ]);
  }

  factory _SimpleNodeValidator.allowImages(UriPolicy uriPolicy) {
    return new _SimpleNodeValidator(uriPolicy,
      allowedElements: [
        'IMG'
      ],
      allowedAttributes: [
        'IMG::align',
        'IMG::alt',
        'IMG::border',
        'IMG::height',
        'IMG::hspace',
        'IMG::ismap',
        'IMG::name',
        'IMG::usemap',
        'IMG::vspace',
        'IMG::width',
      ],
      allowedUriAttributes: [
        'IMG::src',
      ]);
  }

  factory _SimpleNodeValidator.allowTextElements() {
    return new _SimpleNodeValidator(null,
      allowedElements: [
        'B',
        'BLOCKQUOTE',
        'BR',
        'EM',
        'H1',
        'H2',
        'H3',
        'H4',
        'H5',
        'H6',
        'HR',
        'I',
        'LI',
        'OL',
        'P',
        'SPAN',
        'UL',
      ]);
  }

  /**
   * Elements must be uppercased tag names. For example `'IMG'`.
   * Attributes must be uppercased tag name followed by :: followed by
   * lowercase attribute name. For example `'IMG:src'`.
   */
  _SimpleNodeValidator(this.uriPolicy,
      {Iterable<String> allowedElements, Iterable<String> allowedAttributes,
      Iterable<String> allowedUriAttributes}):
      this.allowedElements = allowedElements != null ?
          new Set.from(allowedElements) : new Set(),
      this.allowedAttributes = allowedAttributes != null ?
          new Set.from(allowedAttributes) : new Set(),
      this.allowedUriAttributes = allowedUriAttributes != null ?
          new Set.from(allowedUriAttributes) : new Set();

  bool allowsElement(Element element) {
    return allowedElements.contains(element.tagName);
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    var tagName = element.tagName;
    if (allowedUriAttributes.contains('$tagName::$attributeName')) {
      return uriPolicy.allowsUri(value);
    } else if (allowedUriAttributes.contains('*::$attributeName')) {
      return uriPolicy.allowsUri(value);
    } else if (allowedAttributes.contains('$tagName::$attributeName')) {
      return true;
    } else if (allowedAttributes.contains('*::$attributeName')) {
      return true;
    } else if (allowedAttributes.contains('$tagName::*')) {
      return true;
    } else if (allowedAttributes.contains('*::*')) {
      return true;
    }
    return false;
  }
}

class _CustomElementNodeValidator extends _SimpleNodeValidator {
  final bool allowTypeExtension;
  final bool allowCustomTag;

  _CustomElementNodeValidator(UriPolicy uriPolicy,
      Iterable<String> allowedElements,
      Iterable<String> allowedAttributes,
      Iterable<String> allowedUriAttributes,
      bool allowTypeExtension,
      bool allowCustomTag):

      super(uriPolicy,
          allowedElements: allowedElements,
          allowedAttributes: allowedAttributes,
          allowedUriAttributes: allowedUriAttributes),
      this.allowTypeExtension = allowTypeExtension == true,
      this.allowCustomTag = allowCustomTag == true;

  bool allowsElement(Element element) {
    if (allowTypeExtension) {
      var isAttr = element.attributes['is'];
      if (isAttr != null) {
        return allowedElements.contains(isAttr.toUpperCase()) &&
          allowedElements.contains(element.tagName);
      }
    }
    return allowCustomTag && allowedElements.contains(element.tagName);
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
   if (allowsElement(element)) {
      if (allowTypeExtension && attributeName == 'is' &&
          allowedElements.contains(value.toUpperCase())) {
        return true;
      }
      return super.allowsAttribute(element, attributeName, value);
    }
    return false;
  }
}

class _TemplatingNodeValidator extends _SimpleNodeValidator {
  static const _TEMPLATE_ATTRS =
      const <String>['bind', 'if', 'ref', 'repeat', 'syntax'];

  final Set<String> _templateAttrs;

  _TemplatingNodeValidator():
      super(null,
          allowedElements: [
            'TEMPLATE'
          ],
          allowedAttributes: _TEMPLATE_ATTRS.map((attr) => 'TEMPLATE::$attr')),
      _templateAttrs = new Set<String>.from(_TEMPLATE_ATTRS) {
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (super.allowsAttribute(element, attributeName, value)) {
      return true;
    }

    if (attributeName == 'template' && value == "") {
      return true;
    }

    if (element.attributes['template'] == "" ) {
      return _templateAttrs.contains(attributeName);
    }
    return false;
  }
}


class _SvgNodeValidator implements NodeValidator {
  bool allowsElement(Element element) {
    if (element is svg.ScriptElement) {
      return false;
    }
    if (element is svg.SvgElement) {
      return true;
    }
    return false;
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (attributeName == 'is' || attributeName.startsWith('on')) {
      return false;
    }
    return allowsElement(element);
  }
}
// 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.


/**
 * Contains the set of standard values returned by HTMLDocument.getReadyState.
 */
abstract class ReadyState {
  /**
   * Indicates the document is still loading and parsing.
   */
  static const String LOADING = "loading";

  /**
   * Indicates the document is finished parsing but is still loading
   * subresources.
   */
  static const String INTERACTIVE = "interactive";

  /**
   * Indicates the document and all subresources have been loaded.
   */
  static const String COMPLETE = "complete";
}
// 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.


/**
 * A list which just wraps another list, for either intercepting list calls or
 * retyping the list (for example, from List<A> to List<B> where B extends A).
 */
class _WrappedList<E extends Node> extends ListBase<E>
    implements NodeListWrapper {
  final List _list;

  _WrappedList(this._list);

  // Iterable APIs

  Iterator<E> get iterator => new _WrappedIterator(_list.iterator);

  int get length => _list.length;

  // Collection APIs

  void add(E element) { _list.add(element); }

  bool remove(Object element) => _list.remove(element);

  void clear() { _list.clear(); }

  // List APIs

  E operator [](int index) => _list[index];

  void operator []=(int index, E value) { _list[index] = value; }

  void set length(int newLength) { _list.length = newLength; }

  void sort([int compare(E a, E b)]) { _list.sort(compare); }

  int indexOf(Object element, [int start = 0]) => _list.indexOf(element, start);

  int lastIndexOf(Object element, [int start]) => _list.lastIndexOf(element, start);

  void insert(int index, E element) => _list.insert(index, element);

  E removeAt(int index) => _list.removeAt(index);

  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
    _list.setRange(start, end, iterable, skipCount);
  }

  void removeRange(int start, int end) { _list.removeRange(start, end); }

  void replaceRange(int start, int end, Iterable<E> iterable) {
    _list.replaceRange(start, end, iterable);
  }

  void fillRange(int start, int end, [E fillValue]) {
    _list.fillRange(start, end, fillValue);
  }

  List<Node> get rawList => _list;
}

/**
 * Iterator wrapper for _WrappedList.
 */
class _WrappedIterator<E> implements Iterator<E> {
  Iterator _iterator;

  _WrappedIterator(this._iterator);

  bool moveNext() {
    return _iterator.moveNext();
  }

  E get current => _iterator.current;
}
// 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.


class _HttpRequestUtils {

  // Helper for factory HttpRequest.get
  static HttpRequest get(String url,
                            onComplete(HttpRequest request),
                            bool withCredentials) {
    final request = new HttpRequest();
    request.open('GET', url, async: true);

    request.withCredentials = withCredentials;

    request.onReadyStateChange.listen((e) {
      if (request.readyState == HttpRequest.DONE) {
        onComplete(request);
      }
    });

    request.send();

    return request;
  }
}
// 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.


// Iterator for arrays with fixed size.
class FixedSizeListIterator<T> implements Iterator<T> {
  final List<T> _array;
  final int _length;  // Cache array length for faster access.
  int _position;
  T _current;
  
  FixedSizeListIterator(List<T> array)
      : _array = array,
        _position = -1,
        _length = array.length;

  bool moveNext() {
    int nextPosition = _position + 1;
    if (nextPosition < _length) {
      _current = _array[nextPosition];
      _position = nextPosition;
      return true;
    }
    _current = null;
    _position = _length;
    return false;
  }

  T get current => _current;
}

// Iterator for arrays with variable size.
class _VariableSizeListIterator<T> implements Iterator<T> {
  final List<T> _array;
  int _position;
  T _current;

  _VariableSizeListIterator(List<T> array)
      : _array = array,
        _position = -1;

  bool moveNext() {
    int nextPosition = _position + 1;
    if (nextPosition < _array.length) {
      _current = _array[nextPosition];
      _position = nextPosition;
      return true;
    }
    _current = null;
    _position = _array.length;
    return false;
  }

  T get current => _current;
}
// 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.


// Conversions for Window.  These check if the window is the local
// window, and if it's not, wraps or unwraps it with a secure wrapper.
// We need to test for EventTarget here as well as it's a base type.
// We omit an unwrapper for Window as no methods take a non-local
// window as a parameter.


WindowBase _convertNativeToDart_Window(win) {
  if (win == null) return null;
  return _DOMWindowCrossFrame._createSafe(win);
}

EventTarget _convertNativeToDart_EventTarget(e) {
  if (e == null) {
    return null;
  }
  // Assume it's a Window if it contains the setInterval property.  It may be
  // from a different frame - without a patched prototype - so we cannot
  // rely on Dart type checking.
  if (JS('bool', r'"setInterval" in #', e)) {
    var window = _DOMWindowCrossFrame._createSafe(e);
    // If it's a native window.
    if (window is EventTarget) {
      return window;
    }
    return null;
  }
  else
    return e;
}

EventTarget _convertDartToNative_EventTarget(e) {
  if (e is _DOMWindowCrossFrame) {
    return e._window;
  } else {
    return e;
  }
}

_convertNativeToDart_XHR_Response(o) {
  if (o is Document) {
    return o;
  }
  return convertNativeToDart_SerializedScriptValue(o);
}
// 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.


_callConstructor(constructor, interceptor) {
  return (receiver) {
    setNativeSubclassDispatchRecord(receiver, interceptor);

    // Mirrors uses the constructor property to cache lookups, so we need it to
    // be set correctly, including on IE where it is not automatically picked
    // up from the __proto__.
    JS('', '#.constructor = #.__proto__.constructor', receiver, receiver);
    return JS('', '#(#)', constructor, receiver);
  };
}

_callAttached(receiver) {
  return receiver.attached();
}

_callDetached(receiver) {
  return receiver.detached();
}
 _callAttributeChanged(receiver, name, oldValue, newValue) {
  return receiver.attributeChanged(name, oldValue, newValue);
}

_makeCallbackMethod(callback) {
  return JS('',
      '''((function(invokeCallback) {
             return function() {
               return invokeCallback(this);
             };
          })(#))''',
      convertDartClosureToJS(callback, 1));
}

_makeCallbackMethod3(callback) {
  return JS('',
      '''((function(invokeCallback) {
             return function(arg1, arg2, arg3) {
               return invokeCallback(this, arg1, arg2, arg3);
             };
          })(#))''',
      convertDartClosureToJS(callback, 4));
}

void _registerCustomElement(context, document, String tag, Type type,
    String extendsTagName) {
  // Function follows the same pattern as the following JavaScript code for
  // registering a custom element.
  //
  //    var proto = Object.create(HTMLElement.prototype, {
  //        createdCallback: {
  //          value: function() {
  //            window.console.log('here');
  //          }
  //        }
  //    });
  //    document.registerElement('x-foo', { prototype: proto });
  //    ...
  //    var e = document.createElement('x-foo');

  var interceptorClass = findInterceptorConstructorForType(type);
  if (interceptorClass == null) {
    throw new ArgumentError(type);
  }

  var interceptor = JS('=Object', '#.prototype', interceptorClass);

  var constructor = findConstructorForNativeSubclassType(type, 'created');
  if (constructor == null) {
    throw new ArgumentError("$type has no constructor called 'created'");
  }

  // Workaround for 13190- use an article element to ensure that HTMLElement's
  // interceptor is resolved correctly.
  getNativeInterceptor(new Element.tag('article'));

  String baseClassName = findDispatchTagForInterceptorClass(interceptorClass);
  if (baseClassName == null) {
    throw new ArgumentError(type);
  }

  if (extendsTagName == null) {
    if (baseClassName != 'HTMLElement') {
      throw new UnsupportedError('Class must provide extendsTag if base '
          'native class is not HtmlElement');
    }
  } else {
    if (!JS('bool', '(#.createElement(#) instanceof window[#])',
        document, extendsTagName, baseClassName)) {
      throw new UnsupportedError('extendsTag does not match base native class');
    }
  }

  var baseConstructor = JS('=Object', '#[#]', context, baseClassName);

  var properties = JS('=Object', '{}');

  JS('void', '#.createdCallback = #', properties,
      JS('=Object', '{value: #}',
          _makeCallbackMethod(_callConstructor(constructor, interceptor))));
  JS('void', '#.attachedCallback = #', properties,
      JS('=Object', '{value: #}', _makeCallbackMethod(_callAttached)));
  JS('void', '#.detachedCallback = #', properties,
      JS('=Object', '{value: #}', _makeCallbackMethod(_callDetached)));
  JS('void', '#.attributeChangedCallback = #', properties,
      JS('=Object', '{value: #}', _makeCallbackMethod3(_callAttributeChanged)));

  var baseProto = JS('=Object', '#.prototype', baseConstructor);
  var proto = JS('=Object', 'Object.create(#, #)', baseProto, properties);

  setNativeSubclassDispatchRecord(proto, interceptor);

  var options = JS('=Object', '{prototype: #}', proto);

  if (extendsTagName != null) {
    JS('=Object', '#.extends = #', options, extendsTagName);
  }

  JS('void', '#.registerElement(#, #)', document, tag, options);
}

//// Called by Element.created to do validation & initialization.
void _initializeCustomElement(Element e) {
  // TODO(blois): Add validation that this is only in response to an upgrade.
}

/// Dart2JS implementation of ElementUpgrader
class _JSElementUpgrader implements ElementUpgrader {
  var _interceptor;
  var _constructor;
  var _nativeType;

  _JSElementUpgrader(Document document, Type type, String extendsTag) {
    var interceptorClass = findInterceptorConstructorForType(type);
    if (interceptorClass == null) {
      throw new ArgumentError(type);
    }

    _constructor = findConstructorForNativeSubclassType(type, 'created');
    if (_constructor == null) {
      throw new ArgumentError("$type has no constructor called 'created'");
    }

    // Workaround for 13190- use an article element to ensure that HTMLElement's
    // interceptor is resolved correctly.
    getNativeInterceptor(new Element.tag('article'));

    var baseClassName = findDispatchTagForInterceptorClass(interceptorClass);
    if (baseClassName == null) {
      throw new ArgumentError(type);
    }

    if (extendsTag == null) {
      if (baseClassName != 'HTMLElement') {
        throw new UnsupportedError('Class must provide extendsTag if base '
            'native class is not HtmlElement');
      }
      _nativeType = HtmlElement;
    } else {
      var element = document.createElement(extendsTag);
      if (!JS('bool', '(# instanceof window[#])',
          element, baseClassName)) {
        throw new UnsupportedError(
            'extendsTag does not match base native class');
      }
      _nativeType = element.runtimeType;
    }

    _interceptor = JS('=Object', '#.prototype', interceptorClass);
  }

  Element upgrade(Element element) {
    // Only exact type matches are supported- cannot be a subclass.
    if (element.runtimeType != _nativeType) {
      throw new ArgumentError('element is not subclass of $_nativeType');
    }

    setNativeSubclassDispatchRecord(element, _interceptor);
    JS('', '#(#)', _constructor, element);
    return element;
  }
}
// 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.


// TODO(vsm): Unify with Dartium version.
class _DOMWindowCrossFrame implements WindowBase {
  // Private window.  Note, this is a window in another frame, so it
  // cannot be typed as "Window" as its prototype is not patched
  // properly.  Its fields and methods can only be accessed via JavaScript.
  final _window;

  // Fields.
  HistoryBase get history =>
    _HistoryCrossFrame._createSafe(JS('HistoryBase', '#.history', _window));
  LocationBase get location =>
    _LocationCrossFrame._createSafe(JS('LocationBase', '#.location', _window));

  // TODO(vsm): Add frames to navigate subframes.  See 2312.

  bool get closed => JS('bool', '#.closed', _window);

  WindowBase get opener => _createSafe(JS('WindowBase', '#.opener', _window));

  WindowBase get parent => _createSafe(JS('WindowBase', '#.parent', _window));

  WindowBase get top => _createSafe(JS('WindowBase', '#.top', _window));

  // Methods.
  void close() => JS('void', '#.close()', _window);

  void postMessage(var message, String targetOrigin, [List messagePorts = null]) {
    if (messagePorts == null) {
      JS('void', '#.postMessage(#,#)', _window, message, targetOrigin);
    } else {
      JS('void', '#.postMessage(#,#,#)', _window, message, targetOrigin, messagePorts);
    }
  }

  // Implementation support.
  _DOMWindowCrossFrame(this._window);

  static WindowBase _createSafe(w) {
    if (identical(w, window)) {
      return w;
    } else {
      // TODO(vsm): Cache or implement equality.
      return new _DOMWindowCrossFrame(w);
    }
  }

  // TODO(efortuna): Remove this method. dartbug.com/16814
  Events get on => throw new UnsupportedError(
    'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  void addEventListener(String type, EventListener listener, [bool useCapture])
      => throw new UnsupportedError(
        'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  bool dispatchEvent(Event event) => throw new UnsupportedError(
    'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  void removeEventListener(String type, EventListener listener,
      [bool useCapture]) => throw new UnsupportedError(
          'You can only attach EventListeners to your own window.');
}

class _LocationCrossFrame implements LocationBase {
  // Private location.  Note, this is a location object in another frame, so it
  // cannot be typed as "Location" as its prototype is not patched
  // properly.  Its fields and methods can only be accessed via JavaScript.
  var _location;

  void set href(String val) => _setHref(_location, val);
  static void _setHref(location, val) {
    JS('void', '#.href = #', location, val);
  }

  // Implementation support.
  _LocationCrossFrame(this._location);

  static LocationBase _createSafe(location) {
    if (identical(location, window.location)) {
      return location;
    } else {
      // TODO(vsm): Cache or implement equality.
      return new _LocationCrossFrame(location);
    }
  }
}

class _HistoryCrossFrame implements HistoryBase {
  // Private history.  Note, this is a history object in another frame, so it
  // cannot be typed as "History" as its prototype is not patched
  // properly.  Its fields and methods can only be accessed via JavaScript.
  var _history;

  void back() => JS('void', '#.back()', _history);

  void forward() => JS('void', '#.forward()', _history);

  void go(int distance) => JS('void', '#.go(#)', _history, distance);

  // Implementation support.
  _HistoryCrossFrame(this._history);

  static HistoryBase _createSafe(h) {
    if (identical(h, window.history)) {
      return h;
    } else {
      // TODO(vsm): Cache or implement equality.
      return new _HistoryCrossFrame(h);
    }
  }
}
/**
 * A custom KeyboardEvent that attempts to eliminate cross-browser
 * inconsistencies, and also provide both keyCode and charCode information
 * for all key events (when such information can be determined).
 *
 * KeyEvent tries to provide a higher level, more polished keyboard event
 * information on top of the "raw" [KeyboardEvent].
 *
 * The mechanics of using KeyEvents is a little different from the underlying
 * [KeyboardEvent]. To use KeyEvents, you need to create a stream and then add
 * KeyEvents to the stream, rather than using the [EventTarget.dispatchEvent].
 * Here's an example usage:
 *
 *     // Initialize a stream for the KeyEvents:
 *     var stream = KeyEvent.keyPressEvent.forTarget(document.body);
 *     // Start listening to the stream of KeyEvents.
 *     stream.listen((keyEvent) =>
 *         window.console.log('KeyPress event detected ${keyEvent.charCode}'));
 *     ...
 *     // Add a new KeyEvent of someone pressing the 'A' key to the stream so
 *     // listeners can know a KeyEvent happened.
 *     stream.add(new KeyEvent('keypress', keyCode: 65, charCode: 97));
 *
 * This class is very much a work in progress, and we'd love to get information
 * on how we can make this class work with as many international keyboards as
 * possible. Bugs welcome!
 */
@Experimental()
class KeyEvent extends _WrappedEvent implements KeyboardEvent {
  /** The parent KeyboardEvent that this KeyEvent is wrapping and "fixing". */
  KeyboardEvent _parent;

  /** The "fixed" value of whether the alt key is being pressed. */
  bool _shadowAltKey;

  /** Caculated value of what the estimated charCode is for this event. */
  int _shadowCharCode;

  /** Caculated value of what the estimated keyCode is for this event. */
  int _shadowKeyCode;

  /** Caculated value of what the estimated keyCode is for this event. */
  int get keyCode => _shadowKeyCode;

  /** Caculated value of what the estimated charCode is for this event. */
  int get charCode => this.type == 'keypress' ? _shadowCharCode : 0;

  /** Caculated value of whether the alt key is pressed is for this event. */
  bool get altKey => _shadowAltKey;

  /** Caculated value of what the estimated keyCode is for this event. */
  int get which => keyCode;

  /** Accessor to the underlying keyCode value is the parent event. */
  int get _realKeyCode => JS('int', '#.keyCode', _parent);

  /** Accessor to the underlying charCode value is the parent event. */
  int get _realCharCode => JS('int', '#.charCode', _parent);

  /** Accessor to the underlying altKey value is the parent event. */
  bool get _realAltKey => JS('bool', '#.altKey', _parent);

  /** Shadows on top of the parent's currentTarget. */
  EventTarget _currentTarget;

  /**
   * The value we want to use for this object's dispatch. Created here so it is
   * only invoked once.
   */
  static final _keyboardEventDispatchRecord = _makeRecord();

  /** Helper to statically create the dispatch record. */
  static _makeRecord() {
    var interceptor = JS_INTERCEPTOR_CONSTANT(KeyboardEvent);
    return makeLeafDispatchRecord(interceptor);
  }

  /** Construct a KeyEvent with [parent] as the event we're emulating. */
  KeyEvent.wrap(KeyboardEvent parent): super(parent) {
    _parent = parent;
    _shadowAltKey = _realAltKey;
    _shadowCharCode = _realCharCode;
    _shadowKeyCode = _realKeyCode;
    _currentTarget = _parent.currentTarget;
  }

  /** Programmatically create a new KeyEvent (and KeyboardEvent). */
  factory KeyEvent(String type,
      {Window view, bool canBubble: true, bool cancelable: true, int keyCode: 0,
      int charCode: 0, int keyLocation: 1, bool ctrlKey: false,
      bool altKey: false, bool shiftKey: false, bool metaKey: false,
      bool altGraphKey: false, EventTarget currentTarget}) {
    if (view == null) {
      view = window;
    }

    var eventObj;
    // In these two branches we create an underlying native KeyboardEvent, but
    // we set it with our specified values. Because we are doing custom setting
    // of certain values (charCode/keyCode, etc) only in this class (as opposed
    // to KeyboardEvent) and the way we set these custom values depends on the
    // type of underlying JS object, we do all the contruction for the
    // underlying KeyboardEvent here.
    if (canUseDispatchEvent) {
      // Currently works in everything but Internet Explorer.
      eventObj = new Event.eventType('Event', type,
          canBubble: canBubble, cancelable: cancelable);

      JS('void', '#.keyCode = #', eventObj, keyCode);
      JS('void', '#.which = #', eventObj, keyCode);
      JS('void', '#.charCode = #', eventObj, charCode);

      JS('void', '#.keyLocation = #', eventObj, keyLocation);
      JS('void', '#.ctrlKey = #', eventObj, ctrlKey);
      JS('void', '#.altKey = #', eventObj, altKey);
      JS('void', '#.shiftKey = #', eventObj, shiftKey);
      JS('void', '#.metaKey = #', eventObj, metaKey);
      JS('void', '#.altGraphKey = #', eventObj, altGraphKey);
    } else {
      // Currently this works on everything but Safari. Safari throws an
      // "Attempting to change access mechanism for an unconfigurable property"
      // TypeError when trying to do the Object.defineProperty hack, so we avoid
      // this branch if possible.
      // Also, if we want this branch to work in FF, we also need to modify
      // _initKeyboardEvent to also take charCode and keyCode values to
      // initialize initKeyEvent.

      eventObj = new Event.eventType('KeyboardEvent', type,
          canBubble: canBubble, cancelable: cancelable);

      // Chromium Hack
      JS('void', "Object.defineProperty(#, 'keyCode', {"
          "  get : function() { return this.keyCodeVal; } })",  eventObj);
      JS('void', "Object.defineProperty(#, 'which', {"
          "  get : function() { return this.keyCodeVal; } })",  eventObj);
      JS('void', "Object.defineProperty(#, 'charCode', {"
          "  get : function() { return this.charCodeVal; } })",  eventObj);

      var keyIdentifier = _convertToHexString(charCode, keyCode);
      eventObj._initKeyboardEvent(type, canBubble, cancelable, view,
          keyIdentifier, keyLocation, ctrlKey, altKey, shiftKey, metaKey,
          altGraphKey);
      JS('void', '#.keyCodeVal = #', eventObj, keyCode);
      JS('void', '#.charCodeVal = #', eventObj, charCode);
    }
    // Tell dart2js that it smells like a KeyboardEvent!
    setDispatchProperty(eventObj, _keyboardEventDispatchRecord);

    var keyEvent = new KeyEvent.wrap(eventObj);
    if (keyEvent._currentTarget == null) {
      keyEvent._currentTarget = currentTarget == null ? window : currentTarget;
    }
    return keyEvent;
  }

  // Currently known to work on all browsers but IE.
  static bool get canUseDispatchEvent =>
      JS('bool',
         '(typeof document.body.dispatchEvent == "function")'
         '&& document.body.dispatchEvent.length > 0');

  /** The currently registered target for this event. */
  EventTarget get currentTarget => _currentTarget;

  // This is an experimental method to be sure.
  static String _convertToHexString(int charCode, int keyCode) {
    if (charCode != -1) {
      var hex = charCode.toRadixString(16); // Convert to hexadecimal.
      StringBuffer sb = new StringBuffer('U+');
      for (int i = 0; i < 4 - hex.length; i++) sb.write('0');
      sb.write(hex);
      return sb.toString();
    } else {
      return KeyCode._convertKeyCodeToKeyName(keyCode);
    }
  }

  // TODO(efortuna): If KeyEvent is sufficiently successful that we want to make
  // it the default keyboard event handling, move these methods over to Element.
  /** Accessor to provide a stream of KeyEvents on the desired target. */
  static EventStreamProvider<KeyEvent> keyDownEvent =
      new _KeyboardEventHandler('keydown');
  /** Accessor to provide a stream of KeyEvents on the desired target. */
  static EventStreamProvider<KeyEvent> keyUpEvent =
      new _KeyboardEventHandler('keyup');
  /** Accessor to provide a stream of KeyEvents on the desired target. */
  static EventStreamProvider<KeyEvent> keyPressEvent =
      new _KeyboardEventHandler('keypress');

  /** True if the altGraphKey is pressed during this event. */
  bool get altGraphKey => _parent.altGraphKey;
  /** Accessor to the clipboardData available for this event. */
  DataTransfer get clipboardData => _parent.clipboardData;
  /** True if the ctrl key is pressed during this event. */
  bool get ctrlKey => _parent.ctrlKey;
  int get detail => _parent.detail;
  /**
   * Accessor to the part of the keyboard that the key was pressed from (one of
   * KeyLocation.STANDARD, KeyLocation.RIGHT, KeyLocation.LEFT,
   * KeyLocation.NUMPAD, KeyLocation.MOBILE, KeyLocation.JOYSTICK).
   */
  int get keyLocation => _parent.keyLocation;
  Point get layer => _parent.layer;
  /** True if the Meta (or Mac command) key is pressed during this event. */
  bool get metaKey => _parent.metaKey;
  Point get page => _parent.page;
  /** True if the shift key was pressed during this event. */
  bool get shiftKey => _parent.shiftKey;
  Window get view => _parent.view;
  void _initUIEvent(String type, bool canBubble, bool cancelable,
      Window view, int detail) {
    throw new UnsupportedError("Cannot initialize a UI Event from a KeyEvent.");
  }
  String get _shadowKeyIdentifier => JS('String', '#.keyIdentifier', _parent);

  int get _charCode => charCode;
  int get _keyCode => keyCode;
  String get _keyIdentifier {
    throw new UnsupportedError("keyIdentifier is unsupported.");
  }
  void _initKeyboardEvent(String type, bool canBubble, bool cancelable,
      Window view, String keyIdentifier, int keyLocation, bool ctrlKey,
      bool altKey, bool shiftKey, bool metaKey,
      bool altGraphKey) {
    throw new UnsupportedError(
        "Cannot initialize a KeyboardEvent from a KeyEvent.");
  }
  int get _layerX => throw new UnsupportedError('Not applicable to KeyEvent');
  int get _layerY => throw new UnsupportedError('Not applicable to KeyEvent');
  int get _pageX => throw new UnsupportedError('Not applicable to KeyEvent');
  int get _pageY => throw new UnsupportedError('Not applicable to KeyEvent');
  @Experimental() // untriaged
  bool getModifierState(String keyArgument) => throw new UnimplementedError();
  @Experimental() // untriaged
  int get location => throw new UnimplementedError();
  @Experimental() // untriaged
  bool get repeat => throw new UnimplementedError();
  dynamic get _get_view => throw new UnimplementedError();
}
// 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.


class Platform {
  /**
   * Returns true if dart:typed_data types are supported on this
   * browser.  If false, using these types will generate a runtime
   * error.
   */
  static final supportsTypedData = JS('bool', '!!(window.ArrayBuffer)');

  /**
   * Returns true if SIMD types in dart:typed_data types are supported
   * on this browser.  If false, using these types will generate a runtime
   * error.
   */
  static final supportsSimd = false;
}
// 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.


/**
 * Helper class to implement custom events which wrap DOM events.
 */
class _WrappedEvent implements Event {
  final Event wrapped;

  /** The CSS selector involved with event delegation. */
  String _selector;

  _WrappedEvent(this.wrapped);

  bool get bubbles => wrapped.bubbles;

  bool get cancelable => wrapped.cancelable;

  DataTransfer get clipboardData => wrapped.clipboardData;

  EventTarget get currentTarget => wrapped.currentTarget;

  bool get defaultPrevented => wrapped.defaultPrevented;

  int get eventPhase => wrapped.eventPhase;

  EventTarget get target => wrapped.target;

  int get timeStamp => wrapped.timeStamp;

  String get type => wrapped.type;

  void _initEvent(String eventTypeArg, bool canBubbleArg,
      bool cancelableArg) {
    throw new UnsupportedError(
        'Cannot initialize this Event.');
  }

  void preventDefault() {
    wrapped.preventDefault();
  }

  void stopImmediatePropagation() {
    wrapped.stopImmediatePropagation();
  }

  void stopPropagation() {
    wrapped.stopPropagation();
  }

  /**
   * A pointer to the element whose CSS selector matched within which an event
   * was fired. If this Event was not associated with any Event delegation,
   * accessing this value will throw an [UnsupportedError].
   */
  Element get matchingTarget {
    if (_selector == null) {
      throw new UnsupportedError('Cannot call matchingTarget if this Event did'
          ' not arise as a result of event delegation.');
    }
    var currentTarget = this.currentTarget;
    var target = this.target;
    var matchedTarget;
    do {
      if (target.matches(_selector)) return target;
      target = target.parent;
    } while (target != null && target != currentTarget.parent);
    throw new StateError('No selector matched for populating matchedTarget.');
  }

  /**
   * This event's path, taking into account shadow DOM.
   *
   * ## Other resources
   *
   * * [Shadow DOM extensions to Event]
   * (http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event) from
   * W3C.
   */
  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#extensions-to-event
  @Experimental()
  List<Node> get path => wrapped.path;

  dynamic get _get_currentTarget => wrapped._get_currentTarget;

  dynamic get _get_target => wrapped._get_target;
}
// 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.


_wrapZone(callback(arg)) {
  // For performance reasons avoid wrapping if we are in the root zone.
  if (Zone.current == Zone.ROOT) return callback;
  if (callback == null) return null;
  return Zone.current.bindUnaryCallback(callback, runGuarded: true);
}

_wrapBinaryZone(callback(arg1, arg2)) {
  if (Zone.current == Zone.ROOT) return callback;
  if (callback == null) return null;
  return Zone.current.bindBinaryCallback(callback, runGuarded: true);
}

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

/**
 * Finds the first descendant element of this document that matches the
 * specified group of selectors.
 *
 * Unless your webpage contains multiple documents, the top-level
 * [querySelector]
 * 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 element1 = document.querySelector('.className');
 *     var element2 = document.querySelector('#id');
 *
 * For details about CSS selector syntax, see the
 * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
 */
Element querySelector(String selectors) => document.querySelector(selectors);

/**
 * 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 querySelectorAll(String selectors) => document.querySelectorAll(selectors);

/// A utility for changing the Dart wrapper type for elements.
abstract class ElementUpgrader {
  /// Upgrade the specified element to be of the Dart type this was created for.
  ///
  /// After upgrading the element passed in is invalid and the returned value
  /// should be used instead.
  Element upgrade(Element element);
}
// 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.



/**
 * Interface used to validate that only accepted elements and attributes are
 * allowed while parsing HTML strings into DOM nodes.
 *
 * In general, customization of validation behavior should be done via the
 * [NodeValidatorBuilder] class to mitigate the chances of incorrectly
 * implementing validation rules.
 */
abstract class NodeValidator {

  /**
   * Construct a default NodeValidator which only accepts whitelisted HTML5
   * elements and attributes.
   *
   * If a uriPolicy is not specified then the default uriPolicy will be used.
   */
  factory NodeValidator({UriPolicy uriPolicy}) =>
      new _Html5NodeValidator(uriPolicy: uriPolicy);

  factory NodeValidator.throws(NodeValidator base) =>
      new _ThrowsNodeValidator(base);

  /**
   * Returns true if the tagName is an accepted type.
   */
  bool allowsElement(Element element);

  /**
   * Returns true if the attribute is allowed.
   *
   * The attributeName parameter will always be in lowercase.
   *
   * See [allowsElement] for format of tagName.
   */
  bool allowsAttribute(Element element, String attributeName, String value);
}

/**
 * Performs sanitization of a node tree after construction to ensure that it
 * does not contain any disallowed elements or attributes.
 *
 * In general custom implementations of this class should not be necessary and
 * all validation customization should be done in custom NodeValidators, but
 * custom implementations of this class can be created to perform more complex
 * tree sanitization.
 */
abstract class NodeTreeSanitizer {

  /**
   * Constructs a default tree sanitizer which will remove all elements and
   * attributes which are not allowed by the provided validator.
   */
  factory NodeTreeSanitizer(NodeValidator validator) =>
      new _ValidatingTreeSanitizer(validator);

  /**
   * Called with the root of the tree which is to be sanitized.
   *
   * This method needs to walk the entire tree and either remove elements and
   * attributes which are not recognized as safe or throw an exception which
   * will mark the entire tree as unsafe.
   */
  void sanitizeTree(Node node);
}

/**
 * Defines the policy for what types of uris are allowed for particular
 * attribute values.
 *
 * This can be used to provide custom rules such as allowing all http:// URIs
 * for image attributes but only same-origin URIs for anchor tags.
 */
abstract class UriPolicy {
  /**
   * Constructs the default UriPolicy which is to only allow Uris to the same
   * origin as the application was launched from.
   *
   * This will block all ftp: mailto: URIs. It will also block accessing
   * https://example.com if the app is running from http://example.com.
   */
  factory UriPolicy() => new _SameOriginUriPolicy();

  /**
   * Checks if the uri is allowed on the specified attribute.
   *
   * The uri provided may or may not be a relative path.
   */
  bool allowsUri(String uri);
}

/**
 * Allows URIs to the same origin as the current application was loaded from
 * (such as https://example.com:80).
 */
class _SameOriginUriPolicy implements UriPolicy {
  final AnchorElement _hiddenAnchor = new AnchorElement();
  final Location _loc = window.location;

  bool allowsUri(String uri) {
    _hiddenAnchor.href = uri;
    // IE leaves an empty hostname for same-origin URIs.
    return (_hiddenAnchor.hostname == _loc.hostname &&
        _hiddenAnchor.port == _loc.port &&
        _hiddenAnchor.protocol == _loc.protocol) ||
        (_hiddenAnchor.hostname == '' &&
        _hiddenAnchor.port == '' &&
        _hiddenAnchor.protocol == ':');
  }
}


class _ThrowsNodeValidator implements NodeValidator {
  final NodeValidator validator;

  _ThrowsNodeValidator(this.validator) {}

  bool allowsElement(Element element) {
    if (!validator.allowsElement(element)) {
      throw new ArgumentError(element.tagName);
    }
    return true;
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (!validator.allowsAttribute(element, attributeName, value)) {
      throw new ArgumentError('${element.tagName}[$attributeName="$value"]');
    }
  }
}


/**
 * Standard tree sanitizer which validates a node tree against the provided
 * validator and removes any nodes or attributes which are not allowed.
 */
class _ValidatingTreeSanitizer implements NodeTreeSanitizer {
  NodeValidator validator;
  _ValidatingTreeSanitizer(this.validator) {}

  void sanitizeTree(Node node) {
    void walk(Node node) {
      sanitizeNode(node);

      var child = node.lastChild;
      while (child != null) {
        // Child may be removed during the walk.
        var nextChild = child.previousNode;
        walk(child);
        child = nextChild;
      }
    }
    walk(node);
  }

  void sanitizeNode(Node node) {
    switch (node.nodeType) {
      case Node.ELEMENT_NODE:
        Element element = node;
        var attrs = element.attributes;
        if (!validator.allowsElement(element)) {
          window.console.warn(
              'Removing disallowed element <${element.tagName}>');
          element.remove();
          break;
        }

        var isAttr = attrs['is'];
        if (isAttr != null) {
          if (!validator.allowsAttribute(element, 'is', isAttr)) {
            window.console.warn('Removing disallowed type extension '
                '<${element.tagName} is="$isAttr">');
            element.remove();
            break;
          }
        }

        // TODO(blois): Need to be able to get all attributes, irrespective of
        // XMLNS.
        var keys = attrs.keys.toList();
        for (var i = attrs.length - 1; i >= 0; --i) {
          var name = keys[i];
          if (!validator.allowsAttribute(element, name.toLowerCase(),
              attrs[name])) {
            window.console.warn('Removing disallowed attribute '
                '<${element.tagName} $name="${attrs[name]}">');
            attrs.remove(name);
          }
        }

        if (element is TemplateElement) {
          TemplateElement template = element;
          sanitizeTree(template.content);
        }
        break;
      case Node.COMMENT_NODE:
      case Node.DOCUMENT_FRAGMENT_NODE:
      case Node.TEXT_NODE:
      case Node.CDATA_SECTION_NODE:
        break;
      default:
        node.remove();
    }
  }
}
