/**
 * 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;
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_gl' show RenderingContext;
import 'dart:web_sql';
import 'dart:_isolate_helper' show IsolateNatives;
import 'dart:_foreign_helper' show JS, JS_INTERCEPTOR_CONSTANT, JS_CONST;
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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, Native, Returns, ForceInline,
    findDispatchTagForInterceptorClass, setNativeSubclassDispatchRecord,
    makeLeafDispatchRecord;
import 'dart:_interceptors' show
    Interceptor, JSExtendableArray, JSUInt31,
    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.
@Native("HTMLElement")
class HtmlElement extends Element {
  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.
@Native("EntryArray")
abstract class _EntryArray implements List<Entry> {}

/**
 * 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();
}

/// Dartium functions that are a NOOP in dart2js.
unwrap_jso(dartClass_instance) => dartClass_instance;
wrap_jso(jsObject) => jsObject;
createCustomUpgrader(Type customElementClass, $this) => $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('AbstractWorker')
abstract class AbstractWorker extends Interceptor implements EventTarget {
  // 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) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All 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')
@Native("HTMLAnchorElement")
class AnchorElement extends HtmlElement implements UrlUtils {
  // 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.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String integrity;

  @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() => JS('String', 'String(#)', 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('Animation')
@Experimental() // untriaged
@Native("Animation")
class Animation extends AnimationNode {
  // 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 ((keyframes is List<Map> || keyframes == null) && (target is Element || target == null) && timingInput == null) {
      return Animation._create_1(target, keyframes);
    }
    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 ((timingInput is Map || timingInput == null) && (keyframes is List<Map> || keyframes == null) && (target is Element || target == null)) {
      var timingInput_1 = convertDartToNative_Dictionary(timingInput);
      return Animation._create_3(target, keyframes, timingInput_1);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static Animation _create_1(target, keyframes) => JS('Animation', 'new Animation(#,#)', target, keyframes);
  static Animation _create_2(target, keyframes, timingInput) => JS('Animation', 'new Animation(#,#,#)', target, keyframes, timingInput);
  static Animation _create_3(target, keyframes, timingInput) => JS('Animation', 'new Animation(#,#,#)', target, keyframes, timingInput);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('AnimationEffect')
@Experimental() // untriaged
@Native("AnimationEffect")
class AnimationEffect extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory AnimationEffect._() { 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('WebKitAnimationEvent')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
@Native("WebKitAnimationEvent")
class AnimationEvent extends Event {
  // 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('AnimationNode')
@Experimental() // untriaged
@Native("AnimationNode")
class AnimationNode extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory AnimationNode._() { throw new UnsupportedError("Not supported"); }

  @DomName('AnimationNode.activeDuration')
  @DocsEditable()
  @Experimental() // untriaged
  final double activeDuration;

  @DomName('AnimationNode.currentIteration')
  @DocsEditable()
  @Experimental() // untriaged
  final int currentIteration;

  @DomName('AnimationNode.duration')
  @DocsEditable()
  @Experimental() // untriaged
  final double duration;

  @DomName('AnimationNode.endTime')
  @DocsEditable()
  @Experimental() // untriaged
  final double endTime;

  @DomName('AnimationNode.localTime')
  @DocsEditable()
  @Experimental() // untriaged
  final double localTime;

  @DomName('AnimationNode.player')
  @DocsEditable()
  @Experimental() // untriaged
  final AnimationPlayer player;

  @DomName('AnimationNode.startTime')
  @DocsEditable()
  @Experimental() // untriaged
  final double startTime;

  @DomName('AnimationNode.timing')
  @DocsEditable()
  @Experimental() // untriaged
  final Timing timing;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

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

  @DomName('AnimationPlayer.currentTime')
  @DocsEditable()
  @Experimental() // untriaged
  num currentTime;

  @DomName('AnimationPlayer.playState')
  @DocsEditable()
  @Experimental() // untriaged
  final String playState;

  @DomName('AnimationPlayer.playbackRate')
  @DocsEditable()
  @Experimental() // untriaged
  num playbackRate;

  @DomName('AnimationPlayer.source')
  @DocsEditable()
  @Experimental() // untriaged
  AnimationNode source;

  @DomName('AnimationPlayer.startTime')
  @DocsEditable()
  @Experimental() // untriaged
  num startTime;

  @DomName('AnimationPlayer.cancel')
  @DocsEditable()
  @Experimental() // untriaged
  void cancel() native;

  @DomName('AnimationPlayer.finish')
  @DocsEditable()
  @Experimental() // untriaged
  void finish() native;

  @DomName('AnimationPlayer.pause')
  @DocsEditable()
  @Experimental() // untriaged
  void pause() native;

  @DomName('AnimationPlayer.play')
  @DocsEditable()
  @Experimental() // untriaged
  void play() native;

  @DomName('AnimationPlayer.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('AnimationPlayerEvent')
@Experimental() // untriaged
@Native("AnimationPlayerEvent")
class AnimationPlayerEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory AnimationPlayerEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('AnimationPlayerEvent.currentTime')
  @DocsEditable()
  @Experimental() // untriaged
  final double currentTime;

  @DomName('AnimationPlayerEvent.timelineTime')
  @DocsEditable()
  @Experimental() // untriaged
  final double timelineTime;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

  @DomName('AnimationTimeline.currentTime')
  @DocsEditable()
  @Experimental() // untriaged
  final double currentTime;

  @DomName('AnimationTimeline.getAnimationPlayers')
  @DocsEditable()
  @Experimental() // untriaged
  List<AnimationPlayer> getAnimationPlayers() native;

  @DomName('AnimationTimeline.play')
  @DocsEditable()
  @Experimental() // untriaged
  AnimationPlayer play(AnimationNode 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.


@DocsEditable()
/**
 * ApplicationCache is accessed via [Window.applicationCache].
 */
@DomName('ApplicationCache')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.OPERA)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
@Native("ApplicationCache,DOMApplicationCache,OfflineResourceList")
class ApplicationCache extends EventTarget {
  // 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()
@DomName('ApplicationCacheErrorEvent')
@Experimental() // untriaged
@Native("ApplicationCacheErrorEvent")
class ApplicationCacheErrorEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory ApplicationCacheErrorEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('ApplicationCacheErrorEvent.message')
  @DocsEditable()
  @Experimental() // untriaged
  final String message;

  @DomName('ApplicationCacheErrorEvent.reason')
  @DocsEditable()
  @Experimental() // untriaged
  final String reason;

  @DomName('ApplicationCacheErrorEvent.status')
  @DocsEditable()
  @Experimental() // untriaged
  final int status;

  @DomName('ApplicationCacheErrorEvent.url')
  @DocsEditable()
  @Experimental() // untriaged
  final String url;
}
// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. 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')
@Native("HTMLAreaElement")
class AreaElement extends HtmlElement implements UrlUtils {
  // 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()
  String toString() => JS('String', 'String(#)', 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('HTMLAudioElement')
@Native("HTMLAudioElement")
class AudioElement extends MediaElement {

  @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();

  factory AudioElement([String src]) => new AudioElement._(src);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

  @DomName('AudioTrack.enabled')
  @DocsEditable()
  @Experimental() // untriaged
  bool enabled;

  @DomName('AudioTrack.id')
  @DocsEditable()
  @Experimental() // untriaged
  final String id;

  @DomName('AudioTrack.kind')
  @DocsEditable()
  @Experimental() // untriaged
  final String kind;

  @DomName('AudioTrack.label')
  @DocsEditable()
  @Experimental() // untriaged
  final String label;

  @DomName('AudioTrack.language')
  @DocsEditable()
  @Experimental() // untriaged
  final String language;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

  @DomName('AudioTrackList.changeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> changeEvent = const EventStreamProvider<Event>('change');

  @DomName('AudioTrackList.length')
  @DocsEditable()
  @Experimental() // untriaged
  final int length;

  @DomName('AudioTrackList.__getter__')
  @DocsEditable()
  @Experimental() // untriaged
  AudioTrack __getter__(int index) native;

  @DomName('AudioTrackList.getTrackById')
  @DocsEditable()
  @Experimental() // untriaged
  AudioTrack getTrackById(String id) native;

  @DomName('AudioTrackList.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('AutocompleteErrorEvent')
// http://wiki.whatwg.org/wiki/RequestAutocomplete
@Experimental()
@Native("AutocompleteErrorEvent")
class AutocompleteErrorEvent extends Event {
  // 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')
@Native("HTMLBRElement")
class BRElement extends HtmlElement {
  // 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
@Native("BarProp")
class BarProp extends Interceptor {
  // 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')
@Native("HTMLBaseElement")
class BaseElement extends HtmlElement {
  // 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('BatteryManager')
// https://dvcs.w3.org/hg/dap/raw-file/default/battery/Overview.html#batterymanager-interface
@Experimental() // stable
@Native("BatteryManager")
class BatteryManager extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory BatteryManager._() { throw new UnsupportedError("Not supported"); }

  @DomName('BatteryManager.charging')
  @DocsEditable()
  final bool charging;

  @DomName('BatteryManager.chargingTime')
  @DocsEditable()
  final double chargingTime;

  @DomName('BatteryManager.dischargingTime')
  @DocsEditable()
  final double dischargingTime;

  @DomName('BatteryManager.level')
  @DocsEditable()
  final double level;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All 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')
@Native("BeforeUnloadEvent")
class BeforeUnloadEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory BeforeUnloadEvent._() { throw new UnsupportedError("Not supported"); }

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

  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')
@Native("Blob")
class Blob extends Interceptor {
  // 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.close')
  @DocsEditable()
  @Experimental() // untriaged
  void close() native;

  @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('Body')
@Experimental() // untriaged
@Native("Body")
class Body extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Body._() { throw new UnsupportedError("Not supported"); }

  @DomName('Body.bodyUsed')
  @DocsEditable()
  @Experimental() // untriaged
  final bool bodyUsed;

  @DomName('Body.arrayBuffer')
  @DocsEditable()
  @Experimental() // untriaged
  Future arrayBuffer() native;

  @DomName('Body.blob')
  @DocsEditable()
  @Experimental() // untriaged
  Future blob() native;

  @DomName('Body.json')
  @DocsEditable()
  @Experimental() // untriaged
  Future json() native;

  @DomName('Body.text')
  @DocsEditable()
  @Experimental() // untriaged
  Future text() 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('HTMLBodyElement')
@Native("HTMLBodyElement")
class BodyElement extends HtmlElement implements WindowEventHandlers {
  // 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')
@Native("HTMLButtonElement")
class ButtonElement extends HtmlElement {
  // 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
@Native("CDATASection")
class CDataSection extends Text {
  // 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('CacheStorage')
@Experimental() // untriaged
@Native("CacheStorage")
class CacheStorage extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CacheStorage._() { throw new UnsupportedError("Not supported"); }

  @DomName('CacheStorage.create')
  @DocsEditable()
  @Experimental() // untriaged
  Future create(String cacheName) native;

  @DomName('CacheStorage.delete')
  @DocsEditable()
  @Experimental() // untriaged
  Future delete(String cacheName) native;

  @DomName('CacheStorage.get')
  @DocsEditable()
  @Experimental() // untriaged
  Future get(String cacheName) native;

  @DomName('CacheStorage.has')
  @DocsEditable()
  @Experimental() // untriaged
  Future has(String cacheName) native;

  @DomName('CacheStorage.keys')
  @DocsEditable()
  @Experimental() // untriaged
  Future keys() 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('Canvas2DContextAttributes')
// http://wiki.whatwg.org/wiki/CanvasOpaque#Suggested_IDL
@Experimental()
@Native("Canvas2DContextAttributes")
class Canvas2DContextAttributes extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Canvas2DContextAttributes._() { throw new UnsupportedError("Not supported"); }

  @DomName('Canvas2DContextAttributes.alpha')
  @DocsEditable()
  bool alpha;

  @DomName('Canvas2DContextAttributes.storage')
  @DocsEditable()
  @Experimental() // untriaged
  String storage;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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')
@Native("HTMLCanvasElement")
class CanvasElement extends HtmlElement implements CanvasImageSource {
  // 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()
  @Creates('CanvasRenderingContext2D|RenderingContext')
  @Returns('CanvasRenderingContext2D|RenderingContext|Null')
  Object 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()
  @Creates('CanvasRenderingContext2D|RenderingContext')
  @Returns('CanvasRenderingContext2D|RenderingContext|Null')
  Object _getContext_1(contextId, attrs) native;
  @JSName('getContext')
  @DomName('HTMLCanvasElement.getContext')
  @DocsEditable()
  @Creates('CanvasRenderingContext2D|RenderingContext')
  @Returns('CanvasRenderingContext2D|RenderingContext|Null')
  Object _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')
@Native("CanvasGradient")
class CanvasGradient extends Interceptor {
  // 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')
@Native("CanvasPattern")
class CanvasPattern extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CanvasPattern._() { throw new UnsupportedError("Not supported"); }

  @DomName('CanvasPattern.setTransform')
  @DocsEditable()
  @Experimental() // untriaged
  void setTransform(Matrix transform) 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.


abstract class CanvasRenderingContext {
  CanvasElement get canvas;
}

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

  @DomName('CanvasRenderingContext2D.canvas')
  @DocsEditable()
  @Experimental() // untriaged
  final CanvasElement canvas;

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

  @DomName('CanvasRenderingContext2D.direction')
  @DocsEditable()
  @Experimental() // untriaged
  String direction;

  @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;

  @DomName('CanvasRenderingContext2D.addHitRegion')
  @DocsEditable()
  @Experimental() // untriaged
  void addHitRegion([Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      _addHitRegion_1(options_1);
      return;
    }
    _addHitRegion_2();
    return;
  }
  @JSName('addHitRegion')
  @DomName('CanvasRenderingContext2D.addHitRegion')
  @DocsEditable()
  @Experimental() // untriaged
  void _addHitRegion_1(options) native;
  @JSName('addHitRegion')
  @DomName('CanvasRenderingContext2D.addHitRegion')
  @DocsEditable()
  @Experimental() // untriaged
  void _addHitRegion_2() native;

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

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

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

  @DomName('CanvasRenderingContext2D.clip')
  @DocsEditable()
  void clip([path_OR_winding, String winding]) 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(canvas_OR_image, 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.drawFocusIfNeeded')
  @DocsEditable()
  @Experimental() // untriaged
  void drawFocusIfNeeded(element_OR_path, [Element element]) 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.isContextLost')
  @DocsEditable()
  @Experimental() // untriaged
  bool isContextLost() native;

  @DomName('CanvasRenderingContext2D.isPointInPath')
  @DocsEditable()
  bool isPointInPath(path_OR_x, num x_OR_y, [winding_OR_y, String winding]) native;

  @DomName('CanvasRenderingContext2D.isPointInStroke')
  @DocsEditable()
  bool isPointInStroke(path_OR_x, num x_OR_y, [num y]) native;

  @DomName('CanvasRenderingContext2D.measureText')
  @DocsEditable()
  TextMetrics measureText(String text) 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_1 = convertDartToNative_ImageData(imagedata);
      _putImageData_2(imagedata_1, 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.removeHitRegion')
  @DocsEditable()
  @Experimental() // untriaged
  void removeHitRegion(String id) 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 x, num y) native;

  @DomName('CanvasRenderingContext2D.scrollPathIntoView')
  @DocsEditable()
  @Experimental() // untriaged
  void scrollPathIntoView([Path2D path]) native;

  @DomName('CanvasRenderingContext2D.setTransform')
  @DocsEditable()
  void setTransform(num a, num b, num c, num d, num e, num f) native;

  @DomName('CanvasRenderingContext2D.stroke')
  @DocsEditable()
  void stroke([Path2D path]) 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 a, num b, num c, num d, num e, num f) native;

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

  // From CanvasPathMethods

  @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.bezierCurveTo')
  @DocsEditable()
  void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y, num x, num y) native;

  @DomName('CanvasRenderingContext2D.closePath')
  @DocsEditable()
  void closePath() 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.lineTo')
  @DocsEditable()
  void lineTo(num x, num y) native;

  @DomName('CanvasRenderingContext2D.moveTo')
  @DocsEditable()
  void moveTo(num x, num y) 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;


  /**
   * 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]) {
    // TODO(terry): This should not be needed: dartbug.com/20939.
    JS('void', '#.arc(#, #, #, #, #, #)', this, 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.
  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);
  }

  /** Deprecated always returns 1.0 */
  @DomName('CanvasRenderingContext2D.webkitBackingStorePixelRation')
  @Experimental()
  @deprecated
  double get backingStorePixelRatio => 1.0;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All 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')
@Native("CharacterData")
class CharacterData extends Node implements ChildNode {
  // 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('CircularGeofencingRegion')
@Experimental() // untriaged
@Native("CircularGeofencingRegion")
class CircularGeofencingRegion extends GeofencingRegion {
  // To suppress missing implicit constructor warnings.
  factory CircularGeofencingRegion._() { throw new UnsupportedError("Not supported"); }

  @DomName('CircularGeofencingRegion.CircularGeofencingRegion')
  @DocsEditable()
  factory CircularGeofencingRegion(Map init) {
    var init_1 = convertDartToNative_Dictionary(init);
    return CircularGeofencingRegion._create_1(init_1);
  }
  static CircularGeofencingRegion _create_1(init) => JS('CircularGeofencingRegion', 'new CircularGeofencingRegion(#)', init);

  @DomName('CircularGeofencingRegion.MAX_RADIUS')
  @DocsEditable()
  @Experimental() // untriaged
  static const num MAX_RADIUS = 100.0;

  @DomName('CircularGeofencingRegion.MIN_RADIUS')
  @DocsEditable()
  @Experimental() // untriaged
  static const num MIN_RADIUS = 1.0;

  @DomName('CircularGeofencingRegion.latitude')
  @DocsEditable()
  @Experimental() // untriaged
  final double latitude;

  @DomName('CircularGeofencingRegion.longitude')
  @DocsEditable()
  @Experimental() // untriaged
  final double longitude;

  @DomName('CircularGeofencingRegion.radius')
  @DocsEditable()
  @Experimental() // untriaged
  final double radius;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All 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')
@Native("CloseEvent")
class CloseEvent extends Event {
  // 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')
@Native("Comment")
class Comment extends CharacterData {
  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')
@Native("CompositionEvent")
class CompositionEvent extends UIEvent {
  factory CompositionEvent(String type,
      {bool canBubble: false, bool cancelable: false, Window view,
      String data, String locale}) {
    if (view == null) {
      view = window;
    }
    var e = document._createEvent("CompositionEvent");

    if (Device.isFirefox) {
      // Firefox requires the locale parameter that isn't supported elsewhere.
      JS('void', '#.initCompositionEvent(#, #, #, #, #, #)',
          e, type, canBubble, cancelable, view, data, locale);
    } else {
      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;

  @DomName('CompositionEvent.getSegments')
  @DocsEditable()
  @Experimental() // untriaged
  List<int> getSegments() native;

  @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
@Native("ConsoleBase")
class ConsoleBase extends Interceptor {
  // 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
@Native("HTMLContentElement")
class ContentElement extends HtmlElement {
  // 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.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')
@Native("Coordinates")
class Coordinates extends Interceptor {
  // 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('Credential')
@Experimental() // untriaged
@Native("Credential")
class Credential extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Credential._() { throw new UnsupportedError("Not supported"); }

  @JSName('avatarURL')
  @DomName('Credential.avatarURL')
  @DocsEditable()
  @Experimental() // untriaged
  final String avatarUrl;

  @DomName('Credential.id')
  @DocsEditable()
  @Experimental() // untriaged
  final String id;

  @DomName('Credential.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('CredentialsContainer')
@Experimental() // untriaged
@Native("CredentialsContainer")
class CredentialsContainer extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CredentialsContainer._() { throw new UnsupportedError("Not supported"); }

  @DomName('CredentialsContainer.notifyFailedSignIn')
  @DocsEditable()
  @Experimental() // untriaged
  Future notifyFailedSignIn(Credential credential) native;

  @DomName('CredentialsContainer.notifySignedIn')
  @DocsEditable()
  @Experimental() // untriaged
  Future notifySignedIn(Credential credential) native;

  @DomName('CredentialsContainer.notifySignedOut')
  @DocsEditable()
  @Experimental() // untriaged
  Future notifySignedOut() native;

  @DomName('CredentialsContainer.request')
  @DocsEditable()
  @Experimental() // untriaged
  Future request([Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _request_1(options_1);
    }
    return _request_2();
  }
  @JSName('request')
  @DomName('CredentialsContainer.request')
  @DocsEditable()
  @Experimental() // untriaged
  Future _request_1(options) native;
  @JSName('request')
  @DomName('CredentialsContainer.request')
  @DocsEditable()
  @Experimental() // untriaged
  Future _request_2() native;
}
// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for 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('Crypto')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
// http://www.w3.org/TR/WebCryptoAPI/
@Native("Crypto")
class Crypto extends Interceptor {

  TypedData getRandomValues(TypedData array) {
    return _getRandomValues(array);
  }

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

  @JSName('getRandomValues')
  @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('CryptoKey')
@Experimental() // untriaged
@Native("CryptoKey")
class CryptoKey extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CryptoKey._() { throw new UnsupportedError("Not supported"); }

  @DomName('CryptoKey.algorithm')
  @DocsEditable()
  @Experimental() // untriaged
  final Object algorithm;

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

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

  @DomName('CryptoKey.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
@Native("CSS")
class Css extends Interceptor {
  // 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()
@Native("CSSCharsetRule")
class CssCharsetRule extends CssRule {
  // 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/
@Native("WebKitCSSFilterRule")
class CssFilterRule extends CssRule {
  // 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('CSSFontFaceRule')
@Native("CSSFontFaceRule")
class CssFontFaceRule extends CssRule {
  // 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')
@Native("CSSImportRule")
class CssImportRule extends CssRule {
  // 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
@Native("CSSKeyframeRule,MozCSSKeyframeRule,WebKitCSSKeyframeRule")
class CssKeyframeRule extends CssRule {
  // 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
@Native("CSSKeyframesRule,MozCSSKeyframesRule,WebKitCSSKeyframesRule")
class CssKeyframesRule extends CssRule {
  // 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')
@Native("CSSMediaRule")
class CssMediaRule extends CssRule {
  // 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')
@Native("CSSPageRule")
class CssPageRule extends CssRule {
  // 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')
@Native("CSSRule")
class CssRule extends Interceptor {
  // 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) 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.

// WARNING: DO NOT EDIT THIS TEMPLATE FILE.
// The template file was generated by scripts/css_code_generator.py

// Source of CSS properties:
//   CSSPropertyNames.in


@DomName('CSSStyleDeclaration')
@Native("CSSStyleDeclaration,MSStyleCSSProperties,CSS2Properties")
class CssStyleDeclaration  extends Interceptor with
    CssStyleDeclarationBase  {
  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 = _getPropertyValueHelper(propertyName);
    return propValue != null ? propValue : '';
  }

  String _getPropertyValueHelper(String propertyName) {
    if (_supportsProperty(_camelCase(propertyName))) {
      return _getPropertyValue(propertyName);
    } else {
      return _getPropertyValue(Device.cssPrefix + propertyName);
    }
  }

  /**
   * Returns true if the provided *CSS* property name is supported on this
   * element.
   *
   * Please note the property name camelCase, not-hyphens. This
   * method returns true if the property is accessible via an unprefixed _or_
   * prefixed property.
   */
  bool supportsProperty(String propertyName) {
    return _supportsProperty(propertyName) ||
        _supportsProperty(_camelCase(Device.cssPrefix + propertyName));
  }

  bool _supportsProperty(String propertyName) {
    return JS('bool', '# in #', propertyName, this);
  }


  @DomName('CSSStyleDeclaration.setProperty')
  void setProperty(String propertyName, String value, [String priority]) {
    return _setPropertyHelper(_browserPropertyName(propertyName),
      value, priority);
  }

  String _browserPropertyName(String propertyName) {
    String name = _readCache(propertyName);
    if (name is String) return name;
    if (_supportsProperty(_camelCase(propertyName))) {
      name = propertyName;
    } else {
      name = Device.cssPrefix + propertyName;
    }
    _writeCache(propertyName, name);
    return name;
  }

  static final _propertyCache = JS('', '{}');
  static String _readCache(String key) =>
    JS('String|Null', '#[#]', _propertyCache, key);
  static void _writeCache(String key, String value) {
    JS('void', '#[#] = #', _propertyCache, key, value);
  }

  static String _camelCase(String hyphenated) {
    var replacedMs = JS('String', r'#.replace(/^-ms-/, "ms-")', hyphenated);

    var fToUpper = const JS_CONST(
        r'function(_, letter) { return letter.toUpperCase(); }');
    return JS('String', r'#.replace(/-([\da-z])/ig, #)', replacedMs, fToUpper);
  }

  void _setPropertyHelper(String propertyName, String value, [String priority]) {
    if (value == null) value = '';
    if (priority == null) priority = '';
    JS('void', '#.setProperty(#, #, #)', this, propertyName, value, priority);
  }

  /**
   * Checks to see if CSS Transitions are supported.
   */
  static bool get supportsTransitions {
    return document.body.style.supportsProperty('transition');
  }
  // 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.__getter__')
  @DocsEditable()
  @Experimental() // untriaged
  Object __getter__(String name) native;

  @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;


  /** Gets the value of "background" */
  String get background => this._background;

  /** Sets the value of "background" */
  set background(String value) {
    _background = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('background')
  String _background;
    
  /** Gets the value of "background-attachment" */
  String get backgroundAttachment => this._backgroundAttachment;

  /** Sets the value of "background-attachment" */
  set backgroundAttachment(String value) {
    _backgroundAttachment = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('backgroundAttachment')
  String _backgroundAttachment;
    
  /** Gets the value of "background-color" */
  String get backgroundColor => this._backgroundColor;

  /** Sets the value of "background-color" */
  set backgroundColor(String value) {
    _backgroundColor = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('backgroundColor')
  String _backgroundColor;
    
  /** Gets the value of "background-image" */
  String get backgroundImage => this._backgroundImage;

  /** Sets the value of "background-image" */
  set backgroundImage(String value) {
    _backgroundImage = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('backgroundImage')
  String _backgroundImage;
    
  /** Gets the value of "background-position" */
  String get backgroundPosition => this._backgroundPosition;

  /** Sets the value of "background-position" */
  set backgroundPosition(String value) {
    _backgroundPosition = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('backgroundPosition')
  String _backgroundPosition;
    
  /** Gets the value of "background-repeat" */
  String get backgroundRepeat => this._backgroundRepeat;

  /** Sets the value of "background-repeat" */
  set backgroundRepeat(String value) {
    _backgroundRepeat = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('backgroundRepeat')
  String _backgroundRepeat;
    
  /** Gets the value of "border" */
  String get border => this._border;

  /** Sets the value of "border" */
  set border(String value) {
    _border = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('border')
  String _border;
    
  /** Gets the value of "border-bottom" */
  String get borderBottom => this._borderBottom;

  /** Sets the value of "border-bottom" */
  set borderBottom(String value) {
    _borderBottom = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('borderBottom')
  String _borderBottom;
    
  /** Gets the value of "border-bottom-color" */
  String get borderBottomColor => this._borderBottomColor;

  /** Sets the value of "border-bottom-color" */
  set borderBottomColor(String value) {
    _borderBottomColor = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('borderBottomColor')
  String _borderBottomColor;
    
  /** Gets the value of "border-bottom-style" */
  String get borderBottomStyle => this._borderBottomStyle;

  /** Sets the value of "border-bottom-style" */
  set borderBottomStyle(String value) {
    _borderBottomStyle = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('borderBottomStyle')
  String _borderBottomStyle;
    
  /** Gets the value of "border-bottom-width" */
  String get borderBottomWidth => this._borderBottomWidth;

  /** Sets the value of "border-bottom-width" */
  set borderBottomWidth(String value) {
    _borderBottomWidth = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('borderBottomWidth')
  String _borderBottomWidth;
    
  /** Gets the value of "border-collapse" */
  String get borderCollapse => this._borderCollapse;

  /** Sets the value of "border-collapse" */
  set borderCollapse(String value) {
    _borderCollapse = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('borderCollapse')
  String _borderCollapse;
    
  /** Gets the value of "border-color" */
  String get borderColor => this._borderColor;

  /** Sets the value of "border-color" */
  set borderColor(String value) {
    _borderColor = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('borderColor')
  String _borderColor;
    
  /** Gets the value of "border-left" */
  String get borderLeft => this._borderLeft;

  /** Sets the value of "border-left" */
  set borderLeft(String value) {
    _borderLeft = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('borderLeft')
  String _borderLeft;
    
  /** Gets the value of "border-left-color" */
  String get borderLeftColor => this._borderLeftColor;

  /** Sets the value of "border-left-color" */
  set borderLeftColor(String value) {
    _borderLeftColor = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('borderLeftColor')
  String _borderLeftColor;
    
  /** Gets the value of "border-left-style" */
  String get borderLeftStyle => this._borderLeftStyle;

  /** Sets the value of "border-left-style" */
  set borderLeftStyle(String value) {
    _borderLeftStyle = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('borderLeftStyle')
  String _borderLeftStyle;
    
  /** Gets the value of "border-left-width" */
  String get borderLeftWidth => this._borderLeftWidth;

  /** Sets the value of "border-left-width" */
  set borderLeftWidth(String value) {
    _borderLeftWidth = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('borderLeftWidth')
  String _borderLeftWidth;
    
  /** Gets the value of "border-right" */
  String get borderRight => this._borderRight;

  /** Sets the value of "border-right" */
  set borderRight(String value) {
    _borderRight = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('borderRight')
  String _borderRight;
    
  /** Gets the value of "border-right-color" */
  String get borderRightColor => this._borderRightColor;

  /** Sets the value of "border-right-color" */
  set borderRightColor(String value) {
    _borderRightColor = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('borderRightColor')
  String _borderRightColor;
    
  /** Gets the value of "border-right-style" */
  String get borderRightStyle => this._borderRightStyle;

  /** Sets the value of "border-right-style" */
  set borderRightStyle(String value) {
    _borderRightStyle = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('borderRightStyle')
  String _borderRightStyle;
    
  /** Gets the value of "border-right-width" */
  String get borderRightWidth => this._borderRightWidth;

  /** Sets the value of "border-right-width" */
  set borderRightWidth(String value) {
    _borderRightWidth = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('borderRightWidth')
  String _borderRightWidth;
    
  /** Gets the value of "border-spacing" */
  String get borderSpacing => this._borderSpacing;

  /** Sets the value of "border-spacing" */
  set borderSpacing(String value) {
    _borderSpacing = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('borderSpacing')
  String _borderSpacing;
    
  /** Gets the value of "border-style" */
  String get borderStyle => this._borderStyle;

  /** Sets the value of "border-style" */
  set borderStyle(String value) {
    _borderStyle = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('borderStyle')
  String _borderStyle;
    
  /** Gets the value of "border-top" */
  String get borderTop => this._borderTop;

  /** Sets the value of "border-top" */
  set borderTop(String value) {
    _borderTop = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('borderTop')
  String _borderTop;
    
  /** Gets the value of "border-top-color" */
  String get borderTopColor => this._borderTopColor;

  /** Sets the value of "border-top-color" */
  set borderTopColor(String value) {
    _borderTopColor = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('borderTopColor')
  String _borderTopColor;
    
  /** Gets the value of "border-top-style" */
  String get borderTopStyle => this._borderTopStyle;

  /** Sets the value of "border-top-style" */
  set borderTopStyle(String value) {
    _borderTopStyle = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('borderTopStyle')
  String _borderTopStyle;
    
  /** Gets the value of "border-top-width" */
  String get borderTopWidth => this._borderTopWidth;

  /** Sets the value of "border-top-width" */
  set borderTopWidth(String value) {
    _borderTopWidth = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('borderTopWidth')
  String _borderTopWidth;
    
  /** Gets the value of "border-width" */
  String get borderWidth => this._borderWidth;

  /** Sets the value of "border-width" */
  set borderWidth(String value) {
    _borderWidth = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('borderWidth')
  String _borderWidth;
    
  /** Gets the value of "bottom" */
  String get bottom => this._bottom;

  /** Sets the value of "bottom" */
  set bottom(String value) {
    _bottom = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('bottom')
  String _bottom;
    
  /** Gets the value of "caption-side" */
  String get captionSide => this._captionSide;

  /** Sets the value of "caption-side" */
  set captionSide(String value) {
    _captionSide = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('captionSide')
  String _captionSide;
    
  /** Gets the value of "clear" */
  String get clear => this._clear;

  /** Sets the value of "clear" */
  set clear(String value) {
    _clear = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('clear')
  String _clear;
    
  /** Gets the value of "clip" */
  String get clip => this._clip;

  /** Sets the value of "clip" */
  set clip(String value) {
    _clip = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('clip')
  String _clip;
    
  /** Gets the value of "color" */
  String get color => this._color;

  /** Sets the value of "color" */
  set color(String value) {
    _color = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('color')
  String _color;
    
  /** Gets the value of "content" */
  String get content => this._content;

  /** Sets the value of "content" */
  set content(String value) {
    _content = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('content')
  String _content;
    
  /** Gets the value of "cursor" */
  String get cursor => this._cursor;

  /** Sets the value of "cursor" */
  set cursor(String value) {
    _cursor = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('cursor')
  String _cursor;
    
  /** Gets the value of "direction" */
  String get direction => this._direction;

  /** Sets the value of "direction" */
  set direction(String value) {
    _direction = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('direction')
  String _direction;
    
  /** Gets the value of "display" */
  String get display => this._display;

  /** Sets the value of "display" */
  set display(String value) {
    _display = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('display')
  String _display;
    
  /** Gets the value of "empty-cells" */
  String get emptyCells => this._emptyCells;

  /** Sets the value of "empty-cells" */
  set emptyCells(String value) {
    _emptyCells = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('emptyCells')
  String _emptyCells;
    
  /** Gets the value of "font" */
  String get font => this._font;

  /** Sets the value of "font" */
  set font(String value) {
    _font = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('font')
  String _font;
    
  /** Gets the value of "font-family" */
  String get fontFamily => this._fontFamily;

  /** Sets the value of "font-family" */
  set fontFamily(String value) {
    _fontFamily = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('fontFamily')
  String _fontFamily;
    
  /** Gets the value of "font-size" */
  String get fontSize => this._fontSize;

  /** Sets the value of "font-size" */
  set fontSize(String value) {
    _fontSize = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('fontSize')
  String _fontSize;
    
  /** Gets the value of "font-style" */
  String get fontStyle => this._fontStyle;

  /** Sets the value of "font-style" */
  set fontStyle(String value) {
    _fontStyle = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('fontStyle')
  String _fontStyle;
    
  /** Gets the value of "font-variant" */
  String get fontVariant => this._fontVariant;

  /** Sets the value of "font-variant" */
  set fontVariant(String value) {
    _fontVariant = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('fontVariant')
  String _fontVariant;
    
  /** Gets the value of "font-weight" */
  String get fontWeight => this._fontWeight;

  /** Sets the value of "font-weight" */
  set fontWeight(String value) {
    _fontWeight = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('fontWeight')
  String _fontWeight;
    
  /** Gets the value of "height" */
  String get height => this._height;

  /** Sets the value of "height" */
  set height(String value) {
    _height = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('height')
  String _height;
    
  /** Gets the value of "left" */
  String get left => this._left;

  /** Sets the value of "left" */
  set left(String value) {
    _left = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('left')
  String _left;
    
  /** Gets the value of "letter-spacing" */
  String get letterSpacing => this._letterSpacing;

  /** Sets the value of "letter-spacing" */
  set letterSpacing(String value) {
    _letterSpacing = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('letterSpacing')
  String _letterSpacing;
    
  /** Gets the value of "line-height" */
  String get lineHeight => this._lineHeight;

  /** Sets the value of "line-height" */
  set lineHeight(String value) {
    _lineHeight = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('lineHeight')
  String _lineHeight;
    
  /** Gets the value of "list-style" */
  String get listStyle => this._listStyle;

  /** Sets the value of "list-style" */
  set listStyle(String value) {
    _listStyle = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('listStyle')
  String _listStyle;
    
  /** Gets the value of "list-style-image" */
  String get listStyleImage => this._listStyleImage;

  /** Sets the value of "list-style-image" */
  set listStyleImage(String value) {
    _listStyleImage = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('listStyleImage')
  String _listStyleImage;
    
  /** Gets the value of "list-style-position" */
  String get listStylePosition => this._listStylePosition;

  /** Sets the value of "list-style-position" */
  set listStylePosition(String value) {
    _listStylePosition = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('listStylePosition')
  String _listStylePosition;
    
  /** Gets the value of "list-style-type" */
  String get listStyleType => this._listStyleType;

  /** Sets the value of "list-style-type" */
  set listStyleType(String value) {
    _listStyleType = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('listStyleType')
  String _listStyleType;
    
  /** Gets the value of "margin" */
  String get margin => this._margin;

  /** Sets the value of "margin" */
  set margin(String value) {
    _margin = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('margin')
  String _margin;
    
  /** Gets the value of "margin-bottom" */
  String get marginBottom => this._marginBottom;

  /** Sets the value of "margin-bottom" */
  set marginBottom(String value) {
    _marginBottom = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('marginBottom')
  String _marginBottom;
    
  /** Gets the value of "margin-left" */
  String get marginLeft => this._marginLeft;

  /** Sets the value of "margin-left" */
  set marginLeft(String value) {
    _marginLeft = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('marginLeft')
  String _marginLeft;
    
  /** Gets the value of "margin-right" */
  String get marginRight => this._marginRight;

  /** Sets the value of "margin-right" */
  set marginRight(String value) {
    _marginRight = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('marginRight')
  String _marginRight;
    
  /** Gets the value of "margin-top" */
  String get marginTop => this._marginTop;

  /** Sets the value of "margin-top" */
  set marginTop(String value) {
    _marginTop = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('marginTop')
  String _marginTop;
    
  /** Gets the value of "max-height" */
  String get maxHeight => this._maxHeight;

  /** Sets the value of "max-height" */
  set maxHeight(String value) {
    _maxHeight = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('maxHeight')
  String _maxHeight;
    
  /** Gets the value of "max-width" */
  String get maxWidth => this._maxWidth;

  /** Sets the value of "max-width" */
  set maxWidth(String value) {
    _maxWidth = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('maxWidth')
  String _maxWidth;
    
  /** Gets the value of "min-height" */
  String get minHeight => this._minHeight;

  /** Sets the value of "min-height" */
  set minHeight(String value) {
    _minHeight = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('minHeight')
  String _minHeight;
    
  /** Gets the value of "min-width" */
  String get minWidth => this._minWidth;

  /** Sets the value of "min-width" */
  set minWidth(String value) {
    _minWidth = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('minWidth')
  String _minWidth;
    
  /** Gets the value of "outline" */
  String get outline => this._outline;

  /** Sets the value of "outline" */
  set outline(String value) {
    _outline = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('outline')
  String _outline;
    
  /** Gets the value of "outline-color" */
  String get outlineColor => this._outlineColor;

  /** Sets the value of "outline-color" */
  set outlineColor(String value) {
    _outlineColor = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('outlineColor')
  String _outlineColor;
    
  /** Gets the value of "outline-style" */
  String get outlineStyle => this._outlineStyle;

  /** Sets the value of "outline-style" */
  set outlineStyle(String value) {
    _outlineStyle = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('outlineStyle')
  String _outlineStyle;
    
  /** Gets the value of "outline-width" */
  String get outlineWidth => this._outlineWidth;

  /** Sets the value of "outline-width" */
  set outlineWidth(String value) {
    _outlineWidth = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('outlineWidth')
  String _outlineWidth;
    
  /** Gets the value of "overflow" */
  String get overflow => this._overflow;

  /** Sets the value of "overflow" */
  set overflow(String value) {
    _overflow = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('overflow')
  String _overflow;
    
  /** Gets the value of "padding" */
  String get padding => this._padding;

  /** Sets the value of "padding" */
  set padding(String value) {
    _padding = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('padding')
  String _padding;
    
  /** Gets the value of "padding-bottom" */
  String get paddingBottom => this._paddingBottom;

  /** Sets the value of "padding-bottom" */
  set paddingBottom(String value) {
    _paddingBottom = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('paddingBottom')
  String _paddingBottom;
    
  /** Gets the value of "padding-left" */
  String get paddingLeft => this._paddingLeft;

  /** Sets the value of "padding-left" */
  set paddingLeft(String value) {
    _paddingLeft = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('paddingLeft')
  String _paddingLeft;
    
  /** Gets the value of "padding-right" */
  String get paddingRight => this._paddingRight;

  /** Sets the value of "padding-right" */
  set paddingRight(String value) {
    _paddingRight = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('paddingRight')
  String _paddingRight;
    
  /** Gets the value of "padding-top" */
  String get paddingTop => this._paddingTop;

  /** Sets the value of "padding-top" */
  set paddingTop(String value) {
    _paddingTop = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('paddingTop')
  String _paddingTop;
    
  /** Gets the value of "page-break-after" */
  String get pageBreakAfter => this._pageBreakAfter;

  /** Sets the value of "page-break-after" */
  set pageBreakAfter(String value) {
    _pageBreakAfter = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('pageBreakAfter')
  String _pageBreakAfter;
    
  /** Gets the value of "page-break-before" */
  String get pageBreakBefore => this._pageBreakBefore;

  /** Sets the value of "page-break-before" */
  set pageBreakBefore(String value) {
    _pageBreakBefore = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('pageBreakBefore')
  String _pageBreakBefore;
    
  /** Gets the value of "page-break-inside" */
  String get pageBreakInside => this._pageBreakInside;

  /** Sets the value of "page-break-inside" */
  set pageBreakInside(String value) {
    _pageBreakInside = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('pageBreakInside')
  String _pageBreakInside;
    
  /** Gets the value of "position" */
  String get position => this._position;

  /** Sets the value of "position" */
  set position(String value) {
    _position = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('position')
  String _position;
    
  /** Gets the value of "quotes" */
  String get quotes => this._quotes;

  /** Sets the value of "quotes" */
  set quotes(String value) {
    _quotes = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('quotes')
  String _quotes;
    
  /** Gets the value of "right" */
  String get right => this._right;

  /** Sets the value of "right" */
  set right(String value) {
    _right = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('right')
  String _right;
    
  /** Gets the value of "table-layout" */
  String get tableLayout => this._tableLayout;

  /** Sets the value of "table-layout" */
  set tableLayout(String value) {
    _tableLayout = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('tableLayout')
  String _tableLayout;
    
  /** Gets the value of "text-align" */
  String get textAlign => this._textAlign;

  /** Sets the value of "text-align" */
  set textAlign(String value) {
    _textAlign = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('textAlign')
  String _textAlign;
    
  /** Gets the value of "text-decoration" */
  String get textDecoration => this._textDecoration;

  /** Sets the value of "text-decoration" */
  set textDecoration(String value) {
    _textDecoration = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('textDecoration')
  String _textDecoration;
    
  /** Gets the value of "text-indent" */
  String get textIndent => this._textIndent;

  /** Sets the value of "text-indent" */
  set textIndent(String value) {
    _textIndent = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('textIndent')
  String _textIndent;
    
  /** Gets the value of "text-transform" */
  String get textTransform => this._textTransform;

  /** Sets the value of "text-transform" */
  set textTransform(String value) {
    _textTransform = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('textTransform')
  String _textTransform;
    
  /** Gets the value of "top" */
  String get top => this._top;

  /** Sets the value of "top" */
  set top(String value) {
    _top = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('top')
  String _top;
    
  /** Gets the value of "unicode-bidi" */
  String get unicodeBidi => this._unicodeBidi;

  /** Sets the value of "unicode-bidi" */
  set unicodeBidi(String value) {
    _unicodeBidi = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('unicodeBidi')
  String _unicodeBidi;
    
  /** Gets the value of "vertical-align" */
  String get verticalAlign => this._verticalAlign;

  /** Sets the value of "vertical-align" */
  set verticalAlign(String value) {
    _verticalAlign = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('verticalAlign')
  String _verticalAlign;
    
  /** Gets the value of "visibility" */
  String get visibility => this._visibility;

  /** Sets the value of "visibility" */
  set visibility(String value) {
    _visibility = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('visibility')
  String _visibility;
    
  /** Gets the value of "white-space" */
  String get whiteSpace => this._whiteSpace;

  /** Sets the value of "white-space" */
  set whiteSpace(String value) {
    _whiteSpace = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('whiteSpace')
  String _whiteSpace;
    
  /** Gets the value of "width" */
  String get width => this._width;

  /** Sets the value of "width" */
  set width(String value) {
    _width = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('width')
  String _width;
    
  /** Gets the value of "word-spacing" */
  String get wordSpacing => this._wordSpacing;

  /** Sets the value of "word-spacing" */
  set wordSpacing(String value) {
    _wordSpacing = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('wordSpacing')
  String _wordSpacing;
    
  /** Gets the value of "z-index" */
  String get zIndex => this._zIndex;

  /** Sets the value of "z-index" */
  set zIndex(String value) {
    _zIndex = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('zIndex')
  String _zIndex;
    
}

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));
  }


  void _setAll(String propertyName, String value) {
    value = value == null ? '' : value;
    for (Element element in _elementIterable) {
      JS('void', '#.style[#] = #', element, propertyName, value);
    }
  }

  /** Sets the value of "background" */
  set background(String value) {
    _setAll('background', value);
  }
    
  /** Sets the value of "background-attachment" */
  set backgroundAttachment(String value) {
    _setAll('backgroundAttachment', value);
  }
    
  /** Sets the value of "background-color" */
  set backgroundColor(String value) {
    _setAll('backgroundColor', value);
  }
    
  /** Sets the value of "background-image" */
  set backgroundImage(String value) {
    _setAll('backgroundImage', value);
  }
    
  /** Sets the value of "background-position" */
  set backgroundPosition(String value) {
    _setAll('backgroundPosition', value);
  }
    
  /** Sets the value of "background-repeat" */
  set backgroundRepeat(String value) {
    _setAll('backgroundRepeat', value);
  }
    
  /** Sets the value of "border" */
  set border(String value) {
    _setAll('border', value);
  }
    
  /** Sets the value of "border-bottom" */
  set borderBottom(String value) {
    _setAll('borderBottom', value);
  }
    
  /** Sets the value of "border-bottom-color" */
  set borderBottomColor(String value) {
    _setAll('borderBottomColor', value);
  }
    
  /** Sets the value of "border-bottom-style" */
  set borderBottomStyle(String value) {
    _setAll('borderBottomStyle', value);
  }
    
  /** Sets the value of "border-bottom-width" */
  set borderBottomWidth(String value) {
    _setAll('borderBottomWidth', value);
  }
    
  /** Sets the value of "border-collapse" */
  set borderCollapse(String value) {
    _setAll('borderCollapse', value);
  }
    
  /** Sets the value of "border-color" */
  set borderColor(String value) {
    _setAll('borderColor', value);
  }
    
  /** Sets the value of "border-left" */
  set borderLeft(String value) {
    _setAll('borderLeft', value);
  }
    
  /** Sets the value of "border-left-color" */
  set borderLeftColor(String value) {
    _setAll('borderLeftColor', value);
  }
    
  /** Sets the value of "border-left-style" */
  set borderLeftStyle(String value) {
    _setAll('borderLeftStyle', value);
  }
    
  /** Sets the value of "border-left-width" */
  set borderLeftWidth(String value) {
    _setAll('borderLeftWidth', value);
  }
    
  /** Sets the value of "border-right" */
  set borderRight(String value) {
    _setAll('borderRight', value);
  }
    
  /** Sets the value of "border-right-color" */
  set borderRightColor(String value) {
    _setAll('borderRightColor', value);
  }
    
  /** Sets the value of "border-right-style" */
  set borderRightStyle(String value) {
    _setAll('borderRightStyle', value);
  }
    
  /** Sets the value of "border-right-width" */
  set borderRightWidth(String value) {
    _setAll('borderRightWidth', value);
  }
    
  /** Sets the value of "border-spacing" */
  set borderSpacing(String value) {
    _setAll('borderSpacing', value);
  }
    
  /** Sets the value of "border-style" */
  set borderStyle(String value) {
    _setAll('borderStyle', value);
  }
    
  /** Sets the value of "border-top" */
  set borderTop(String value) {
    _setAll('borderTop', value);
  }
    
  /** Sets the value of "border-top-color" */
  set borderTopColor(String value) {
    _setAll('borderTopColor', value);
  }
    
  /** Sets the value of "border-top-style" */
  set borderTopStyle(String value) {
    _setAll('borderTopStyle', value);
  }
    
  /** Sets the value of "border-top-width" */
  set borderTopWidth(String value) {
    _setAll('borderTopWidth', value);
  }
    
  /** Sets the value of "border-width" */
  set borderWidth(String value) {
    _setAll('borderWidth', value);
  }
    
  /** Sets the value of "bottom" */
  set bottom(String value) {
    _setAll('bottom', value);
  }
    
  /** Sets the value of "caption-side" */
  set captionSide(String value) {
    _setAll('captionSide', value);
  }
    
  /** Sets the value of "clear" */
  set clear(String value) {
    _setAll('clear', value);
  }
    
  /** Sets the value of "clip" */
  set clip(String value) {
    _setAll('clip', value);
  }
    
  /** Sets the value of "color" */
  set color(String value) {
    _setAll('color', value);
  }
    
  /** Sets the value of "content" */
  set content(String value) {
    _setAll('content', value);
  }
    
  /** Sets the value of "cursor" */
  set cursor(String value) {
    _setAll('cursor', value);
  }
    
  /** Sets the value of "direction" */
  set direction(String value) {
    _setAll('direction', value);
  }
    
  /** Sets the value of "display" */
  set display(String value) {
    _setAll('display', value);
  }
    
  /** Sets the value of "empty-cells" */
  set emptyCells(String value) {
    _setAll('emptyCells', value);
  }
    
  /** Sets the value of "font" */
  set font(String value) {
    _setAll('font', value);
  }
    
  /** Sets the value of "font-family" */
  set fontFamily(String value) {
    _setAll('fontFamily', value);
  }
    
  /** Sets the value of "font-size" */
  set fontSize(String value) {
    _setAll('fontSize', value);
  }
    
  /** Sets the value of "font-style" */
  set fontStyle(String value) {
    _setAll('fontStyle', value);
  }
    
  /** Sets the value of "font-variant" */
  set fontVariant(String value) {
    _setAll('fontVariant', value);
  }
    
  /** Sets the value of "font-weight" */
  set fontWeight(String value) {
    _setAll('fontWeight', value);
  }
    
  /** Sets the value of "height" */
  set height(String value) {
    _setAll('height', value);
  }
    
  /** Sets the value of "left" */
  set left(String value) {
    _setAll('left', value);
  }
    
  /** Sets the value of "letter-spacing" */
  set letterSpacing(String value) {
    _setAll('letterSpacing', value);
  }
    
  /** Sets the value of "line-height" */
  set lineHeight(String value) {
    _setAll('lineHeight', value);
  }
    
  /** Sets the value of "list-style" */
  set listStyle(String value) {
    _setAll('listStyle', value);
  }
    
  /** Sets the value of "list-style-image" */
  set listStyleImage(String value) {
    _setAll('listStyleImage', value);
  }
    
  /** Sets the value of "list-style-position" */
  set listStylePosition(String value) {
    _setAll('listStylePosition', value);
  }
    
  /** Sets the value of "list-style-type" */
  set listStyleType(String value) {
    _setAll('listStyleType', value);
  }
    
  /** Sets the value of "margin" */
  set margin(String value) {
    _setAll('margin', value);
  }
    
  /** Sets the value of "margin-bottom" */
  set marginBottom(String value) {
    _setAll('marginBottom', value);
  }
    
  /** Sets the value of "margin-left" */
  set marginLeft(String value) {
    _setAll('marginLeft', value);
  }
    
  /** Sets the value of "margin-right" */
  set marginRight(String value) {
    _setAll('marginRight', value);
  }
    
  /** Sets the value of "margin-top" */
  set marginTop(String value) {
    _setAll('marginTop', value);
  }
    
  /** Sets the value of "max-height" */
  set maxHeight(String value) {
    _setAll('maxHeight', value);
  }
    
  /** Sets the value of "max-width" */
  set maxWidth(String value) {
    _setAll('maxWidth', value);
  }
    
  /** Sets the value of "min-height" */
  set minHeight(String value) {
    _setAll('minHeight', value);
  }
    
  /** Sets the value of "min-width" */
  set minWidth(String value) {
    _setAll('minWidth', value);
  }
    
  /** Sets the value of "outline" */
  set outline(String value) {
    _setAll('outline', value);
  }
    
  /** Sets the value of "outline-color" */
  set outlineColor(String value) {
    _setAll('outlineColor', value);
  }
    
  /** Sets the value of "outline-style" */
  set outlineStyle(String value) {
    _setAll('outlineStyle', value);
  }
    
  /** Sets the value of "outline-width" */
  set outlineWidth(String value) {
    _setAll('outlineWidth', value);
  }
    
  /** Sets the value of "overflow" */
  set overflow(String value) {
    _setAll('overflow', value);
  }
    
  /** Sets the value of "padding" */
  set padding(String value) {
    _setAll('padding', value);
  }
    
  /** Sets the value of "padding-bottom" */
  set paddingBottom(String value) {
    _setAll('paddingBottom', value);
  }
    
  /** Sets the value of "padding-left" */
  set paddingLeft(String value) {
    _setAll('paddingLeft', value);
  }
    
  /** Sets the value of "padding-right" */
  set paddingRight(String value) {
    _setAll('paddingRight', value);
  }
    
  /** Sets the value of "padding-top" */
  set paddingTop(String value) {
    _setAll('paddingTop', value);
  }
    
  /** Sets the value of "page-break-after" */
  set pageBreakAfter(String value) {
    _setAll('pageBreakAfter', value);
  }
    
  /** Sets the value of "page-break-before" */
  set pageBreakBefore(String value) {
    _setAll('pageBreakBefore', value);
  }
    
  /** Sets the value of "page-break-inside" */
  set pageBreakInside(String value) {
    _setAll('pageBreakInside', value);
  }
    
  /** Sets the value of "position" */
  set position(String value) {
    _setAll('position', value);
  }
    
  /** Sets the value of "quotes" */
  set quotes(String value) {
    _setAll('quotes', value);
  }
    
  /** Sets the value of "right" */
  set right(String value) {
    _setAll('right', value);
  }
    
  /** Sets the value of "table-layout" */
  set tableLayout(String value) {
    _setAll('tableLayout', value);
  }
    
  /** Sets the value of "text-align" */
  set textAlign(String value) {
    _setAll('textAlign', value);
  }
    
  /** Sets the value of "text-decoration" */
  set textDecoration(String value) {
    _setAll('textDecoration', value);
  }
    
  /** Sets the value of "text-indent" */
  set textIndent(String value) {
    _setAll('textIndent', value);
  }
    
  /** Sets the value of "text-transform" */
  set textTransform(String value) {
    _setAll('textTransform', value);
  }
    
  /** Sets the value of "top" */
  set top(String value) {
    _setAll('top', value);
  }
    
  /** Sets the value of "unicode-bidi" */
  set unicodeBidi(String value) {
    _setAll('unicodeBidi', value);
  }
    
  /** Sets the value of "vertical-align" */
  set verticalAlign(String value) {
    _setAll('verticalAlign', value);
  }
    
  /** Sets the value of "visibility" */
  set visibility(String value) {
    _setAll('visibility', value);
  }
    
  /** Sets the value of "white-space" */
  set whiteSpace(String value) {
    _setAll('whiteSpace', value);
  }
    
  /** Sets the value of "width" */
  set width(String value) {
    _setAll('width', value);
  }
    
  /** Sets the value of "word-spacing" */
  set wordSpacing(String value) {
    _setAll('wordSpacing', value);
  }
    
  /** Sets the value of "z-index" */
  set zIndex(String value) {
    _setAll('zIndex', value);
  }
    

  // 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]);

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

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

  /** Gets the value of "align-items" */
  String get alignItems =>
    getPropertyValue('align-items');

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

  /** Gets the value of "align-self" */
  String get alignSelf =>
    getPropertyValue('align-self');

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

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

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

  /** Gets the value of "animation-delay" */
  String get animationDelay =>
    getPropertyValue('animation-delay');

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

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

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

  /** Gets the value of "animation-duration" */
  String get animationDuration =>
    getPropertyValue('animation-duration');

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

  /** Gets the value of "animation-fill-mode" */
  String get animationFillMode =>
    getPropertyValue('animation-fill-mode');

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

  /** Gets the value of "animation-iteration-count" */
  String get animationIterationCount =>
    getPropertyValue('animation-iteration-count');

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

  /** Gets the value of "animation-name" */
  String get animationName =>
    getPropertyValue('animation-name');

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

  /** Gets the value of "animation-play-state" */
  String get animationPlayState =>
    getPropertyValue('animation-play-state');

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

  /** Gets the value of "animation-timing-function" */
  String get animationTimingFunction =>
    getPropertyValue('animation-timing-function');

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

  /** Gets the value of "app-region" */
  String get appRegion =>
    getPropertyValue('app-region');

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

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

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

  /** Gets the value of "aspect-ratio" */
  String get aspectRatio =>
    getPropertyValue('aspect-ratio');

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

  /** Gets the value of "backface-visibility" */
  String get backfaceVisibility =>
    getPropertyValue('backface-visibility');

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

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

  /** Sets the value of "background" */
  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" */
  set backgroundAttachment(String value) {
    setProperty('background-attachment', value, '');
  }

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

  /** Sets the value of "background-blend-mode" */
  set backgroundBlendMode(String value) {
    setProperty('background-blend-mode', value, '');
  }

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

  /** Sets the value of "background-clip" */
  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" */
  set backgroundColor(String value) {
    setProperty('background-color', value, '');
  }

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

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

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

  /** Sets the value of "background-image" */
  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" */
  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" */
  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" */
  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" */
  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" */
  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" */
  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" */
  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" */
  set backgroundSize(String value) {
    setProperty('background-size', value, '');
  }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  /** Sets the value of "border-bottom" */
  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" */
  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" */
  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" */
  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" */
  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" */
  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" */
  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" */
  set borderColor(String value) {
    setProperty('border-color', value, '');
  }

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

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

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

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

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

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

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

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

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

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

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

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

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

  /** Sets the value of "border-image" */
  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" */
  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" */
  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" */
  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" */
  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" */
  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" */
  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" */
  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" */
  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" */
  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" */
  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" */
  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" */
  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" */
  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" */
  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" */
  set borderSpacing(String value) {
    setProperty('border-spacing', value, '');
  }

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

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

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

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

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

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

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

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

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

  /** Sets the value of "border-style" */
  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" */
  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" */
  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" */
  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" */
  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" */
  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" */
  set borderTopWidth(String value) {
    setProperty('border-top-width', value, '');
  }

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

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

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

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

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

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

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

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

  /** Gets the value of "box-decoration-break" */
  String get boxDecorationBreak =>
    getPropertyValue('box-decoration-break');

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

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

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

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

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

  /** Gets the value of "box-flex-group" */
  String get boxFlexGroup =>
    getPropertyValue('box-flex-group');

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

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

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

  /** Gets the value of "box-ordinal-group" */
  String get boxOrdinalGroup =>
    getPropertyValue('box-ordinal-group');

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

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

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

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

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

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

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

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

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

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

  /** Sets the value of "box-sizing" */
  set boxSizing(String value) {
    setProperty('box-sizing', value, '');
  }

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

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

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

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

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

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

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

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

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

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

  /** Gets the value of "column-break-after" */
  String get columnBreakAfter =>
    getPropertyValue('column-break-after');

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

  /** Gets the value of "column-break-before" */
  String get columnBreakBefore =>
    getPropertyValue('column-break-before');

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

  /** Gets the value of "column-break-inside" */
  String get columnBreakInside =>
    getPropertyValue('column-break-inside');

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

  /** Gets the value of "column-count" */
  String get columnCount =>
    getPropertyValue('column-count');

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

  /** Gets the value of "column-fill" */
  String get columnFill =>
    getPropertyValue('column-fill');

  /** Sets the value of "column-fill" */
  set columnFill(String value) {
    setProperty('column-fill', value, '');
  }

  /** Gets the value of "column-gap" */
  String get columnGap =>
    getPropertyValue('column-gap');

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

  /** Gets the value of "column-rule" */
  String get columnRule =>
    getPropertyValue('column-rule');

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

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

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

  /** Gets the value of "column-rule-style" */
  String get columnRuleStyle =>
    getPropertyValue('column-rule-style');

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

  /** Gets the value of "column-rule-width" */
  String get columnRuleWidth =>
    getPropertyValue('column-rule-width');

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

  /** Gets the value of "column-span" */
  String get columnSpan =>
    getPropertyValue('column-span');

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

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

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

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

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

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

  /** Sets the value of "content" */
  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" */
  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" */
  set counterReset(String value) {
    setProperty('counter-reset', value, '');
  }

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

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

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

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

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

  /** Sets the value of "display" */
  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" */
  set emptyCells(String value) {
    setProperty('empty-cells', value, '');
  }

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

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

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

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

  /** Gets the value of "flex-basis" */
  String get flexBasis =>
    getPropertyValue('flex-basis');

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

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

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

  /** Gets the value of "flex-flow" */
  String get flexFlow =>
    getPropertyValue('flex-flow');

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

  /** Gets the value of "flex-grow" */
  String get flexGrow =>
    getPropertyValue('flex-grow');

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

  /** Gets the value of "flex-shrink" */
  String get flexShrink =>
    getPropertyValue('flex-shrink');

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

  /** Gets the value of "flex-wrap" */
  String get flexWrap =>
    getPropertyValue('flex-wrap');

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

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

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

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

  /** Sets the value of "font" */
  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" */
  set fontFamily(String value) {
    setProperty('font-family', value, '');
  }

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

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

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

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

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

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

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

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

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

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

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

  /** Sets the value of "font-stretch" */
  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" */
  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" */
  set fontVariant(String value) {
    setProperty('font-variant', value, '');
  }

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

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

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

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

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

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

  /** Gets the value of "grid-area" */
  String get gridArea =>
    getPropertyValue('grid-area');

  /** Sets the value of "grid-area" */
  set gridArea(String value) {
    setProperty('grid-area', value, '');
  }

  /** Gets the value of "grid-auto-columns" */
  String get gridAutoColumns =>
    getPropertyValue('grid-auto-columns');

  /** Sets the value of "grid-auto-columns" */
  set gridAutoColumns(String value) {
    setProperty('grid-auto-columns', value, '');
  }

  /** Gets the value of "grid-auto-flow" */
  String get gridAutoFlow =>
    getPropertyValue('grid-auto-flow');

  /** Sets the value of "grid-auto-flow" */
  set gridAutoFlow(String value) {
    setProperty('grid-auto-flow', value, '');
  }

  /** Gets the value of "grid-auto-rows" */
  String get gridAutoRows =>
    getPropertyValue('grid-auto-rows');

  /** Sets the value of "grid-auto-rows" */
  set gridAutoRows(String value) {
    setProperty('grid-auto-rows', value, '');
  }

  /** Gets the value of "grid-column" */
  String get gridColumn =>
    getPropertyValue('grid-column');

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

  /** Gets the value of "grid-column-end" */
  String get gridColumnEnd =>
    getPropertyValue('grid-column-end');

  /** Sets the value of "grid-column-end" */
  set gridColumnEnd(String value) {
    setProperty('grid-column-end', value, '');
  }

  /** Gets the value of "grid-column-start" */
  String get gridColumnStart =>
    getPropertyValue('grid-column-start');

  /** Sets the value of "grid-column-start" */
  set gridColumnStart(String value) {
    setProperty('grid-column-start', value, '');
  }

  /** Gets the value of "grid-row" */
  String get gridRow =>
    getPropertyValue('grid-row');

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

  /** Gets the value of "grid-row-end" */
  String get gridRowEnd =>
    getPropertyValue('grid-row-end');

  /** Sets the value of "grid-row-end" */
  set gridRowEnd(String value) {
    setProperty('grid-row-end', value, '');
  }

  /** Gets the value of "grid-row-start" */
  String get gridRowStart =>
    getPropertyValue('grid-row-start');

  /** Sets the value of "grid-row-start" */
  set gridRowStart(String value) {
    setProperty('grid-row-start', value, '');
  }

  /** Gets the value of "grid-template" */
  String get gridTemplate =>
    getPropertyValue('grid-template');

  /** Sets the value of "grid-template" */
  set gridTemplate(String value) {
    setProperty('grid-template', value, '');
  }

  /** Gets the value of "grid-template-areas" */
  String get gridTemplateAreas =>
    getPropertyValue('grid-template-areas');

  /** Sets the value of "grid-template-areas" */
  set gridTemplateAreas(String value) {
    setProperty('grid-template-areas', value, '');
  }

  /** Gets the value of "grid-template-columns" */
  String get gridTemplateColumns =>
    getPropertyValue('grid-template-columns');

  /** Sets the value of "grid-template-columns" */
  set gridTemplateColumns(String value) {
    setProperty('grid-template-columns', value, '');
  }

  /** Gets the value of "grid-template-rows" */
  String get gridTemplateRows =>
    getPropertyValue('grid-template-rows');

  /** Sets the value of "grid-template-rows" */
  set gridTemplateRows(String value) {
    setProperty('grid-template-rows', value, '');
  }

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

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

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

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

  /** Gets the value of "hyphenate-character" */
  String get hyphenateCharacter =>
    getPropertyValue('hyphenate-character');

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

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

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

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

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

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

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

  /** Gets the value of "justify-self" */
  String get justifySelf =>
    getPropertyValue('justify-self');

  /** Sets the value of "justify-self" */
  set justifySelf(String value) {
    setProperty('justify-self', value, '');
  }

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

  /** Sets the value of "left" */
  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" */
  set letterSpacing(String value) {
    setProperty('letter-spacing', value, '');
  }

  /** Gets the value of "line-box-contain" */
  String get lineBoxContain =>
    getPropertyValue('line-box-contain');

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

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

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

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

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

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

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

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

  /** Sets the value of "list-style" */
  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" */
  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" */
  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" */
  set listStyleType(String value) {
    setProperty('list-style-type', value, '');
  }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  /** Sets the value of "margin-left" */
  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" */
  set marginRight(String value) {
    setProperty('margin-right', value, '');
  }

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

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

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

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

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

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

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

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

  /** Gets the value of "mask-box-image" */
  String get maskBoxImage =>
    getPropertyValue('mask-box-image');

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

  /** Gets the value of "mask-box-image-outset" */
  String get maskBoxImageOutset =>
    getPropertyValue('mask-box-image-outset');

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

  /** Gets the value of "mask-box-image-repeat" */
  String get maskBoxImageRepeat =>
    getPropertyValue('mask-box-image-repeat');

  /** Sets the value of "mask-box-image-repeat" */
  set maskBoxImageRepeat(String value) {
    setProperty('mask-box-image-repeat', value, '');
  }

  /** Gets the value of "mask-box-image-slice" */
  String get maskBoxImageSlice =>
    getPropertyValue('mask-box-image-slice');

  /** Sets the value of "mask-box-image-slice" */
  set maskBoxImageSlice(String value) {
    setProperty('mask-box-image-slice', value, '');
  }

  /** Gets the value of "mask-box-image-source" */
  String get maskBoxImageSource =>
    getPropertyValue('mask-box-image-source');

  /** Sets the value of "mask-box-image-source" */
  set maskBoxImageSource(String value) {
    setProperty('mask-box-image-source', value, '');
  }

  /** Gets the value of "mask-box-image-width" */
  String get maskBoxImageWidth =>
    getPropertyValue('mask-box-image-width');

  /** Sets the value of "mask-box-image-width" */
  set maskBoxImageWidth(String value) {
    setProperty('mask-box-image-width', value, '');
  }

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

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

  /** Gets the value of "mask-composite" */
  String get maskComposite =>
    getPropertyValue('mask-composite');

  /** Sets the value of "mask-composite" */
  set maskComposite(String value) {
    setProperty('mask-composite', value, '');
  }

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

  /** Sets the value of "mask-image" */
  set maskImage(String value) {
    setProperty('mask-image', value, '');
  }

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

  /** Sets the value of "mask-origin" */
  set maskOrigin(String value) {
    setProperty('mask-origin', value, '');
  }

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

  /** Sets the value of "mask-position" */
  set maskPosition(String value) {
    setProperty('mask-position', value, '');
  }

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

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

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

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

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

  /** Sets the value of "mask-repeat" */
  set maskRepeat(String value) {
    setProperty('mask-repeat', value, '');
  }

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

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

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

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

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

  /** Sets the value of "mask-size" */
  set maskSize(String value) {
    setProperty('mask-size', value, '');
  }

  /** Gets the value of "mask-source-type" */
  String get maskSourceType =>
    getPropertyValue('mask-source-type');

  /** Sets the value of "mask-source-type" */
  set maskSourceType(String value) {
    setProperty('mask-source-type', value, '');
  }

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

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

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

  /** Sets the value of "max-logical-height" */
  set maxLogicalHeight(String value) {
    setProperty('max-logical-height', value, '');
  }

  /** Gets the value of "max-logical-width" */
  String get maxLogicalWidth =>
    getPropertyValue('max-logical-width');

  /** Sets the value of "max-logical-width" */
  set maxLogicalWidth(String value) {
    setProperty('max-logical-width', value, '');
  }

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

  /** Sets the value of "max-width" */
  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" */
  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" */
  set minHeight(String value) {
    setProperty('min-height', value, '');
  }

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

  /** Sets the value of "min-logical-height" */
  set minLogicalHeight(String value) {
    setProperty('min-logical-height', value, '');
  }

  /** Gets the value of "min-logical-width" */
  String get minLogicalWidth =>
    getPropertyValue('min-logical-width');

  /** Sets the value of "min-logical-width" */
  set minLogicalWidth(String value) {
    setProperty('min-logical-width', value, '');
  }

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

  /** Sets the value of "min-width" */
  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" */
  set minZoom(String value) {
    setProperty('min-zoom', value, '');
  }

  /** Gets the value of "mix-blend-mode" */
  String get mixBlendMode =>
    getPropertyValue('mix-blend-mode');

  /** Sets the value of "mix-blend-mode" */
  set mixBlendMode(String value) {
    setProperty('mix-blend-mode', value, '');
  }

  /** Gets the value of "object-fit" */
  String get objectFit =>
    getPropertyValue('object-fit');

  /** Sets the value of "object-fit" */
  set objectFit(String value) {
    setProperty('object-fit', value, '');
  }

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

  /** Sets the value of "object-position" */
  set objectPosition(String value) {
    setProperty('object-position', value, '');
  }

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

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

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

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

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

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

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

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

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

  /** Sets the value of "outline" */
  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" */
  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" */
  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" */
  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" */
  set outlineWidth(String value) {
    setProperty('outline-width', value, '');
  }

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

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

  /** Gets the value of "overflow-wrap" */
  String get overflowWrap =>
    getPropertyValue('overflow-wrap');

  /** Sets the value of "overflow-wrap" */
  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" */
  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" */
  set overflowY(String value) {
    setProperty('overflow-y', value, '');
  }

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

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

  /** Gets the value of "padding-after" */
  String get paddingAfter =>
    getPropertyValue('padding-after');

  /** Sets the value of "padding-after" */
  set paddingAfter(String value) {
    setProperty('padding-after', value, '');
  }

  /** Gets the value of "padding-before" */
  String get paddingBefore =>
    getPropertyValue('padding-before');

  /** Sets the value of "padding-before" */
  set paddingBefore(String value) {
    setProperty('padding-before', value, '');
  }

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

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

  /** Gets the value of "padding-end" */
  String get paddingEnd =>
    getPropertyValue('padding-end');

  /** Sets the value of "padding-end" */
  set paddingEnd(String value) {
    setProperty('padding-end', value, '');
  }

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

  /** Sets the value of "padding-left" */
  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" */
  set paddingRight(String value) {
    setProperty('padding-right', value, '');
  }

  /** Gets the value of "padding-start" */
  String get paddingStart =>
    getPropertyValue('padding-start');

  /** Sets the value of "padding-start" */
  set paddingStart(String value) {
    setProperty('padding-start', value, '');
  }

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

  /** Sets the value of "padding-top" */
  set paddingTop(String value) {
    setProperty('padding-top', value, '');
  }

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

  /** Sets the value of "page" */
  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" */
  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" */
  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" */
  set pageBreakInside(String value) {
    setProperty('page-break-inside', value, '');
  }

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

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

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

  /** Sets the value of "perspective-origin" */
  set perspectiveOrigin(String value) {
    setProperty('perspective-origin', value, '');
  }

  /** Gets the value of "perspective-origin-x" */
  String get perspectiveOriginX =>
    getPropertyValue('perspective-origin-x');

  /** Sets the value of "perspective-origin-x" */
  set perspectiveOriginX(String value) {
    setProperty('perspective-origin-x', value, '');
  }

  /** Gets the value of "perspective-origin-y" */
  String get perspectiveOriginY =>
    getPropertyValue('perspective-origin-y');

  /** Sets the value of "perspective-origin-y" */
  set perspectiveOriginY(String value) {
    setProperty('perspective-origin-y', value, '');
  }

  /** Gets the value of "pointer-events" */
  String get pointerEvents =>
    getPropertyValue('pointer-events');

  /** Sets the value of "pointer-events" */
  set pointerEvents(String value) {
    setProperty('pointer-events', value, '');
  }

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

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

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

  /** Sets the value of "print-color-adjust" */
  set printColorAdjust(String value) {
    setProperty('print-color-adjust', value, '');
  }

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

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

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

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

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

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

  /** Gets the value of "rtl-ordering" */
  String get rtlOrdering =>
    getPropertyValue('rtl-ordering');

  /** Sets the value of "rtl-ordering" */
  set rtlOrdering(String value) {
    setProperty('rtl-ordering', value, '');
  }

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

  /** Sets the value of "ruby-position" */
  set rubyPosition(String value) {
    setProperty('ruby-position', value, '');
  }

  /** Gets the value of "scroll-behavior" */
  String get scrollBehavior =>
    getPropertyValue('scroll-behavior');

  /** Sets the value of "scroll-behavior" */
  set scrollBehavior(String value) {
    setProperty('scroll-behavior', value, '');
  }

  /** Gets the value of "shape-image-threshold" */
  String get shapeImageThreshold =>
    getPropertyValue('shape-image-threshold');

  /** Sets the value of "shape-image-threshold" */
  set shapeImageThreshold(String value) {
    setProperty('shape-image-threshold', value, '');
  }

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

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

  /** Gets the value of "shape-outside" */
  String get shapeOutside =>
    getPropertyValue('shape-outside');

  /** Sets the value of "shape-outside" */
  set shapeOutside(String value) {
    setProperty('shape-outside', value, '');
  }

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

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

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

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

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

  /** Sets the value of "src" */
  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" */
  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" */
  set tableLayout(String value) {
    setProperty('table-layout', value, '');
  }

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

  /** Sets the value of "tap-highlight-color" */
  set tapHighlightColor(String value) {
    setProperty('tap-highlight-color', value, '');
  }

  /** Gets the value of "text-align" */
  String get textAlign =>
    getPropertyValue('text-align');

  /** Sets the value of "text-align" */
  set textAlign(String value) {
    setProperty('text-align', value, '');
  }

  /** Gets the value of "text-align-last" */
  String get textAlignLast =>
    getPropertyValue('text-align-last');

  /** Sets the value of "text-align-last" */
  set textAlignLast(String value) {
    setProperty('text-align-last', value, '');
  }

  /** Gets the value of "text-combine" */
  String get textCombine =>
    getPropertyValue('text-combine');

  /** Sets the value of "text-combine" */
  set textCombine(String value) {
    setProperty('text-combine', value, '');
  }

  /** Gets the value of "text-decoration" */
  String get textDecoration =>
    getPropertyValue('text-decoration');

  /** Sets the value of "text-decoration" */
  set textDecoration(String value) {
    setProperty('text-decoration', value, '');
  }

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

  /** Sets the value of "text-decoration-color" */
  set textDecorationColor(String value) {
    setProperty('text-decoration-color', value, '');
  }

  /** Gets the value of "text-decoration-line" */
  String get textDecorationLine =>
    getPropertyValue('text-decoration-line');

  /** Sets the value of "text-decoration-line" */
  set textDecorationLine(String value) {
    setProperty('text-decoration-line', value, '');
  }

  /** Gets the value of "text-decoration-style" */
  String get textDecorationStyle =>
    getPropertyValue('text-decoration-style');

  /** Sets the value of "text-decoration-style" */
  set textDecorationStyle(String value) {
    setProperty('text-decoration-style', value, '');
  }

  /** Gets the value of "text-decorations-in-effect" */
  String get textDecorationsInEffect =>
    getPropertyValue('text-decorations-in-effect');

  /** Sets the value of "text-decorations-in-effect" */
  set textDecorationsInEffect(String value) {
    setProperty('text-decorations-in-effect', value, '');
  }

  /** Gets the value of "text-emphasis" */
  String get textEmphasis =>
    getPropertyValue('text-emphasis');

  /** Sets the value of "text-emphasis" */
  set textEmphasis(String value) {
    setProperty('text-emphasis', value, '');
  }

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

  /** Sets the value of "text-emphasis-color" */
  set textEmphasisColor(String value) {
    setProperty('text-emphasis-color', value, '');
  }

  /** Gets the value of "text-emphasis-position" */
  String get textEmphasisPosition =>
    getPropertyValue('text-emphasis-position');

  /** Sets the value of "text-emphasis-position" */
  set textEmphasisPosition(String value) {
    setProperty('text-emphasis-position', value, '');
  }

  /** Gets the value of "text-emphasis-style" */
  String get textEmphasisStyle =>
    getPropertyValue('text-emphasis-style');

  /** Sets the value of "text-emphasis-style" */
  set textEmphasisStyle(String value) {
    setProperty('text-emphasis-style', value, '');
  }

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

  /** Sets the value of "text-fill-color" */
  set textFillColor(String value) {
    setProperty('text-fill-color', value, '');
  }

  /** Gets the value of "text-indent" */
  String get textIndent =>
    getPropertyValue('text-indent');

  /** Sets the value of "text-indent" */
  set textIndent(String value) {
    setProperty('text-indent', value, '');
  }

  /** Gets the value of "text-justify" */
  String get textJustify =>
    getPropertyValue('text-justify');

  /** Sets the value of "text-justify" */
  set textJustify(String value) {
    setProperty('text-justify', 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" */
  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" */
  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" */
  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" */
  set textLineThroughWidth(String value) {
    setProperty('text-line-through-width', value, '');
  }

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

  /** Sets the value of "text-orientation" */
  set textOrientation(String value) {
    setProperty('text-orientation', value, '');
  }

  /** Gets the value of "text-overflow" */
  String get textOverflow =>
    getPropertyValue('text-overflow');

  /** Sets the value of "text-overflow" */
  set textOverflow(String value) {
    setProperty('text-overflow', value, '');
  }

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

  /** Sets the value of "text-overline-color" */
  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" */
  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" */
  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" */
  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" */
  set textRendering(String value) {
    setProperty('text-rendering', value, '');
  }

  /** Gets the value of "text-security" */
  String get textSecurity =>
    getPropertyValue('text-security');

  /** Sets the value of "text-security" */
  set textSecurity(String value) {
    setProperty('text-security', value, '');
  }

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

  /** Sets the value of "text-shadow" */
  set textShadow(String value) {
    setProperty('text-shadow', value, '');
  }

  /** Gets the value of "text-stroke" */
  String get textStroke =>
    getPropertyValue('text-stroke');

  /** Sets the value of "text-stroke" */
  set textStroke(String value) {
    setProperty('text-stroke', value, '');
  }

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

  /** Sets the value of "text-stroke-color" */
  set textStrokeColor(String value) {
    setProperty('text-stroke-color', value, '');
  }

  /** Gets the value of "text-stroke-width" */
  String get textStrokeWidth =>
    getPropertyValue('text-stroke-width');

  /** Sets the value of "text-stroke-width" */
  set textStrokeWidth(String value) {
    setProperty('text-stroke-width', value, '');
  }

  /** Gets the value of "text-transform" */
  String get textTransform =>
    getPropertyValue('text-transform');

  /** Sets the value of "text-transform" */
  set textTransform(String value) {
    setProperty('text-transform', value, '');
  }

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

  /** Sets the value of "text-underline-color" */
  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" */
  set textUnderlineMode(String value) {
    setProperty('text-underline-mode', value, '');
  }

  /** Gets the value of "text-underline-position" */
  String get textUnderlinePosition =>
    getPropertyValue('text-underline-position');

  /** Sets the value of "text-underline-position" */
  set textUnderlinePosition(String value) {
    setProperty('text-underline-position', value, '');
  }

  /** Gets the value of "text-underline-style" */
  String get textUnderlineStyle =>
    getPropertyValue('text-underline-style');

  /** Sets the value of "text-underline-style" */
  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" */
  set textUnderlineWidth(String value) {
    setProperty('text-underline-width', value, '');
  }

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

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

  /** Gets the value of "touch-action" */
  String get touchAction =>
    getPropertyValue('touch-action');

  /** Sets the value of "touch-action" */
  set touchAction(String value) {
    setProperty('touch-action', value, '');
  }

  /** Gets the value of "touch-action-delay" */
  String get touchActionDelay =>
    getPropertyValue('touch-action-delay');

  /** Sets the value of "touch-action-delay" */
  set touchActionDelay(String value) {
    setProperty('touch-action-delay', value, '');
  }

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

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

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

  /** Sets the value of "transform-origin" */
  set transformOrigin(String value) {
    setProperty('transform-origin', value, '');
  }

  /** Gets the value of "transform-origin-x" */
  String get transformOriginX =>
    getPropertyValue('transform-origin-x');

  /** Sets the value of "transform-origin-x" */
  set transformOriginX(String value) {
    setProperty('transform-origin-x', value, '');
  }

  /** Gets the value of "transform-origin-y" */
  String get transformOriginY =>
    getPropertyValue('transform-origin-y');

  /** Sets the value of "transform-origin-y" */
  set transformOriginY(String value) {
    setProperty('transform-origin-y', value, '');
  }

  /** Gets the value of "transform-origin-z" */
  String get transformOriginZ =>
    getPropertyValue('transform-origin-z');

  /** Sets the value of "transform-origin-z" */
  set transformOriginZ(String value) {
    setProperty('transform-origin-z', value, '');
  }

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

  /** Sets the value of "transform-style" */
  set transformStyle(String value) {
    setProperty('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('transition');

  /** Sets the value of "transition" */@SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  set transition(String value) {
    setProperty('transition', value, '');
  }

  /** Gets the value of "transition-delay" */
  String get transitionDelay =>
    getPropertyValue('transition-delay');

  /** Sets the value of "transition-delay" */
  set transitionDelay(String value) {
    setProperty('transition-delay', value, '');
  }

  /** Gets the value of "transition-duration" */
  String get transitionDuration =>
    getPropertyValue('transition-duration');

  /** Sets the value of "transition-duration" */
  set transitionDuration(String value) {
    setProperty('transition-duration', value, '');
  }

  /** Gets the value of "transition-property" */
  String get transitionProperty =>
    getPropertyValue('transition-property');

  /** Sets the value of "transition-property" */
  set transitionProperty(String value) {
    setProperty('transition-property', value, '');
  }

  /** Gets the value of "transition-timing-function" */
  String get transitionTimingFunction =>
    getPropertyValue('transition-timing-function');

  /** Sets the value of "transition-timing-function" */
  set transitionTimingFunction(String value) {
    setProperty('transition-timing-function', value, '');
  }

  /** Gets the value of "unicode-bidi" */
  String get unicodeBidi =>
    getPropertyValue('unicode-bidi');

  /** Sets the value of "unicode-bidi" */
  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" */
  set unicodeRange(String value) {
    setProperty('unicode-range', value, '');
  }

  /** Gets the value of "user-drag" */
  String get userDrag =>
    getPropertyValue('user-drag');

  /** Sets the value of "user-drag" */
  set userDrag(String value) {
    setProperty('user-drag', value, '');
  }

  /** Gets the value of "user-modify" */
  String get userModify =>
    getPropertyValue('user-modify');

  /** Sets the value of "user-modify" */
  set userModify(String value) {
    setProperty('user-modify', value, '');
  }

  /** Gets the value of "user-select" */
  String get userSelect =>
    getPropertyValue('user-select');

  /** Sets the value of "user-select" */
  set userSelect(String value) {
    setProperty('user-select', value, '');
  }

  /** Gets the value of "user-zoom" */
  String get userZoom =>
    getPropertyValue('user-zoom');

  /** Sets the value of "user-zoom" */
  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" */
  set verticalAlign(String value) {
    setProperty('vertical-align', value, '');
  }

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

  /** Sets the value of "visibility" */
  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" */
  set whiteSpace(String value) {
    setProperty('white-space', value, '');
  }

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

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

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

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

  /** Gets the value of "will-change" */
  String get willChange =>
    getPropertyValue('will-change');

  /** Sets the value of "will-change" */
  set willChange(String value) {
    setProperty('will-change', value, '');
  }

  /** Gets the value of "word-break" */
  String get wordBreak =>
    getPropertyValue('word-break');

  /** Sets the value of "word-break" */
  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" */
  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" */
  set wordWrap(String value) {
    setProperty('word-wrap', value, '');
  }

  /** Gets the value of "wrap-flow" */
  String get wrapFlow =>
    getPropertyValue('wrap-flow');

  /** Sets the value of "wrap-flow" */
  set wrapFlow(String value) {
    setProperty('wrap-flow', value, '');
  }

  /** Gets the value of "wrap-through" */
  String get wrapThrough =>
    getPropertyValue('wrap-through');

  /** Sets the value of "wrap-through" */
  set wrapThrough(String value) {
    setProperty('wrap-through', value, '');
  }

  /** Gets the value of "writing-mode" */
  String get writingMode =>
    getPropertyValue('writing-mode');

  /** Sets the value of "writing-mode" */
  set writingMode(String value) {
    setProperty('writing-mode', value, '');
  }

  /** Gets the value of "z-index" */
  String get zIndex =>
    getPropertyValue('z-index');

  /** Sets the value of "z-index" */
  set zIndex(String value) {
    setProperty('z-index', value, '');
  }

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

  /** Sets the value of "zoom" */
  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')
@Native("CSSStyleRule")
class CssStyleRule extends CssRule {
  // 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')
@Native("CSSStyleSheet")
class CssStyleSheet extends StyleSheet {
  // 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')
@Native("CSSSupportsRule")
class CssSupportsRule extends CssRule {
  // 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
@Native("CSSViewportRule")
class CssViewportRule extends CssRule {
  // 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')
@Native("CustomEvent")
class CustomEvent extends Event {
    @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')
@Native("HTMLDListElement")
class DListElement extends HtmlElement {
  // 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)
@Native("HTMLDataListElement")
class DataListElement extends HtmlElement {
  // 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('DataTransfer')
@Experimental() // untriaged
@Native("DataTransfer")
class DataTransfer extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DataTransfer._() { throw new UnsupportedError("Not supported"); }

  @DomName('DataTransfer.dropEffect')
  @DocsEditable()
  @Experimental() // untriaged
  String dropEffect;

  @DomName('DataTransfer.effectAllowed')
  @DocsEditable()
  @Experimental() // untriaged
  String effectAllowed;

  @DomName('DataTransfer.files')
  @DocsEditable()
  @Experimental() // untriaged
  @Returns('FileList')
  @Creates('FileList')
  final List<File> files;

  @DomName('DataTransfer.items')
  @DocsEditable()
  @Experimental() // untriaged
  final DataTransferItemList items;

  @DomName('DataTransfer.types')
  @DocsEditable()
  @Experimental() // untriaged
  final List<String> types;

  @DomName('DataTransfer.clearData')
  @DocsEditable()
  @Experimental() // untriaged
  void clearData([String type]) native;

  @DomName('DataTransfer.getData')
  @DocsEditable()
  @Experimental() // untriaged
  String getData(String type) native;

  @DomName('DataTransfer.setData')
  @DocsEditable()
  @Experimental() // untriaged
  void setData(String type, String data) native;

  @DomName('DataTransfer.setDragImage')
  @DocsEditable()
  @Experimental() // untriaged
  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()
@Native("DataTransferItem")
class DataTransferItem extends Interceptor {
  // 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()
@Native("DataTransferItemList")
class DataTransferItemList extends Interceptor {
  // 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(SqlDatabase 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
@Native("DedicatedWorkerGlobalScope")
class DedicatedWorkerGlobalScope extends WorkerGlobalScope {
  // 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> transfer]) 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
@Native("DeprecatedStorageInfo")
class DeprecatedStorageInfo extends Interceptor {
  // 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
@Native("DeprecatedStorageQuota")
class DeprecatedStorageQuota extends Interceptor {
  // 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()
@Native("HTMLDetailsElement")
class DetailsElement extends HtmlElement {
  // 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()
@Native("DeviceAcceleration")
class DeviceAcceleration extends Interceptor {
  // 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('DeviceLightEvent')
@Experimental() // untriaged
@Native("DeviceLightEvent")
class DeviceLightEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory DeviceLightEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('DeviceLightEvent.value')
  @DocsEditable()
  @Experimental() // untriaged
  final double 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('DeviceMotionEvent')
// http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
@Experimental()
@Native("DeviceMotionEvent")
class DeviceMotionEvent extends Event {
  // 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()
@Native("DeviceOrientationEvent")
class DeviceOrientationEvent extends Event {
  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()
@Native("DeviceRotationRate")
class DeviceRotationRate extends Interceptor {
  // 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()
@Native("HTMLDialogElement")
class DialogElement extends HtmlElement {
  // 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()
@Native("DirectoryEntry")
class DirectoryEntry extends Entry {

  /**
   * 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_1 = convertDartToNative_Dictionary(options);
      __getDirectory_2(path, options_1, successCallback);
      return;
    }
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      __getDirectory_3(path, options_1);
      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_1 = convertDartToNative_Dictionary(options);
      __getFile_2(path, options_1, successCallback);
      return;
    }
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      __getFile_3(path, options_1);
      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()
@Native("DirectoryReader")
class DirectoryReader extends Interceptor {
  // 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')
@Native("HTMLDivElement")
class DivElement extends HtmlElement {
  // 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')
@Native("Document")
class Document extends Node
{

  // To suppress missing implicit constructor warnings.
  factory Document._() { throw new UnsupportedError("Not supported"); }

  @DomName('Document.pointerlockchangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> pointerLockChangeEvent = const EventStreamProvider<Event>('pointerlockchange');

  @DomName('Document.pointerlockerrorEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> pointerLockErrorEvent = const EventStreamProvider<Event>('pointerlockerror');

  /**
   * 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');

  @DomName('Document.activeElement')
  @DocsEditable()
  @Experimental() // untriaged
  final Element activeElement;

  @JSName('body')
  @DomName('Document.body')
  @DocsEditable()
  HtmlElement _body;

  @DomName('Document.contentType')
  @DocsEditable()
  @Experimental() // untriaged
  final String contentType;

  @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;

  @DomName('Document.fullscreenElement')
  @DocsEditable()
  @Experimental() // untriaged
  final Element fullscreenElement;

  @DomName('Document.fullscreenEnabled')
  @DocsEditable()
  @Experimental() // untriaged
  final bool fullscreenEnabled;

  @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;

  @DomName('Document.pointerLockElement')
  @DocsEditable()
  @Experimental() // untriaged
  final Element pointerLockElement;

  @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 AnimationTimeline 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('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;

  @JSName('createElementNS')
  @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, num pageX, num pageY, num screenX, num screenY, num webkitRadiusX, num 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('createTouchList')
  @DomName('Document.createTouchList')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  TouchList _createTouchList(Touch touches) 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;

  @DomName('Document.exitFullscreen')
  @DocsEditable()
  @Experimental() // untriaged
  void exitFullscreen() native;

  @DomName('Document.exitPointerLock')
  @DocsEditable()
  @Experimental() // untriaged
  void exitPointerLock() native;

  @JSName('getCSSCanvasContext')
  @DomName('Document.getCSSCanvasContext')
  @DocsEditable()
  // https://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariCSSRef/Articles/Functions.html
  @Experimental() // non-standard
  Object _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()
  @Creates('NodeList|HtmlCollection')
  @Returns('NodeList|HtmlCollection')
  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;

  @DomName('Document.transformDocumentToTreeView')
  @DocsEditable()
  @Experimental() // untriaged
  void transformDocumentToTreeView(String noStyleMessage) 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;

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

  /**
   * 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;

  /// 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);

  @DomName('Document.oncanplay')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onCanPlay => Element.canPlayEvent.forTarget(this);

  @DomName('Document.oncanplaythrough')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onCanPlayThrough => Element.canPlayThroughEvent.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);

  @DomName('Document.ondurationchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onDurationChange => Element.durationChangeEvent.forTarget(this);

  @DomName('Document.onemptied')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onEmptied => Element.emptiedEvent.forTarget(this);

  @DomName('Document.onended')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onEnded => Element.endedEvent.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);

  @DomName('Document.onloadeddata')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onLoadedData => Element.loadedDataEvent.forTarget(this);

  @DomName('Document.onloadedmetadata')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onLoadedMetadata => Element.loadedMetadataEvent.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);

  @DomName('Document.onpause')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onPause => Element.pauseEvent.forTarget(this);

  @DomName('Document.onplay')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onPlay => Element.playEvent.forTarget(this);

  @DomName('Document.onplaying')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onPlaying => Element.playingEvent.forTarget(this);

  @DomName('Document.onpointerlockchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onPointerLockChange => pointerLockChangeEvent.forTarget(this);

  @DomName('Document.onpointerlockerror')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onPointerLockError => pointerLockErrorEvent.forTarget(this);

  @DomName('Document.onratechange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onRateChange => Element.rateChangeEvent.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);

  @DomName('Document.onseeked')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSeeked => Element.seekedEvent.forTarget(this);

  @DomName('Document.onseeking')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSeeking => Element.seekingEvent.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);

  @DomName('Document.onstalled')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onStalled => Element.stalledEvent.forTarget(this);

  /// Stream of `submit` events handled by this [Document].
  @DomName('Document.onsubmit')
  @DocsEditable()
  Stream<Event> get onSubmit => Element.submitEvent.forTarget(this);

  @DomName('Document.onsuspend')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSuspend => Element.suspendEvent.forTarget(this);

  @DomName('Document.ontimeupdate')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onTimeUpdate => Element.timeUpdateEvent.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);

  @DomName('Document.onvolumechange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onVolumeChange => Element.volumeChangeEvent.forTarget(this);

  @DomName('Document.onwaiting')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onWaiting => Element.waitingEvent.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);

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

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

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

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

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

  @DomName('Document.createElement')
  Element createElement(String tagName, [String typeExtension]) {
    if (typeExtension == null) {
      return _createElement_2(tagName);
    } else {
      return _createElement(tagName, typeExtension);
    }
  }

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

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

  @DomName('Document.createElementNS')
  @DocsEditable()
  Element createElementNS(String namespaceURI, String qualifiedName, [String typeExtension]) {
    if (typeExtension == null) {
      return _createElementNS_2(namespaceURI, qualifiedName);
    } else {
      return _createElementNS(namespaceURI, qualifiedName, 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')
@Native("DocumentFragment")
class DocumentFragment extends Node implements ParentNode {
  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;
  }

  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<Element> 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;
  }

  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, {NodeValidator validator,
      NodeTreeSanitizer, treeSanitizer}) {
    this.append(new DocumentFragment.html(text, validator: validator,
        treeSanitizer: treeSanitizer));
  }

  /** 
   * 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<Element> queryAll(String relativeSelectors) {
    return querySelectorAll(relativeSelectors);
  }
  // To suppress missing implicit constructor warnings.
  factory DocumentFragment._() { throw new UnsupportedError("Not supported"); }

  @DomName('DocumentFragment.getElementById')
  @DocsEditable()
  @Experimental() // untriaged
  Element getElementById(String elementId) 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;

  /**
   * 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;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All 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')
@Native("DOMError")
class DomError extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomError._() { throw new UnsupportedError("Not supported"); }

  @DomName('DOMError.DOMError')
  @DocsEditable()
  factory DomError(String name, [String message]) {
    if (message != null) {
      return DomError._create_1(name, message);
    }
    return DomError._create_2(name);
  }
  static DomError _create_1(name, message) => JS('DomError', 'new DOMError(#,#)', name, message);
  static DomError _create_2(name) => JS('DomError', 'new DOMError(#)', name);

  @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()
@Native("DOMException")
class DomException extends Interceptor {

  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() => JS('String', 'String(#)', 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('DOMImplementation')
@Native("DOMImplementation")
class DomImplementation extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomImplementation._() { throw new UnsupportedError("Not supported"); }

  @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('Iterator')
@Experimental() // untriaged
@Native("Iterator")
class DomIterator extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomIterator._() { throw new UnsupportedError("Not supported"); }

  @DomName('Iterator.next')
  @DocsEditable()
  @Experimental() // untriaged
  Object next([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('DOMMatrix')
@Experimental() // untriaged
@Native("DOMMatrix")
class DomMatrix extends DomMatrixReadOnly {
  // To suppress missing implicit constructor warnings.
  factory DomMatrix._() { throw new UnsupportedError("Not supported"); }

  @DomName('DOMMatrix.DOMMatrix')
  @DocsEditable()
  factory DomMatrix([DomMatrixReadOnly other]) {
    if (other == null) {
      return DomMatrix._create_1();
    }
    if ((other is DomMatrixReadOnly || other == null)) {
      return DomMatrix._create_2(other);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static DomMatrix _create_1() => JS('DomMatrix', 'new DOMMatrix()');
  static DomMatrix _create_2(other) => JS('DomMatrix', 'new DOMMatrix(#)', other);

  // Shadowing definition.
  num get a => JS("num", "#.a", this);

  set a(num value) {
    JS("void", "#.a = #", this, value);
  }

  // Shadowing definition.
  num get b => JS("num", "#.b", this);

  set b(num value) {
    JS("void", "#.b = #", this, value);
  }

  // Shadowing definition.
  num get c => JS("num", "#.c", this);

  set c(num value) {
    JS("void", "#.c = #", this, value);
  }

  // Shadowing definition.
  num get d => JS("num", "#.d", this);

  set d(num value) {
    JS("void", "#.d = #", this, value);
  }

  // Shadowing definition.
  num get e => JS("num", "#.e", this);

  set e(num value) {
    JS("void", "#.e = #", this, value);
  }

  // Shadowing definition.
  num get f => JS("num", "#.f", this);

  set f(num value) {
    JS("void", "#.f = #", this, value);
  }

  // Shadowing definition.
  num get m11 => JS("num", "#.m11", this);

  set m11(num value) {
    JS("void", "#.m11 = #", this, value);
  }

  // Shadowing definition.
  num get m12 => JS("num", "#.m12", this);

  set m12(num value) {
    JS("void", "#.m12 = #", this, value);
  }

  // Shadowing definition.
  num get m13 => JS("num", "#.m13", this);

  set m13(num value) {
    JS("void", "#.m13 = #", this, value);
  }

  // Shadowing definition.
  num get m14 => JS("num", "#.m14", this);

  set m14(num value) {
    JS("void", "#.m14 = #", this, value);
  }

  // Shadowing definition.
  num get m21 => JS("num", "#.m21", this);

  set m21(num value) {
    JS("void", "#.m21 = #", this, value);
  }

  // Shadowing definition.
  num get m22 => JS("num", "#.m22", this);

  set m22(num value) {
    JS("void", "#.m22 = #", this, value);
  }

  // Shadowing definition.
  num get m23 => JS("num", "#.m23", this);

  set m23(num value) {
    JS("void", "#.m23 = #", this, value);
  }

  // Shadowing definition.
  num get m24 => JS("num", "#.m24", this);

  set m24(num value) {
    JS("void", "#.m24 = #", this, value);
  }

  // Shadowing definition.
  num get m31 => JS("num", "#.m31", this);

  set m31(num value) {
    JS("void", "#.m31 = #", this, value);
  }

  // Shadowing definition.
  num get m32 => JS("num", "#.m32", this);

  set m32(num value) {
    JS("void", "#.m32 = #", this, value);
  }

  // Shadowing definition.
  num get m33 => JS("num", "#.m33", this);

  set m33(num value) {
    JS("void", "#.m33 = #", this, value);
  }

  // Shadowing definition.
  num get m34 => JS("num", "#.m34", this);

  set m34(num value) {
    JS("void", "#.m34 = #", this, value);
  }

  // Shadowing definition.
  num get m41 => JS("num", "#.m41", this);

  set m41(num value) {
    JS("void", "#.m41 = #", this, value);
  }

  // Shadowing definition.
  num get m42 => JS("num", "#.m42", this);

  set m42(num value) {
    JS("void", "#.m42 = #", this, value);
  }

  // Shadowing definition.
  num get m43 => JS("num", "#.m43", this);

  set m43(num value) {
    JS("void", "#.m43 = #", this, value);
  }

  // Shadowing definition.
  num get m44 => JS("num", "#.m44", this);

  set m44(num value) {
    JS("void", "#.m44 = #", this, value);
  }

  @DomName('DOMMatrix.multiplySelf')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix multiplySelf(DomMatrix other) native;

  @DomName('DOMMatrix.preMultiplySelf')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix preMultiplySelf(DomMatrix other) native;

  @DomName('DOMMatrix.scale3dSelf')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix scale3dSelf(num scale, [num ox, num oy, num oz]) native;

  @DomName('DOMMatrix.scaleNonUniformSelf')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix scaleNonUniformSelf(num sx, [num sy, num sz, num ox, num oy, num oz]) native;

  @DomName('DOMMatrix.scaleSelf')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix scaleSelf(num scale, [num ox, num oy]) native;

  @DomName('DOMMatrix.translateSelf')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix translateSelf(num tx, num ty, [num tz]) 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('DOMMatrixReadOnly')
@Experimental() // untriaged
@Native("DOMMatrixReadOnly")
class DomMatrixReadOnly extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomMatrixReadOnly._() { throw new UnsupportedError("Not supported"); }

  @DomName('DOMMatrixReadOnly.a')
  @DocsEditable()
  @Experimental() // untriaged
  final double a;

  @DomName('DOMMatrixReadOnly.b')
  @DocsEditable()
  @Experimental() // untriaged
  final double b;

  @DomName('DOMMatrixReadOnly.c')
  @DocsEditable()
  @Experimental() // untriaged
  final double c;

  @DomName('DOMMatrixReadOnly.d')
  @DocsEditable()
  @Experimental() // untriaged
  final double d;

  @DomName('DOMMatrixReadOnly.e')
  @DocsEditable()
  @Experimental() // untriaged
  final double e;

  @DomName('DOMMatrixReadOnly.f')
  @DocsEditable()
  @Experimental() // untriaged
  final double f;

  @DomName('DOMMatrixReadOnly.is2D')
  @DocsEditable()
  @Experimental() // untriaged
  final bool is2D;

  @DomName('DOMMatrixReadOnly.isIdentity')
  @DocsEditable()
  @Experimental() // untriaged
  final bool isIdentity;

  @DomName('DOMMatrixReadOnly.m11')
  @DocsEditable()
  @Experimental() // untriaged
  final double m11;

  @DomName('DOMMatrixReadOnly.m12')
  @DocsEditable()
  @Experimental() // untriaged
  final double m12;

  @DomName('DOMMatrixReadOnly.m13')
  @DocsEditable()
  @Experimental() // untriaged
  final double m13;

  @DomName('DOMMatrixReadOnly.m14')
  @DocsEditable()
  @Experimental() // untriaged
  final double m14;

  @DomName('DOMMatrixReadOnly.m21')
  @DocsEditable()
  @Experimental() // untriaged
  final double m21;

  @DomName('DOMMatrixReadOnly.m22')
  @DocsEditable()
  @Experimental() // untriaged
  final double m22;

  @DomName('DOMMatrixReadOnly.m23')
  @DocsEditable()
  @Experimental() // untriaged
  final double m23;

  @DomName('DOMMatrixReadOnly.m24')
  @DocsEditable()
  @Experimental() // untriaged
  final double m24;

  @DomName('DOMMatrixReadOnly.m31')
  @DocsEditable()
  @Experimental() // untriaged
  final double m31;

  @DomName('DOMMatrixReadOnly.m32')
  @DocsEditable()
  @Experimental() // untriaged
  final double m32;

  @DomName('DOMMatrixReadOnly.m33')
  @DocsEditable()
  @Experimental() // untriaged
  final double m33;

  @DomName('DOMMatrixReadOnly.m34')
  @DocsEditable()
  @Experimental() // untriaged
  final double m34;

  @DomName('DOMMatrixReadOnly.m41')
  @DocsEditable()
  @Experimental() // untriaged
  final double m41;

  @DomName('DOMMatrixReadOnly.m42')
  @DocsEditable()
  @Experimental() // untriaged
  final double m42;

  @DomName('DOMMatrixReadOnly.m43')
  @DocsEditable()
  @Experimental() // untriaged
  final double m43;

  @DomName('DOMMatrixReadOnly.m44')
  @DocsEditable()
  @Experimental() // untriaged
  final double m44;

  @DomName('DOMMatrixReadOnly.multiply')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix multiply(DomMatrix other) native;

  @DomName('DOMMatrixReadOnly.scale')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix scale(num scale, [num ox, num oy]) native;

  @DomName('DOMMatrixReadOnly.scale3d')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix scale3d(num scale, [num ox, num oy, num oz]) native;

  @DomName('DOMMatrixReadOnly.scaleNonUniform')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix scaleNonUniform(num sx, [num sy, num sz, num ox, num oy, num oz]) native;

  @DomName('DOMMatrixReadOnly.toFloat32Array')
  @DocsEditable()
  @Experimental() // untriaged
  Float32List toFloat32Array() native;

  @DomName('DOMMatrixReadOnly.toFloat64Array')
  @DocsEditable()
  @Experimental() // untriaged
  Float64List toFloat64Array() native;

  @DomName('DOMMatrixReadOnly.translate')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix translate(num tx, num ty, [num tz]) 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')
@Native("DOMParser")
class DomParser extends Interceptor {
  // 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('DOMPoint')
@Experimental() // untriaged
@Native("DOMPoint")
class DomPoint extends DomPointReadOnly {
  // To suppress missing implicit constructor warnings.
  factory DomPoint._() { throw new UnsupportedError("Not supported"); }

  @DomName('DOMPoint.DOMPoint')
  @DocsEditable()
  factory DomPoint([point_OR_x, num y, num z, num w]) {
    if (point_OR_x == null && y == null && z == null && w == null) {
      return DomPoint._create_1();
    }
    if ((point_OR_x is Map || point_OR_x == null) && y == null && z == null && w == null) {
      var point_1 = convertDartToNative_Dictionary(point_OR_x);
      return DomPoint._create_2(point_1);
    }
    if ((y is num || y == null) && (point_OR_x is num || point_OR_x == null) && z == null && w == null) {
      return DomPoint._create_3(point_OR_x, y);
    }
    if ((z is num || z == null) && (y is num || y == null) && (point_OR_x is num || point_OR_x == null) && w == null) {
      return DomPoint._create_4(point_OR_x, y, z);
    }
    if ((w is num || w == null) && (z is num || z == null) && (y is num || y == null) && (point_OR_x is num || point_OR_x == null)) {
      return DomPoint._create_5(point_OR_x, y, z, w);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static DomPoint _create_1() => JS('DomPoint', 'new DOMPoint()');
  static DomPoint _create_2(point_OR_x) => JS('DomPoint', 'new DOMPoint(#)', point_OR_x);
  static DomPoint _create_3(point_OR_x, y) => JS('DomPoint', 'new DOMPoint(#,#)', point_OR_x, y);
  static DomPoint _create_4(point_OR_x, y, z) => JS('DomPoint', 'new DOMPoint(#,#,#)', point_OR_x, y, z);
  static DomPoint _create_5(point_OR_x, y, z, w) => JS('DomPoint', 'new DOMPoint(#,#,#,#)', point_OR_x, y, z, w);

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

  // Shadowing definition.
  num get w => JS("num", "#.w", this);

  set w(num value) {
    JS("void", "#.w = #", this, value);
  }

  // Shadowing definition.
  num get x => JS("num", "#.x", this);

  set x(num value) {
    JS("void", "#.x = #", this, value);
  }

  // Shadowing definition.
  num get y => JS("num", "#.y", this);

  set y(num value) {
    JS("void", "#.y = #", this, value);
  }

  // Shadowing definition.
  num get z => JS("num", "#.z", this);

  set z(num value) {
    JS("void", "#.z = #", 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.


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

  @DomName('DOMPointReadOnly.DOMPointReadOnly')
  @DocsEditable()
  factory DomPointReadOnly(num x, num y, num z, num w) {
    return DomPointReadOnly._create_1(x, y, z, w);
  }
  static DomPointReadOnly _create_1(x, y, z, w) => JS('DomPointReadOnly', 'new DOMPointReadOnly(#,#,#,#)', x, y, z, w);

  @DomName('DOMPointReadOnly.w')
  @DocsEditable()
  @Experimental() // untriaged
  final double w;

  @DomName('DOMPointReadOnly.x')
  @DocsEditable()
  @Experimental() // untriaged
  final double x;

  @DomName('DOMPointReadOnly.y')
  @DocsEditable()
  @Experimental() // untriaged
  final double y;

  @DomName('DOMPointReadOnly.z')
  @DocsEditable()
  @Experimental() // untriaged
  final double z;
}
// 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('DOMRectReadOnly')
@Experimental() // untriaged
@Native("DOMRectReadOnly")
class DomRectReadOnly extends Interceptor implements Rectangle {

  // 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 DomRectReadOnly._() { throw new UnsupportedError("Not supported"); }

  @DomName('DOMRectReadOnly.DOMRectReadOnly')
  @DocsEditable()
  factory DomRectReadOnly(num x, num y, num width, num height) {
    return DomRectReadOnly._create_1(x, y, width, height);
  }
  static DomRectReadOnly _create_1(x, y, width, height) => JS('DomRectReadOnly', 'new DOMRectReadOnly(#,#,#,#)', x, y, width, height);

  @DomName('DOMRectReadOnly.bottom')
  @DocsEditable()
  @Experimental() // untriaged
  final double bottom;

  @DomName('DOMRectReadOnly.height')
  @DocsEditable()
  @Experimental() // untriaged
  final double height;

  @DomName('DOMRectReadOnly.left')
  @DocsEditable()
  @Experimental() // untriaged
  final double left;

  @DomName('DOMRectReadOnly.right')
  @DocsEditable()
  @Experimental() // untriaged
  final double right;

  @DomName('DOMRectReadOnly.top')
  @DocsEditable()
  @Experimental() // untriaged
  final double top;

  @DomName('DOMRectReadOnly.width')
  @DocsEditable()
  @Experimental() // untriaged
  final double width;

  @DomName('DOMRectReadOnly.x')
  @DocsEditable()
  @Experimental() // untriaged
  final double x;

  @DomName('DOMRectReadOnly.y')
  @DocsEditable()
  @Experimental() // untriaged
  final double 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('DOMSettableTokenList')
@Native("DOMSettableTokenList")
class DomSettableTokenList extends DomTokenList {
  // 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')
@Native("DOMStringList")
class DomStringList extends Interceptor with ListMixin<String>, ImmutableListMixin<String> implements JavaScriptIndexingBehavior, List<String> {
  // 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.index(index, this);
    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.


  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')
@Native("DOMTokenList")
class DomTokenList extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomTokenList._() { throw new UnsupportedError("Not supported"); }

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

  @DomName('DOMTokenList.add')
  @DocsEditable()
  @Experimental() // untriaged
  void add(String tokens) native;

  @DomName('DOMTokenList.contains')
  @DocsEditable()
  bool contains(String token) native;

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

  @DomName('DOMTokenList.remove')
  @DocsEditable()
  @Experimental() // untriaged
  void remove(String tokens) 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]);
  }

  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;

  @DomName('Element.oncanplay')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onCanPlay;

  @DomName('Element.oncanplaythrough')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onCanPlayThrough;

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

  @DomName('Element.ondurationchange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onDurationChange;

  @DomName('Element.onemptied')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEmptied;

  @DomName('Element.onended')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEnded;

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

  @DomName('Element.onloadeddata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedData;

  @DomName('Element.onloadedmetadata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedMetadata;

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

  @DomName('Element.onpause')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPause;

  @DomName('Element.onplay')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPlay;

  @DomName('Element.onplaying')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPlaying;

  @DomName('Element.onratechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onRateChange;

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

  @DomName('Element.onseeked')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeked;

  @DomName('Element.onseeking')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeking;

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

  @DomName('Element.onstalled')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onStalled;

  /// Stream of `submit` events handled by this [Element].
  @DomName('Element.onsubmit')
  @DocsEditable()
  ElementStream<Event> get onSubmit;

  @DomName('Element.onsuspend')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSuspend;

  @DomName('Element.ontimeupdate')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onTimeUpdate;

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

  @DomName('Element.onvolumechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onVolumeChange;

  @DomName('Element.onwaiting')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onWaiting;

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

}

// Wrapper over an immutable NodeList to make it implement ElementList.
//
// Clients are {`Document`, `DocumentFragment`}.`querySelectorAll` which are
// declared to return `ElementList`.  This provides all the static analysis
// benefit so there is no need for this class have a constrained type parameter.
//
class _FrozenElementList extends ListBase
    implements ElementList, NodeListWrapper {
  final List<Node> _nodeList;

  _FrozenElementList._wrap(this._nodeList);

  int get length => _nodeList.length;

  Element operator [](int index) => _nodeList[index];

  void operator []=(int index, Element value) {
    throw new UnsupportedError('Cannot modify list');
  }

  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(this);

  CssStyleDeclarationBase get style =>
      new _CssStyleDeclarationSet(this);

  set classes(Iterable<String> value) {
    // TODO(sra): This might be faster for Sets:
    //
    //     new _MultiElementCssClassSet(this).writeClasses(value)
    //
    // as the code below converts the Iterable[value] to a string multiple
    // times.  Maybe compute the string and set className here.
    _nodeList.forEach((e) => e.classes = value);
  }

  CssRect get contentEdge => new _ContentCssListRect(this);

  CssRect get paddingEdge => this.first.paddingEdge;

  CssRect get borderEdge => this.first.borderEdge;

  CssRect get marginEdge => this.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);

  @DomName('Element.oncanplay')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onCanPlay => Element.canPlayEvent._forElementList(this);

  @DomName('Element.oncanplaythrough')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onCanPlayThrough => Element.canPlayThroughEvent._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);

  @DomName('Element.ondurationchange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onDurationChange => Element.durationChangeEvent._forElementList(this);

  @DomName('Element.onemptied')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEmptied => Element.emptiedEvent._forElementList(this);

  @DomName('Element.onended')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEnded => Element.endedEvent._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);

  @DomName('Element.onloadeddata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedData => Element.loadedDataEvent._forElementList(this);

  @DomName('Element.onloadedmetadata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedMetadata => Element.loadedMetadataEvent._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);

  @DomName('Element.onpause')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPause => Element.pauseEvent._forElementList(this);

  @DomName('Element.onplay')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPlay => Element.playEvent._forElementList(this);

  @DomName('Element.onplaying')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPlaying => Element.playingEvent._forElementList(this);

  @DomName('Element.onratechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onRateChange => Element.rateChangeEvent._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);

  @DomName('Element.onseeked')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeked => Element.seekedEvent._forElementList(this);

  @DomName('Element.onseeking')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeking => Element.seekingEvent._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);

  @DomName('Element.onstalled')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onStalled => Element.stalledEvent._forElementList(this);

  /// Stream of `submit` events handled by this [Element].
  @DomName('Element.onsubmit')
  @DocsEditable()
  ElementStream<Event> get onSubmit => Element.submitEvent._forElementList(this);

  @DomName('Element.onsuspend')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSuspend => Element.suspendEvent._forElementList(this);

  @DomName('Element.ontimeupdate')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onTimeUpdate => Element.timeUpdateEvent._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);

  @DomName('Element.onvolumechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onVolumeChange => Element.volumeChangeEvent._forElementList(this);

  @DomName('Element.onwaiting')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onWaiting => Element.waitingEvent._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')
@Native("Element")
class Element extends Node implements GlobalEventHandlers, ParentNode, ChildNode {

  /**
   * 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();

  /**
   * 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);

  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);

  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<Element> 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<Element> 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);

  set classes(Iterable<String> value) {
    // TODO(sra): Do this without reading the classes in clear() and addAll(),
    // or writing the classes in clear().
    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);

  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.append(new Text(text));
  }

  /**
   * Parses the specified text as HTML and adds the resulting node after the
   * last child of this element.
   */
  void appendHtml(String text, {NodeValidator validator,
      NodeTreeSanitizer treeSanitizer}) {
    this.insertAdjacentHtml('beforeend', text, validator: validator,
        treeSanitizer: treeSanitizer);
  }

  /**
   * 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() {}

  /**
   * Creates a new AnimationEffect object whose target element is the object
   * on which the method is called, and calls the play() method of the
   * AnimationTimeline object of the document timeline of the node document
   * of the element, passing the newly created AnimationEffect as the argument
   * to the method. Returns an AnimationPlayer for the effect.
   *
   * Examples
   *
   *     var animation = elem.animate([{"opacity": 75}, {"opacity": 0}], 200);
   *
   *     var animation = elem.animate([
   *       {"transform": "translate(100px, -100%)"},
   *       {"transform" : "translate(400px, 500px)"}
   *     ], 1500);
   *
   * The [frames] parameter is an Iterable<Map>, where the
   * map entries specify CSS animation effects. The
   * [timing] paramter can be a double, representing the number of milliseconds
   * for the transition, or a Map with fields corresponding to those
   * of the [Timing] object.
  **/
  @Experimental()
  @SupportedBrowser(SupportedBrowser.CHROME, '36')
  AnimationPlayer animate(Iterable<Map<String, dynamic>> frames, [timing]) {
    if (frames is! Iterable || !(frames.every((x) => x is Map))) {
      throw new ArgumentError("The frames parameter should be a List of Maps "
          "with frame information");
    }
    var convertedFrames = frames;
    if (convertedFrames is Iterable) {
      convertedFrames = frames.map(convertDartToNative_Dictionary).toList();
    }
    var convertedTiming = timing;
    if (convertedTiming is Map) {
      convertedTiming = convertDartToNative_Dictionary(convertedTiming);
    }
    return convertedTiming == null
      ? _animate(convertedFrames)
      : _animate(convertedFrames, convertedTiming);
  }

  @DomName('Element.animate')
  @JSName('animate')
  @Experimental() // untriaged
  AnimationPlayer _animate(Object effect, [timing]) native;
  /**
   * 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;

  set xtag(Element value) {
    _xtag = value;
  }

  @DomName('Element.localName')
  @DocsEditable()
  @Returns('String')
  // Non-null for Elements.
  String get localName => JS('String', '#', _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) => 'wheel';

  /**
   * 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, {NodeValidator validator,
      NodeTreeSanitizer treeSanitizer}) {
      if (treeSanitizer is _TrustedHtmlTreeSanitizer) {
        _insertAdjacentHtml(where, html);
      } else {
        _insertAdjacentNode(where, createFragment(html,
            validator: validator, treeSanitizer: treeSanitizer));
      }
  }


  @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 sameAsParent = identical(current, parent);
    bool foundAsParent = sameAsParent || parent.tagName == 'HTML';
    if (current == null || sameAsParent) {
      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 Safari bug. Was also previously 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 &&
        _canBeUsedToCreateContextualFragment) {
      _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;
  }

  /** Test if createContextualFragment is supported for this element type */
  bool get _canBeUsedToCreateContextualFragment =>
      !_cannotBeUsedToCreateContextualFragment;

  /** Test if createContextualFragment is NOT supported for this element type */
  bool get _cannotBeUsedToCreateContextualFragment =>
      _tagsForWhichCreateContextualFragmentIsNotSupported.contains(tagName);

  /**
   * A hard-coded list of the tag names for which createContextualFragment
   * isn't supported.
   */
  static const _tagsForWhichCreateContextualFragmentIsNotSupported =
      const ['HEAD', 'AREA',
      'BASE', 'BASEFONT', 'BR', 'COL', 'COLGROUP', 'EMBED', 'FRAME', 'FRAMESET',
      'HR', 'IMAGE', 'IMG', 'INPUT', 'ISINDEX', 'LINK', 'META', 'PARAM',
      'SOURCE', 'STYLE', 'TITLE', 'WBR'];

  /**
   * 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.
   */
  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;
    if (treeSanitizer is _TrustedHtmlTreeSanitizer) {
      _innerHtml = html;
    } else {
      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);

  /**
   * Verify if any of the attributes that we use in the sanitizer look unexpected,
   * possibly indicating DOM clobbering attacks.
   *
   * Those attributes are: attributes, lastChild, children, previousNode and tagName.
   */
  static bool _hasCorruptedAttributes(Element element) {
     return JS('bool', r'''
       (function(element) {
         if (!(element.attributes instanceof NamedNodeMap)) {
	   return true;
	 }
	 var childNodes = element.childNodes;
	 if (element.lastChild &&
	     element.lastChild !== childNodes[childNodes.length -1]) {
	   return true;
	 }
	 if (element.children) { // On Safari, children can apparently be null.
  	   if (!((element.children instanceof HTMLCollection) ||
               (element.children instanceof NodeList))) {
	     return true;
	   }
	 }
         var length = 0;
         if (element.children) {
           length = element.children.length;
         }
         for (var i = 0; i < length; i++) {
           var child = element.children[i];
           // On IE it seems like we sometimes don't see the clobbered attribute,
           // perhaps as a result of an over-optimization. Also use another route
           // to check of attributes, children, or lastChild are clobbered. It may
           // seem silly to check children as we rely on children to do this iteration,
           // but it seems possible that the access to children might see the real thing,
           // allowing us to check for clobbering that may show up in other accesses.
           if (child["id"] == 'attributes' || child["name"] == 'attributes' ||
               child["id"] == 'lastChild'  || child["name"] == 'lastChild' ||
               child["id"] == 'children' || child["name"] == 'children') {
             return true;
           }
         }
	 return false;
          })(#)''', element);
  }

  /// A secondary check for corruption, needed on IE
  static bool _hasCorruptedAttributesAdditionalCheck(Element element) {
    return JS('bool', r'!(#.attributes instanceof NamedNodeMap)', element);
  }

  static String _safeTagName(element) {
    String result = 'element tag unavailable';
    try {
      if (element.tagName is String) {
        result = element.tagName;
      }
    } catch (e) {}
    return result;
  }

  @DomName('Element.offsetHeight')
  @DocsEditable()
  int get offsetHeight => JS('num', '#.offsetHeight', this).round();

  @DomName('Element.offsetLeft')
  @DocsEditable()
  int get offsetLeft => JS('num', '#.offsetLeft', this).round();

  @DomName('Element.offsetTop')
  @DocsEditable()
  int get offsetTop => JS('num', '#.offsetTop', this).round();

  @DomName('Element.offsetWidth')
  @DocsEditable()
  int get offsetWidth => JS('num', '#.offsetWidth', this).round();

  @DomName('Element.clientHeight')
  @DocsEditable()
  int get clientHeight => JS('num', '#.clientHeight', this).round();

  @DomName('Element.clientLeft')
  @DocsEditable()
  int get clientLeft => JS('num', '#.clientLeft', this).round();

  @DomName('Element.clientTop')
  @DocsEditable()
  int get clientTop => JS('num', '#.clientTop', this).round();

  @DomName('Element.clientWidth')
  @DocsEditable()
  int get clientWidth => JS('num', '#.clientWidth', this).round();

  @DomName('Element.scrollHeight')
  @DocsEditable()
  int get scrollHeight => JS('num', '#.scrollHeight', this).round();

  @DomName('Element.scrollLeft')
  @DocsEditable()
  int get scrollLeft => JS('num', '#.scrollLeft', this).round();

  @DomName('Element.scrollLeft')
  @DocsEditable()
  set scrollLeft(int value) {
    JS("void", "#.scrollLeft = #", this, value.round());
  }

  @DomName('Element.scrollTop')
  @DocsEditable()
  int get scrollTop => JS('num', '#.scrollTop', this).round();

  @DomName('Element.scrollTop')
  @DocsEditable()
  set scrollTop(int value) {
    JS("void", "#.scrollTop = #", this, value.round());
  }

  @DomName('Element.scrollWidth')
  @DocsEditable()
  int get scrollWidth => JS('num', '#.scrollWidth', this).round();


  // 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');

  @DomName('Element.canplayEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> canPlayEvent = const EventStreamProvider<Event>('canplay');

  @DomName('Element.canplaythroughEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> canPlayThroughEvent = const EventStreamProvider<Event>('canplaythrough');

  /**
   * 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');

  @DomName('Element.durationchangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> durationChangeEvent = const EventStreamProvider<Event>('durationchange');

  @DomName('Element.emptiedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> emptiedEvent = const EventStreamProvider<Event>('emptied');

  @DomName('Element.endedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');

  /**
   * 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');

  @DomName('Element.loadeddataEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadedDataEvent = const EventStreamProvider<Event>('loadeddata');

  @DomName('Element.loadedmetadataEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadedMetadataEvent = const EventStreamProvider<Event>('loadedmetadata');

  /**
   * 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');

  @DomName('Element.pauseEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> pauseEvent = const EventStreamProvider<Event>('pause');

  @DomName('Element.playEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> playEvent = const EventStreamProvider<Event>('play');

  @DomName('Element.playingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> playingEvent = const EventStreamProvider<Event>('playing');

  @DomName('Element.ratechangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> rateChangeEvent = const EventStreamProvider<Event>('ratechange');

  /**
   * 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');

  @DomName('Element.seekedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> seekedEvent = const EventStreamProvider<Event>('seeked');

  @DomName('Element.seekingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> seekingEvent = const EventStreamProvider<Event>('seeking');

  /**
   * 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');

  @DomName('Element.stalledEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> stalledEvent = const EventStreamProvider<Event>('stalled');

  /**
   * 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');

  @DomName('Element.suspendEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> suspendEvent = const EventStreamProvider<Event>('suspend');

  @DomName('Element.timeupdateEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> timeUpdateEvent = const EventStreamProvider<Event>('timeupdate');

  /**
   * 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');

  @DomName('Element.volumechangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> volumeChangeEvent = const EventStreamProvider<Event>('volumechange');

  @DomName('Element.waitingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> waitingEvent = const EventStreamProvider<Event>('waiting');

  /**
   * 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.contextMenu')
  @DocsEditable()
  @Experimental() // untriaged
  MenuElement contextMenu;

  @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;

  @JSName('clientHeight')
  @DomName('Element.clientHeight')
  @DocsEditable()
  final int _clientHeight;

  @JSName('clientLeft')
  @DomName('Element.clientLeft')
  @DocsEditable()
  final int _clientLeft;

  @JSName('clientTop')
  @DomName('Element.clientTop')
  @DocsEditable()
  final int _clientTop;

  @JSName('clientWidth')
  @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;

  @JSName('offsetHeight')
  @DomName('Element.offsetHeight')
  @DocsEditable()
  final int _offsetHeight;

  @JSName('offsetLeft')
  @DomName('Element.offsetLeft')
  @DocsEditable()
  final int _offsetLeft;

  @DomName('Element.offsetParent')
  @DocsEditable()
  final Element offsetParent;

  @JSName('offsetTop')
  @DomName('Element.offsetTop')
  @DocsEditable()
  final int _offsetTop;

  @JSName('offsetWidth')
  @DomName('Element.offsetWidth')
  @DocsEditable()
  final int _offsetWidth;

  @JSName('outerHTML')
  @DomName('Element.outerHTML')
  @DocsEditable()
  final String outerHtml;

  @JSName('scrollHeight')
  @DomName('Element.scrollHeight')
  @DocsEditable()
  final int _scrollHeight;

  @JSName('scrollLeft')
  @DomName('Element.scrollLeft')
  @DocsEditable()
  num _scrollLeft;

  @JSName('scrollTop')
  @DomName('Element.scrollTop')
  @DocsEditable()
  num _scrollTop;

  @JSName('scrollWidth')
  @DomName('Element.scrollWidth')
  @DocsEditable()
  final int _scrollWidth;

  @DomName('Element.style')
  @DocsEditable()
  final CssStyleDeclaration style;

  @DomName('Element.tagName')
  @DocsEditable()
  final String tagName;

  @DomName('Element.blur')
  @DocsEditable()
  void blur() native;

  @DomName('Element.focus')
  @DocsEditable()
  void focus() native;

  @DomName('Element.getAnimationPlayers')
  @DocsEditable()
  @Experimental() // untriaged
  List<AnimationPlayer> getAnimationPlayers() 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;

  @JSName('removeAttribute')
  @DomName('Element.removeAttribute')
  @DocsEditable()
  void _removeAttribute(String name) native;

  @JSName('removeAttributeNS')
  @DomName('Element.removeAttributeNS')
  @DocsEditable()
  void _removeAttributeNS(String namespaceURI, String localName) native;

  @DomName('Element.requestFullscreen')
  @DocsEditable()
  @Experimental() // untriaged
  void requestFullscreen() native;

  @DomName('Element.requestPointerLock')
  @DocsEditable()
  @Experimental() // untriaged
  void requestPointerLock() 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;

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

  /**
   * 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;

  /// 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);

  @DomName('Element.oncanplay')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onCanPlay => canPlayEvent.forElement(this);

  @DomName('Element.oncanplaythrough')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onCanPlayThrough => canPlayThroughEvent.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);

  @DomName('Element.ondurationchange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onDurationChange => durationChangeEvent.forElement(this);

  @DomName('Element.onemptied')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEmptied => emptiedEvent.forElement(this);

  @DomName('Element.onended')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEnded => endedEvent.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);

  @DomName('Element.onloadeddata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedData => loadedDataEvent.forElement(this);

  @DomName('Element.onloadedmetadata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedMetadata => loadedMetadataEvent.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);

  @DomName('Element.onpause')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPause => pauseEvent.forElement(this);

  @DomName('Element.onplay')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPlay => playEvent.forElement(this);

  @DomName('Element.onplaying')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPlaying => playingEvent.forElement(this);

  @DomName('Element.onratechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onRateChange => rateChangeEvent.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);

  @DomName('Element.onseeked')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeked => seekedEvent.forElement(this);

  @DomName('Element.onseeking')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeking => seekingEvent.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);

  @DomName('Element.onstalled')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onStalled => stalledEvent.forElement(this);

  /// Stream of `submit` events handled by this [Element].
  @DomName('Element.onsubmit')
  @DocsEditable()
  ElementStream<Event> get onSubmit => submitEvent.forElement(this);

  @DomName('Element.onsuspend')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSuspend => suspendEvent.forElement(this);

  @DomName('Element.ontimeupdate')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onTimeUpdate => timeUpdateEvent.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);

  @DomName('Element.onvolumechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onVolumeChange => volumeChangeEvent.forElement(this);

  @DomName('Element.onwaiting')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onWaiting => waitingEvent.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()
@Native("HTMLEmbedElement")
class EmbedElement extends HtmlElement {
  // 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.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String integrity;

  @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()
@Native("Entry")
class Entry extends Interceptor {
  // 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()
@Native("ErrorEvent")
class ErrorEvent extends Event {
  // 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')
@Native("Event,InputEvent,ClipboardEvent")
class Event extends Interceptor {
  // 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.FIREFOX)
  @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
@Native("EventSource")
class EventSource extends EventTarget {
  factory EventSource(String url, {withCredentials: false}) {
    var parsedOptions = {
      'withCredentials': withCredentials,
    };
    return EventSource._factoryEventSource(url, 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) {
      var eventSourceInit_1 = convertDartToNative_Dictionary(eventSourceInit);
      return EventSource._create_1(url, eventSourceInit_1);
    }
    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')
@Native("EventTarget")
class EventTarget extends Interceptor {

  // 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);

  void addEventListener(String type, EventListener listener, [bool useCapture]) {
    // TODO(leafp): This check is avoid a bug in our dispatch code when
    // listener is null.  The browser treats this call as a no-op in this
    // case, so it's fine to short-circuit it, but we should not have to.
    if (listener != null) {
      _addEventListener(type, listener, useCapture);
    }
  }

  void removeEventListener(String type, EventListener listener, [bool useCapture]) {
    // TODO(leafp): This check is avoid a bug in our dispatch code when
    // listener is null.  The browser treats this call as a no-op in this
    // case, so it's fine to short-circuit it, but we should not have to.
    if (listener != null) {
      _removeEventListener(type, listener, useCapture);
    }
  }

  // To suppress missing implicit constructor warnings.
  factory EventTarget._() { throw new UnsupportedError("Not supported"); }

  @JSName('addEventListener')
  @DomName('EventTarget.addEventListener')
  @DocsEditable()
  void _addEventListener([String type, EventListener listener, bool useCapture]) native;

  @DomName('EventTarget.dispatchEvent')
  @DocsEditable()
  bool dispatchEvent(Event event) native;

  @JSName('removeEventListener')
  @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('ExtendableEvent')
@Experimental() // untriaged
@Native("ExtendableEvent")
class ExtendableEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory ExtendableEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('ExtendableEvent.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('FederatedCredential')
@Experimental() // untriaged
@Native("FederatedCredential")
class FederatedCredential extends Credential {
  // To suppress missing implicit constructor warnings.
  factory FederatedCredential._() { throw new UnsupportedError("Not supported"); }

  @DomName('FederatedCredential.FederatedCredential')
  @DocsEditable()
  factory FederatedCredential(String id, String name, String avatarURL, String federation) {
    return FederatedCredential._create_1(id, name, avatarURL, federation);
  }
  static FederatedCredential _create_1(id, name, avatarURL, federation) => JS('FederatedCredential', 'new FederatedCredential(#,#,#,#)', id, name, avatarURL, federation);

  @DomName('FederatedCredential.federation')
  @DocsEditable()
  @Experimental() // untriaged
  final String federation;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

  @DomName('FetchEvent.isReload')
  @DocsEditable()
  @Experimental() // untriaged
  final bool isReload;

  @DomName('FetchEvent.request')
  @DocsEditable()
  @Experimental() // untriaged
  final _Request request;

  @DomName('FetchEvent.respondWith')
  @DocsEditable()
  @Experimental() // untriaged
  void respondWith(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('HTMLFieldSetElement')
@Unstable()
@Native("HTMLFieldSetElement")
class FieldSetElement extends HtmlElement {
  // 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')
@Native("File")
class File extends Blob {
  // 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()
@Native("FileEntry")
class FileEntry extends Entry {
  // 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()
@Native("FileError")
class FileError extends DomError {
  // 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')
@Native("FileList")
class FileList extends Interceptor with ListMixin<File>, ImmutableListMixin<File> implements JavaScriptIndexingBehavior, List<File> {
  // 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.index(index, this);
    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.


  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')
@Native("FileReader")
class FileReader extends EventTarget {

  @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
@Native("Stream")
class FileStream extends Interceptor {
  // 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/
@Native("DOMFileSystem")
class FileSystem extends Interceptor {
  // 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()
@Native("FileWriter")
class FileWriter extends EventTarget {
  // 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')
@Native("FocusEvent")
class FocusEvent extends UIEvent {
  // 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
@Native("FontFace")
class FontFace extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory FontFace._() { throw new UnsupportedError("Not supported"); }

  @DomName('FontFace.FontFace')
  @DocsEditable()
  factory FontFace(String family, source, [Map descriptors]) {
    if ((source is String || source == null) && (family is String || family == null) && descriptors == null) {
      return FontFace._create_1(family, source);
    }
    if ((descriptors is Map || descriptors == null) && (source is String || source == null) && (family is String || family == null)) {
      var descriptors_1 = convertDartToNative_Dictionary(descriptors);
      return FontFace._create_2(family, source, descriptors_1);
    }
    if ((source is TypedData || source == null) && (family is String || family == null) && descriptors == null) {
      return FontFace._create_3(family, source);
    }
    if ((descriptors is Map || descriptors == null) && (source is TypedData || source == null) && (family is String || family == null)) {
      var descriptors_1 = convertDartToNative_Dictionary(descriptors);
      return FontFace._create_4(family, source, descriptors_1);
    }
    if ((source is ByteBuffer || source == null) && (family is String || family == null) && descriptors == null) {
      return FontFace._create_5(family, source);
    }
    if ((descriptors is Map || descriptors == null) && (source is ByteBuffer || source == null) && (family is String || family == null)) {
      var descriptors_1 = convertDartToNative_Dictionary(descriptors);
      return FontFace._create_6(family, source, descriptors_1);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static FontFace _create_1(family, source) => JS('FontFace', 'new FontFace(#,#)', family, source);
  static FontFace _create_2(family, source, descriptors) => JS('FontFace', 'new FontFace(#,#,#)', family, source, descriptors);
  static FontFace _create_3(family, source) => JS('FontFace', 'new FontFace(#,#)', family, source);
  static FontFace _create_4(family, source, descriptors) => JS('FontFace', 'new FontFace(#,#,#)', family, source, descriptors);
  static FontFace _create_5(family, source) => JS('FontFace', 'new FontFace(#,#)', family, source);
  static FontFace _create_6(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.loaded')
  @DocsEditable()
  @Experimental() // untriaged
  final Future loaded;

  @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
  Future 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
@Native("FontFaceSet")
class FontFaceSet extends EventTarget {
  // 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('FontFaceSetLoadEvent')
@Experimental() // untriaged
@Native("FontFaceSetLoadEvent")
class FontFaceSetLoadEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory FontFaceSetLoadEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('FontFaceSetLoadEvent.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('FormData')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
@Native("FormData")
class FormData extends Interceptor {
  // 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')
@Native("HTMLFormElement")
class FormElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory FormElement._() { throw new UnsupportedError("Not supported"); }

  @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__(index_OR_name) 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(Map details) {
    var details_1 = convertDartToNative_Dictionary(details);
    _requestAutocomplete_1(details_1);
    return;
  }
  @JSName('requestAutocomplete')
  @DomName('HTMLFormElement.requestAutocomplete')
  @DocsEditable()
  // http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2012-October/037711.html
  @Experimental()
  void _requestAutocomplete_1(details) native;

  @DomName('HTMLFormElement.reset')
  @DocsEditable()
  void reset() native;

  @DomName('HTMLFormElement.submit')
  @DocsEditable()
  void submit() 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('Gamepad')
// https://dvcs.w3.org/hg/gamepad/raw-file/default/gamepad.html#gamepad-interface
@Experimental()
@Native("Gamepad")
class Gamepad extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Gamepad._() { throw new UnsupportedError("Not supported"); }

  @DomName('Gamepad.axes')
  @DocsEditable()
  final List<num> axes;

  @DomName('Gamepad.connected')
  @DocsEditable()
  @Experimental() // untriaged
  final bool connected;

  @DomName('Gamepad.id')
  @DocsEditable()
  final String id;

  @DomName('Gamepad.index')
  @DocsEditable()
  final int index;

  @DomName('Gamepad.mapping')
  @DocsEditable()
  @Experimental() // untriaged
  final String mapping;

  @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('GamepadButton')
@Experimental() // untriaged
@Native("GamepadButton")
class GamepadButton extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory GamepadButton._() { throw new UnsupportedError("Not supported"); }

  @DomName('GamepadButton.pressed')
  @DocsEditable()
  @Experimental() // untriaged
  final bool pressed;

  @DomName('GamepadButton.value')
  @DocsEditable()
  @Experimental() // untriaged
  final double 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('GamepadEvent')
@Experimental() // untriaged
@Native("GamepadEvent")
class GamepadEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory GamepadEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('GamepadEvent.gamepad')
  @DocsEditable()
  @Experimental() // untriaged
  final Gamepad gamepad;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

  @DomName('Geofencing.getRegisteredRegions')
  @DocsEditable()
  @Experimental() // untriaged
  Future getRegisteredRegions() native;

  @DomName('Geofencing.registerRegion')
  @DocsEditable()
  @Experimental() // untriaged
  Future registerRegion(GeofencingRegion region) native;

  @DomName('Geofencing.unregisterRegion')
  @DocsEditable()
  @Experimental() // untriaged
  Future unregisterRegion(String regionId) 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('GeofencingRegion')
@Experimental() // untriaged
@Native("GeofencingRegion")
class GeofencingRegion extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory GeofencingRegion._() { throw new UnsupportedError("Not supported"); }

  @DomName('GeofencingRegion.id')
  @DocsEditable()
  @Experimental() // untriaged
  final String id;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All 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()
@Native("Geolocation")
class Geolocation extends Interceptor {

  @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;

  @DomName('Geolocation.getCurrentPosition')
  @DocsEditable()
  void _getCurrentPosition(_PositionCallback successCallback, [_PositionErrorCallback errorCallback, Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      _getCurrentPosition_1(successCallback, errorCallback, options_1);
      return;
    }
    if (errorCallback != null) {
      _getCurrentPosition_2(successCallback, errorCallback);
      return;
    }
    _getCurrentPosition_3(successCallback);
    return;
  }
  @JSName('getCurrentPosition')
  @DomName('Geolocation.getCurrentPosition')
  @DocsEditable()
  void _getCurrentPosition_1(_PositionCallback successCallback, _PositionErrorCallback errorCallback, options) native;
  @JSName('getCurrentPosition')
  @DomName('Geolocation.getCurrentPosition')
  @DocsEditable()
  void _getCurrentPosition_2(_PositionCallback successCallback, _PositionErrorCallback errorCallback) native;
  @JSName('getCurrentPosition')
  @DomName('Geolocation.getCurrentPosition')
  @DocsEditable()
  void _getCurrentPosition_3(_PositionCallback successCallback) native;

  @DomName('Geolocation.watchPosition')
  @DocsEditable()
  int _watchPosition(_PositionCallback successCallback, [_PositionErrorCallback errorCallback, Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _watchPosition_1(successCallback, errorCallback, options_1);
    }
    if (errorCallback != null) {
      return _watchPosition_2(successCallback, errorCallback);
    }
    return _watchPosition_3(successCallback);
  }
  @JSName('watchPosition')
  @DomName('Geolocation.watchPosition')
  @DocsEditable()
  int _watchPosition_1(_PositionCallback successCallback, _PositionErrorCallback errorCallback, options) native;
  @JSName('watchPosition')
  @DomName('Geolocation.watchPosition')
  @DocsEditable()
  int _watchPosition_2(_PositionCallback successCallback, _PositionErrorCallback errorCallback) native;
  @JSName('watchPosition')
  @DomName('Geolocation.watchPosition')
  @DocsEditable()
  int _watchPosition_3(_PositionCallback successCallback) 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()
@Native("Geoposition")
class Geoposition extends Interceptor {
  // 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.canplayEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> canPlayEvent = const EventStreamProvider<Event>('canplay');

  @DomName('GlobalEventHandlers.canplaythroughEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> canPlayThroughEvent = const EventStreamProvider<Event>('canplaythrough');

  @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.durationchangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> durationChangeEvent = const EventStreamProvider<Event>('durationchange');

  @DomName('GlobalEventHandlers.emptiedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> emptiedEvent = const EventStreamProvider<Event>('emptied');

  @DomName('GlobalEventHandlers.endedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');

  @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.loadeddataEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadedDataEvent = const EventStreamProvider<Event>('loadeddata');

  @DomName('GlobalEventHandlers.loadedmetadataEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadedMetadataEvent = const EventStreamProvider<Event>('loadedmetadata');

  @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.pauseEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> pauseEvent = const EventStreamProvider<Event>('pause');

  @DomName('GlobalEventHandlers.playEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> playEvent = const EventStreamProvider<Event>('play');

  @DomName('GlobalEventHandlers.playingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> playingEvent = const EventStreamProvider<Event>('playing');

  @DomName('GlobalEventHandlers.ratechangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> rateChangeEvent = const EventStreamProvider<Event>('ratechange');

  @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.seekedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> seekedEvent = const EventStreamProvider<Event>('seeked');

  @DomName('GlobalEventHandlers.seekingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> seekingEvent = const EventStreamProvider<Event>('seeking');

  @DomName('GlobalEventHandlers.selectEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> selectEvent = const EventStreamProvider<Event>('select');

  @DomName('GlobalEventHandlers.stalledEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> stalledEvent = const EventStreamProvider<Event>('stalled');

  @DomName('GlobalEventHandlers.submitEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> submitEvent = const EventStreamProvider<Event>('submit');

  @DomName('GlobalEventHandlers.suspendEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> suspendEvent = const EventStreamProvider<Event>('suspend');

  @DomName('GlobalEventHandlers.timeupdateEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> timeUpdateEvent = const EventStreamProvider<Event>('timeupdate');

  @DomName('GlobalEventHandlers.volumechangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> volumeChangeEvent = const EventStreamProvider<Event>('volumechange');

  @DomName('GlobalEventHandlers.waitingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> waitingEvent = const EventStreamProvider<Event>('waiting');

  @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.oncanplay')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onCanPlay => canPlayEvent.forTarget(this);

  @DomName('GlobalEventHandlers.oncanplaythrough')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onCanPlayThrough => canPlayThroughEvent.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.ondurationchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onDurationChange => durationChangeEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onemptied')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onEmptied => emptiedEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onended')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onEnded => endedEvent.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.onloadeddata')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onLoadedData => loadedDataEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onloadedmetadata')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onLoadedMetadata => loadedMetadataEvent.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.onpause')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onPause => pauseEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onplay')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onPlay => playEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onplaying')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onPlaying => playingEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onratechange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onRateChange => rateChangeEvent.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.onseeked')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSeeked => seekedEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onseeking')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSeeking => seekingEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onselect')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSelect => selectEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onstalled')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onStalled => stalledEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onsubmit')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSubmit => submitEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onsuspend')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSuspend => suspendEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ontimeupdate')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onTimeUpdate => timeUpdateEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onvolumechange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onVolumeChange => volumeChangeEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onwaiting')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onWaiting => waitingEvent.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')
@Native("HTMLHRElement")
class HRElement extends HtmlElement {
  // 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()
@Native("HashChangeEvent")
class HashChangeEvent extends Event {
  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')
@Native("HTMLHeadElement")
class HeadElement extends HtmlElement {
  // 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('Headers')
@Experimental() // untriaged
@Native("Headers")
class Headers extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Headers._() { throw new UnsupportedError("Not supported"); }

  @DomName('Headers.Headers')
  @DocsEditable()
  factory Headers([input]) {
    if (input == null) {
      return Headers._create_1();
    }
    if ((input is Headers || input == null)) {
      return Headers._create_2(input);
    }
    if ((input is Map || input == null)) {
      var input_1 = convertDartToNative_Dictionary(input);
      return Headers._create_3(input_1);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static Headers _create_1() => JS('Headers', 'new Headers()');
  static Headers _create_2(input) => JS('Headers', 'new Headers(#)', input);
  static Headers _create_3(input) => JS('Headers', 'new Headers(#)', input);

  @DomName('Headers.size')
  @DocsEditable()
  @Experimental() // untriaged
  final int size;

  @DomName('Headers.forEach')
  @DocsEditable()
  @Experimental() // untriaged
  void forEach(HeadersForEachCallback callback, [Object thisArg]) 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('HeadersForEachCallback')
@Experimental() // untriaged
typedef void HeadersForEachCallback(String value, String key, Headers map);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All 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')
@Native("HTMLHeadingElement")
class HeadingElement extends HtmlElement {
  // 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')
@Native("History")
class History extends Interceptor implements HistoryBase {

  /**
   * 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')
@Native("HTMLCollection")
class HtmlCollection extends Interceptor with ListMixin<Node>, ImmutableListMixin<Node> implements JavaScriptIndexingBehavior, List<Node> {
  // 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.index(index, this);
    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.


  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')
@Native("HTMLDocument")
class HtmlDocument extends Document {
  // 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;
  set selectedStylesheetSet(String value) {
    _selectedStylesheetSet = value;
  }

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

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

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

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

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

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

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

  @DomName('Document.visibilityState')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @Experimental()
  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')
@Native("HTMLFormControlsCollection")
class HtmlFormControlsCollection extends HtmlCollection {
  // To suppress missing implicit constructor warnings.
  factory HtmlFormControlsCollection._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLFormControlsCollection.namedItem')
  @DocsEditable()
  Object 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('HTMLHtmlElement')
@Native("HTMLHtmlElement")
class HtmlHtmlElement extends HtmlElement {
  // 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')
@Native("HTMLOptionsCollection")
class HtmlOptionsCollection extends HtmlCollection {
  // 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')
@Native("XMLHttpRequest")
class HttpRequest extends HttpRequestEventTarget {

  /**
   * 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((HttpRequest 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. (See also [HttpRequest.postFormData] for `POST` 
   * requests only.
   *
   * 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.
   *
   * If specified, [responseType] sets the desired response format for the
   * request. By default it is [String], but can also be 'arraybuffer', 'blob', 
   * 'document', 'json', or 'text'. See also [HttpRequest.responseType] 
   * for more information.
   *
   * 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) {
      var accepted = xhr.status >= 200 && xhr.status < 300;
      var fileUri = xhr.status == 0; // file:// URIs have status of 0.
      var notModified = xhr.status == 304;
      // Redirect status is specified up to 307, but others have been used in
      // practice. Notably Google Drive uses 308 Resume Incomplete for
      // resumable uploads, and it's also been used as a redirect. The
      // redirect case will be handled by the browser before it gets to us,
      // so if we see it we should pass it through to the user.
      var unknownRedirect = xhr.status > 307 && xhr.status < 400;
      
      if (accepted || fileUri || notModified || unknownRedirect) {
        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;
  }

  /**
   * 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;

  // 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('responseURL')
  @DomName('XMLHttpRequest.responseURL')
  @DocsEditable()
  @Experimental() // untriaged
  final String responseUrl;

  @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 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
@Native("XMLHttpRequestEventTarget")
class HttpRequestEventTarget extends EventTarget {
  // 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()
@Native("XMLHttpRequestUpload")
class HttpRequestUpload extends HttpRequestEventTarget {
  // 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')
@Native("HTMLIFrameElement")
class IFrameElement extends HtmlElement {
  // 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.allowFullscreen')
  @DocsEditable()
  @Experimental() // untriaged
  bool allowFullscreen;

  @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.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String integrity;

  @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
@Native("ImageBitmap")
class ImageBitmap extends Interceptor {
  // 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')
@Native("ImageData")
class ImageData extends Interceptor {

  // To suppress missing implicit constructor warnings.
  factory ImageData._() { throw new UnsupportedError("Not supported"); }

  @DomName('ImageData.ImageData')
  @DocsEditable()
  factory ImageData(data_OR_width, int height_OR_width, [int height]) {
    if ((height_OR_width is int || height_OR_width == null) && (data_OR_width is int || data_OR_width == null) && height == null) {
      return ImageData._create_1(data_OR_width, height_OR_width);
    }
    if ((height_OR_width is int || height_OR_width == null) && (data_OR_width is Uint8ClampedList || data_OR_width == null) && height == null) {
      return ImageData._create_2(data_OR_width, height_OR_width);
    }
    if ((height is int || height == null) && (height_OR_width is int || height_OR_width == null) && (data_OR_width is Uint8ClampedList || data_OR_width == null)) {
      return ImageData._create_3(data_OR_width, height_OR_width, height);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static ImageData _create_1(data_OR_width, height_OR_width) => JS('ImageData', 'new ImageData(#,#)', data_OR_width, height_OR_width);
  static ImageData _create_2(data_OR_width, height_OR_width) => JS('ImageData', 'new ImageData(#,#)', data_OR_width, height_OR_width);
  static ImageData _create_3(data_OR_width, height_OR_width, height) => JS('ImageData', 'new ImageData(#,#,#)', data_OR_width, height_OR_width, height);

  @DomName('ImageData.data')
  @DocsEditable()
  @Creates('NativeUint8ClampedList')
  @Returns('NativeUint8ClampedList')
  final Uint8ClampedList 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')
@Native("HTMLImageElement")
class ImageElement extends HtmlElement implements CanvasImageSource {
  // 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.currentSrc')
  @DocsEditable()
  @Experimental() // untriaged
  final String currentSrc;

  @DomName('HTMLImageElement.height')
  @DocsEditable()
  int height;

  @DomName('HTMLImageElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String integrity;

  @DomName('HTMLImageElement.isMap')
  @DocsEditable()
  bool isMap;

  @DomName('HTMLImageElement.naturalHeight')
  @DocsEditable()
  final int naturalHeight;

  @DomName('HTMLImageElement.naturalWidth')
  @DocsEditable()
  final int naturalWidth;

  @DomName('HTMLImageElement.sizes')
  @DocsEditable()
  @Experimental() // untriaged
  String sizes;

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


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

  @DomName('InjectedScriptHost.inspect')
  @DocsEditable()
  @Experimental() // untriaged
  void inspect(Object objectId, Object hints) 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('HTMLInputElement')
@Native("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 {

  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"); }
  /**
   * 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.capture')
  @DocsEditable()
  @Experimental() // untriaged
  bool capture;

  @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;

  set valueAsDate(DateTime value) {
    this._set_valueAsDate = convertDartToNative_DateTime(value);
  }
  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('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;

}


// 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()
@Native("InputMethodContext")
class InputMethodContext extends EventTarget {
  // 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
@Native("InstallEvent")
class InstallEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory InstallEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('InstallEvent.reloadAll')
  @DocsEditable()
  @Experimental() // untriaged
  Future reloadAll() native;

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


/**
 * 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')
@Native("KeyboardEvent")
class KeyboardEvent extends UIEvent {

  /** 
   * 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}) {
    if (view == null) {
      view = window;
    }
    final e = document._createEvent("KeyboardEvent");
    e._initKeyboardEvent(type, canBubble, cancelable, view, "",
        keyLocation, ctrlKey, altKey, shiftKey, metaKey);
    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) {
    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);
    }
  }

  @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.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
@Native("HTMLKeygenElement")
class KeygenElement extends HtmlElement {
  // 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')
@Native("HTMLLIElement")
class LIElement extends HtmlElement {
  // 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')
@Native("HTMLLabelElement")
class LabelElement extends HtmlElement {
  // 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')
@Native("HTMLLegendElement")
class LegendElement extends HtmlElement {
  // 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')
@Native("HTMLLinkElement")
class LinkElement extends HtmlElement {
  // 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.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String integrity;

  @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) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

  @DomName('LocalCredential.LocalCredential')
  @DocsEditable()
  factory LocalCredential(String id, String name, String avatarURL, String password) {
    return LocalCredential._create_1(id, name, avatarURL, password);
  }
  static LocalCredential _create_1(id, name, avatarURL, password) => JS('LocalCredential', 'new LocalCredential(#,#,#,#)', id, name, avatarURL, password);

  @DomName('LocalCredential.password')
  @DocsEditable()
  @Experimental() // untriaged
  final String password;
}
// 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')
@Native("Location")
class Location extends Interceptor implements LocationBase {
  // 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.origin')
  String get origin {
    if (JS('bool', '("origin" in #)', this)) {
      return JS('String', '#.origin', this);
    }
    return '${this.protocol}//${this.host}';
  }

  @DomName('Location.toString')
  @DocsEditable()
  String toString() => JS('String', 'String(#)', 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('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')
@Native("HTMLMapElement")
class MapElement extends HtmlElement {
  // 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()
@Native("MediaController")
class MediaController extends EventTarget {
  // 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('MediaDeviceInfo')
@Experimental() // untriaged
@Native("MediaDeviceInfo")
class MediaDeviceInfo extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaDeviceInfo._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaDeviceInfo.deviceId')
  @DocsEditable()
  @Experimental() // untriaged
  final String deviceId;

  @DomName('MediaDeviceInfo.groupId')
  @DocsEditable()
  @Experimental() // untriaged
  final String groupId;

  @DomName('MediaDeviceInfo.kind')
  @DocsEditable()
  @Experimental() // untriaged
  final String kind;

  @DomName('MediaDeviceInfo.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.

// WARNING: Do not edit - generated code.


@DomName('MediaDeviceInfoCallback')
@Experimental() // untriaged
typedef void MediaDeviceInfoCallback(List<MediaDeviceInfo> devices);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All 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()
@Native("HTMLMediaElement")
class MediaElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory MediaElement._() { throw new UnsupportedError("Not supported"); }

  /**
   * 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.audioTracks')
  @DocsEditable()
  @Experimental() // untriaged
  final AudioTrackList audioTracks;

  @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.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String integrity;

  @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.videoTracks')
  @DocsEditable()
  @Experimental() // untriaged
  final VideoTrackList videoTracks;

  @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
  Future 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 `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()
@Native("MediaError")
class MediaError extends Interceptor {
  // 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()
@Native("MediaKeyError")
class MediaKeyError extends Interceptor {
  // 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()
@Native("MediaKeyEvent")
class MediaKeyEvent extends Event {
  // 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()
@Native("MediaKeyMessageEvent")
class MediaKeyMessageEvent extends Event {
  // 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 ByteBuffer 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()
@Native("MediaKeyNeededEvent")
class MediaKeyNeededEvent extends Event {
  // 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()
@Native("MediaKeySession")
class MediaKeySession extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaKeySession._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaKeySession.closed')
  @DocsEditable()
  @Experimental() // untriaged
  final Future closed;

  @DomName('MediaKeySession.error')
  @DocsEditable()
  final MediaKeyError error;

  @DomName('MediaKeySession.keySystem')
  @DocsEditable()
  final String keySystem;

  @DomName('MediaKeySession.sessionId')
  @DocsEditable()
  final String sessionId;

  @DomName('MediaKeySession.generateRequest')
  @DocsEditable()
  @Experimental() // untriaged
  Future generateRequest(String initDataType, initData) native;

  @DomName('MediaKeySession.release')
  @DocsEditable()
  @Experimental() // untriaged
  Future release() native;

  @JSName('update')
  @DomName('MediaKeySession.update')
  @DocsEditable()
  Future _update(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()
@Native("MediaKeys")
class MediaKeys extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaKeys._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaKeys.keySystem')
  @DocsEditable()
  final String keySystem;

  @DomName('MediaKeys.create')
  @DocsEditable()
  @Experimental() // untriaged
  static Future create(String keySystem) native;

  @JSName('createSession')
  @DomName('MediaKeys.createSession')
  @DocsEditable()
  MediaKeySession _createSession([String sessionType]) native;

  @DomName('MediaKeys.isTypeSupported')
  @DocsEditable()
  @Experimental() // untriaged
  static bool isTypeSupported(String keySystem, 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('MediaList')
@Unstable()
@Native("MediaList")
class MediaList extends Interceptor {
  // 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()
@Native("MediaQueryList")
class MediaQueryList extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaQueryList._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaQueryList.changeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> changeEvent = const EventStreamProvider<Event>('change');

  @DomName('MediaQueryList.matches')
  @DocsEditable()
  final bool matches;

  @DomName('MediaQueryList.media')
  @DocsEditable()
  final String media;

  @DomName('MediaQueryList.addListener')
  @DocsEditable()
  void addListener(EventListener listener) native;

  @DomName('MediaQueryList.removeListener')
  @DocsEditable()
  void removeListener(EventListener listener) native;

  @DomName('MediaQueryList.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('MediaQueryListEvent')
@Experimental() // untriaged
@Native("MediaQueryListEvent")
class MediaQueryListEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MediaQueryListEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaQueryListEvent.matches')
  @DocsEditable()
  @Experimental() // untriaged
  final bool matches;

  @DomName('MediaQueryListEvent.media')
  @DocsEditable()
  @Experimental() // untriaged
  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')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE, '11')
// https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#mediasource
@Experimental()
@Native("MediaSource")
class MediaSource extends EventTarget {
  // 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()');

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.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
@Native("MediaStream")
class MediaStream extends EventTarget {
  // 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.clone')
  @DocsEditable()
  @Experimental() // untriaged
  MediaStream clone() native;

  @DomName('MediaStream.getAudioTracks')
  @DocsEditable()
  @Creates('JSExtendableArray')
  @Returns('JSExtendableArray')
  List<MediaStreamTrack> getAudioTracks() native;

  @DomName('MediaStream.getTrackById')
  @DocsEditable()
  MediaStreamTrack getTrackById(String trackId) native;

  @DomName('MediaStream.getTracks')
  @DocsEditable()
  @Experimental() // untriaged
  List<MediaStreamTrack> getTracks() 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
@Native("MediaStreamEvent")
class MediaStreamEvent extends Event {
  // 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
@Native("MediaStreamTrack")
class MediaStreamTrack extends EventTarget {
  // 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.muted')
  @DocsEditable()
  @Experimental() // untriaged
  final bool muted;

  @DomName('MediaStreamTrack.readyState')
  @DocsEditable()
  final String readyState;

  @DomName('MediaStreamTrack.clone')
  @DocsEditable()
  @Experimental() // untriaged
  MediaStreamTrack clone() native;

  @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
@Native("MediaStreamTrackEvent")
class MediaStreamTrackEvent extends Event {
  // 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
@Native("MemoryInfo")
class MemoryInfo extends Interceptor {
  // 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')
@Native("HTMLMenuElement")
class MenuElement extends HtmlElement {
  // 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();

  @DomName('HTMLMenuElement.label')
  @DocsEditable()
  @Experimental() // untriaged
  String label;

  @DomName('HTMLMenuElement.type')
  @DocsEditable()
  @Experimental() // untriaged
  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('HTMLMenuItemElement')
@Experimental() // untriaged
@Native("HTMLMenuItemElement")
class MenuItemElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory MenuItemElement._() { 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.
   */
  MenuItemElement.created() : super.created();

  @DomName('HTMLMenuItemElement.checked')
  @DocsEditable()
  @Experimental() // untriaged
  bool checked;

  @JSName('default')
  @DomName('HTMLMenuItemElement.default')
  @DocsEditable()
  @Experimental() // untriaged
  bool defaultValue;

  @DomName('HTMLMenuItemElement.disabled')
  @DocsEditable()
  @Experimental() // untriaged
  bool disabled;

  @DomName('HTMLMenuItemElement.label')
  @DocsEditable()
  @Experimental() // untriaged
  String label;

  @DomName('HTMLMenuItemElement.type')
  @DocsEditable()
  @Experimental() // untriaged
  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('MessageChannel')
@Unstable()
@Native("MessageChannel")
class MessageChannel extends Interceptor {
  // 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')
@Native("MessageEvent")
class MessageEvent extends Event {
  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;
    }
    if (!Device.isIE) { // TODO: This if check should be removed once IE
      // implements the constructor.
      return JS('MessageEvent', 'new MessageEvent(#, {bubbles: #, cancelable: #, data: #, origin: #, lastEventId: #, source: #, ports: #})',
          type, canBubble, cancelable, data, origin, lastEventId, source,
          messagePorts);
    }
    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()
@Native("MessagePort")
class MessagePort extends EventTarget {
  // 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> transfer]) {
    if (transfer != null) {
      var message_1 = convertDartToNative_SerializedScriptValue(message);
      _postMessage_1(message_1, transfer);
      return;
    }
    var message_1 = convertDartToNative_SerializedScriptValue(message);
    _postMessage_2(message_1);
    return;
  }
  @JSName('postMessage')
  @DomName('MessagePort.postMessage')
  @DocsEditable()
  void _postMessage_1(message, List<MessagePort> transfer) 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')
@Native("HTMLMetaElement")
class MetaElement extends HtmlElement {
  // 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()
@Native("Metadata")
class Metadata extends Interceptor {
  // 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()
@Native("HTMLMeterElement")
class MeterElement extends HtmlElement {
  // 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()
@Native("MIDIAccess")
class MidiAccess extends EventTarget {
  // 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()
  final MidiInputMap inputs;

  @DomName('MIDIAccess.outputs')
  @DocsEditable()
  final MidiOutputMap outputs;

  @DomName('MIDIAccess.sysexEnabled')
  @DocsEditable()
  @Experimental() // untriaged
  final bool sysexEnabled;

  /// 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('MIDIConnectionEvent')
// http://webaudio.github.io/web-midi-api/#midiconnectionevent-interface
@Experimental()
@Native("MIDIConnectionEvent")
class MidiConnectionEvent extends Event {
  // 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()
@Native("MIDIInput")
class MidiInput extends MidiPort {
  // 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('MIDIInputMap')
@Experimental() // untriaged
@Native("MIDIInputMap")
class MidiInputMap extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MidiInputMap._() { throw new UnsupportedError("Not supported"); }

  @DomName('MIDIInputMap.size')
  @DocsEditable()
  @Experimental() // untriaged
  final int size;

  @DomName('MIDIInputMap.entries')
  @DocsEditable()
  @Experimental() // untriaged
  DomIterator entries() native;

  @DomName('MIDIInputMap.get')
  @DocsEditable()
  @Experimental() // untriaged
  Object get(String id) native;

  @DomName('MIDIInputMap.has')
  @DocsEditable()
  @Experimental() // untriaged
  bool has(String key) native;

  @DomName('MIDIInputMap.keys')
  @DocsEditable()
  @Experimental() // untriaged
  DomIterator keys() native;

  @DomName('MIDIInputMap.values')
  @DocsEditable()
  @Experimental() // untriaged
  DomIterator values() 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('MIDIMessageEvent')
// http://webaudio.github.io/web-midi-api/#midimessageevent-interface
@Experimental()
@Native("MIDIMessageEvent")
class MidiMessageEvent extends Event {
  // 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()
@Native("MIDIOutput")
class MidiOutput extends MidiPort {
  // 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('MIDIOutputMap')
@Experimental() // untriaged
@Native("MIDIOutputMap")
class MidiOutputMap extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MidiOutputMap._() { throw new UnsupportedError("Not supported"); }

  @DomName('MIDIOutputMap.size')
  @DocsEditable()
  @Experimental() // untriaged
  final int size;

  @DomName('MIDIOutputMap.entries')
  @DocsEditable()
  @Experimental() // untriaged
  DomIterator entries() native;

  @DomName('MIDIOutputMap.get')
  @DocsEditable()
  @Experimental() // untriaged
  Object get(String id) native;

  @DomName('MIDIOutputMap.has')
  @DocsEditable()
  @Experimental() // untriaged
  bool has(String key) native;

  @DomName('MIDIOutputMap.keys')
  @DocsEditable()
  @Experimental() // untriaged
  DomIterator keys() native;

  @DomName('MIDIOutputMap.values')
  @DocsEditable()
  @Experimental() // untriaged
  DomIterator values() 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()
@Native("MIDIPort")
class MidiPort extends EventTarget {
  // 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
@Native("MimeType")
class MimeType extends Interceptor {
  // 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
@Native("MimeTypeArray")
class MimeTypeArray extends Interceptor with ListMixin<MimeType>, ImmutableListMixin<MimeType> implements JavaScriptIndexingBehavior, List<MimeType> {
  // 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.index(index, this);
    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.


  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()
@Native("HTMLModElement")
class ModElement extends HtmlElement {
  // 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')
@Native("MouseEvent,DragEvent,PointerEvent,MSPointerEvent")
class MouseEvent extends UIEvent {
  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;

  /**
   * The nonstandard way to access the element that the mouse comes
   * from in the case of a `mouseover` event.
   *
   * This member is deprecated and not cross-browser compatible; use
   * relatedTarget to get the same information in the standard way.
   */
  @DomName('MouseEvent.fromElement')
  @DocsEditable()
  @deprecated
  final Node fromElement;

  @DomName('MouseEvent.metaKey')
  @DocsEditable()
  final bool metaKey;

  @JSName('movementX')
  @DomName('MouseEvent.movementX')
  @DocsEditable()
  @Experimental() // untriaged
  final int _movementX;

  @JSName('movementY')
  @DomName('MouseEvent.movementY')
  @DocsEditable()
  @Experimental() // untriaged
  final int _movementY;

  @DomName('MouseEvent.region')
  @DocsEditable()
  @Experimental() // untriaged
  final String region;

  @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;

  /**
   * The nonstandard way to access the element that the mouse goes
   * to in the case of a `mouseout` event.
   *
   * This member is deprecated and not cross-browser compatible; use
   * relatedTarget to get the same information in the standard way.
   */
  @DomName('MouseEvent.toElement')
  @DocsEditable()
  @deprecated
  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()
@Native("MutationObserver,WebKitMutationObserver")
class MutationObserver extends Interceptor {

  @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')
@Native("MutationRecord")
class MutationRecord extends Interceptor {
  // 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')
@Native("Navigator")
class Navigator extends Interceptor implements NavigatorCpu, NavigatorLanguage, NavigatorOnLine, NavigatorID {

  @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.connection')
  @DocsEditable()
  @Experimental() // untriaged
  final NetworkInformation connection;

  @DomName('Navigator.cookieEnabled')
  @DocsEditable()
  @Unstable()
  final bool cookieEnabled;

  @DomName('Navigator.credentials')
  @DocsEditable()
  @Experimental() // untriaged
  final CredentialsContainer credentials;

  @DomName('Navigator.doNotTrack')
  @DocsEditable()
  // http://www.w3.org/2011/tracking-protection/drafts/tracking-dnt.html#js-dom
  @Experimental() // experimental
  final String doNotTrack;

  @DomName('Navigator.geofencing')
  @DocsEditable()
  @Experimental() // untriaged
  final Geofencing geofencing;

  @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.presentation')
  @DocsEditable()
  @Experimental() // untriaged
  final Presentation presentation;

  @DomName('Navigator.productSub')
  @DocsEditable()
  @Unstable()
  final String productSub;

  @DomName('Navigator.push')
  @DocsEditable()
  @Experimental() // untriaged
  final PushManager push;

  @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.getBattery')
  @DocsEditable()
  @Experimental() // untriaged
  Future getBattery() native;

  @DomName('Navigator.getGamepads')
  @DocsEditable()
  @Experimental() // untriaged
  @Returns('_GamepadList')
  @Creates('_GamepadList')
  List<Gamepad> getGamepads() native;

  @DomName('Navigator.getStorageUpdates')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#navigatorstorageutils
  @Experimental()
  void getStorageUpdates() native;

  @DomName('Navigator.registerProtocolHandler')
  @DocsEditable()
  @Unstable()
  void registerProtocolHandler(String scheme, String url, String title) native;

  @DomName('Navigator.sendBeacon')
  @DocsEditable()
  @Experimental() // untriaged
  bool sendBeacon(String url, data) native;

  // From NavigatorCPU

  @DomName('Navigator.hardwareConcurrency')
  @DocsEditable()
  @Experimental() // untriaged
  final int hardwareConcurrency;

  // 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.dartEnabled')
  @DocsEditable()
  @Experimental() // untriaged
  final bool dartEnabled;

  @DomName('Navigator.platform')
  @DocsEditable()
  final String platform;

  @DomName('Navigator.product')
  @DocsEditable()
  @Unstable()
  final String product;

  @DomName('Navigator.userAgent')
  @DocsEditable()
  final String userAgent;

  // From NavigatorLanguage

  @DomName('Navigator.languages')
  @DocsEditable()
  @Experimental() // untriaged
  final List<String> languages;

  // 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('NavigatorCPU')
@Experimental() // untriaged
abstract class NavigatorCpu extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigatorCpu._() { throw new UnsupportedError("Not supported"); }

  final int hardwareConcurrency;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All 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 bool dartEnabled;

  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('NavigatorLanguage')
@Experimental() // untriaged
abstract class NavigatorLanguage extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigatorLanguage._() { throw new UnsupportedError("Not supported"); }

  final String language;

  final List<String> languages;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All 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()
@Native("NavigatorUserMediaError")
class NavigatorUserMediaError extends Interceptor {
  // 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.


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

  @DomName('NetworkInformation.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.


/**
 * 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) {
    if (index == length) {
      addAll(iterable);
    } else {
      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;

  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')
@Native("Node")
class Node extends EventTarget {

  // Custom element created callback.
  Node._created() : super._created();

  /**
   * A modifiable list of this node's children.
   */
  List<Node> get nodes {
    return new _ChildNodeListLazy(this);
  }

  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() {
    String value = nodeValue;  // Fetch DOM Node property once.
    return value == null ? super.toString() : value;
  }

  /**
   * 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;

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

  /**
   * 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()
@Native("NodeFilter")
class NodeFilter extends Interceptor {
  // 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()
@Native("NodeIterator")
class NodeIterator extends Interceptor {
  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')
@Native("NodeList,RadioNodeList")
class NodeList extends Interceptor with ListMixin<Node>, ImmutableListMixin<Node> implements JavaScriptIndexingBehavior, List<Node> {
  // 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.index(index, this);
    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.


  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
@Native("Notification")
class Notification extends EventTarget {

  factory Notification(String title, {String dir: null, String body: null,
      String lang: null, String tag: null, String icon: null}) {

    var parsedOptions = {};
    if (dir != null) parsedOptions['dir'] = dir;
    if (body != null) parsedOptions['body'] = body;
    if (lang != null) parsedOptions['lang'] = lang;
    if (tag != null) parsedOptions['tag'] = tag;
    if (icon != null) parsedOptions['icon'] = icon;
    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) {
      var options_1 = convertDartToNative_Dictionary(options);
      return Notification._create_1(title, options_1);
    }
    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);

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

  @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')
@Native("HTMLOListElement")
class OListElement extends HtmlElement {
  // 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()
@Native("HTMLObjectElement")
class ObjectElement extends HtmlElement {
  // 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.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String integrity;

  @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')
@Native("HTMLOptGroupElement")
class OptGroupElement extends HtmlElement {
  // 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')
@Native("HTMLOptionElement")
class OptionElement extends HtmlElement {
  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)
@Native("HTMLOutputElement")
class OutputElement extends HtmlElement {
  // 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
@Native("OverflowEvent")
class OverflowEvent extends Event {
  // 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()
@Native("PageTransitionEvent")
class PageTransitionEvent extends Event {
  // 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')
@Native("HTMLParagraphElement")
class ParagraphElement extends HtmlElement {
  // 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()
@Native("HTMLParamElement")
class ParamElement extends HtmlElement {
  // 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;

  Element querySelector(String selectors);

  List<Node> _querySelectorAll(String selectors);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

  @DomName('Path2D.Path2D')
  @DocsEditable()
  factory Path2D([path_OR_text]) {
    if (path_OR_text == null) {
      return Path2D._create_1();
    }
    if ((path_OR_text is Path2D || path_OR_text == null)) {
      return Path2D._create_2(path_OR_text);
    }
    if ((path_OR_text is String || path_OR_text == null)) {
      return Path2D._create_3(path_OR_text);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static Path2D _create_1() => JS('Path2D', 'new Path2D()');
  static Path2D _create_2(path_OR_text) => JS('Path2D', 'new Path2D(#)', path_OR_text);
  static Path2D _create_3(path_OR_text) => JS('Path2D', 'new Path2D(#)', path_OR_text);

  @DomName('Path2D.addPath')
  @DocsEditable()
  @Experimental() // untriaged
  void addPath(Path2D path, [Matrix transform]) native;

  // From CanvasPathMethods

  @DomName('Path2D.arc')
  @DocsEditable()
  @Experimental() // untriaged
  void arc(num x, num y, num radius, num startAngle, num endAngle, bool anticlockwise) native;

  @DomName('Path2D.arcTo')
  @DocsEditable()
  @Experimental() // untriaged
  void arcTo(num x1, num y1, num x2, num y2, num radius) native;

  @DomName('Path2D.bezierCurveTo')
  @DocsEditable()
  @Experimental() // untriaged
  void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y, num x, num y) native;

  @DomName('Path2D.closePath')
  @DocsEditable()
  @Experimental() // untriaged
  void closePath() native;

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

  @DomName('Path2D.lineTo')
  @DocsEditable()
  @Experimental() // untriaged
  void lineTo(num x, num y) native;

  @DomName('Path2D.moveTo')
  @DocsEditable()
  @Experimental() // untriaged
  void moveTo(num x, num y) native;

  @DomName('Path2D.quadraticCurveTo')
  @DocsEditable()
  @Experimental() // untriaged
  void quadraticCurveTo(num cpx, num cpy, num x, num y) native;

  @DomName('Path2D.rect')
  @DocsEditable()
  @Experimental() // untriaged
  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)
@Native("Performance")
class Performance extends EventTarget {
  // 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()
@Native("PerformanceEntry")
class PerformanceEntry extends Interceptor {
  // 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()
@Native("PerformanceMark")
class PerformanceMark extends PerformanceEntry {
  // 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()
@Native("PerformanceMeasure")
class PerformanceMeasure extends PerformanceEntry {
  // 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()
@Native("PerformanceNavigation")
class PerformanceNavigation extends Interceptor {
  // 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()
@Native("PerformanceResourceTiming")
class PerformanceResourceTiming extends PerformanceEntry {
  // 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()
@Native("PerformanceTiming")
class PerformanceTiming extends Interceptor {
  // 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('HTMLPictureElement')
@Experimental() // untriaged
@Native("HTMLPictureElement")
class PictureElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory PictureElement._() { 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.
   */
  PictureElement.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('Plugin')
@Experimental() // non-standard
@Native("Plugin")
class Plugin extends Interceptor {
  // 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
@Native("PluginArray")
class PluginArray extends Interceptor with ListMixin<Plugin>, ImmutableListMixin<Plugin> implements JavaScriptIndexingBehavior, List<Plugin> {
  // 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.index(index, this);
    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.


  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('PluginPlaceholderElement')
@Experimental() // untriaged
@Native("PluginPlaceholderElement")
class PluginPlaceholderElement extends DivElement {
  // To suppress missing implicit constructor warnings.
  factory PluginPlaceholderElement._() { 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.
   */
  PluginPlaceholderElement.created() : super.created();

  @DomName('PluginPlaceholderElement.message')
  @DocsEditable()
  @Experimental() // untriaged
  String message;

  @DomName('PluginPlaceholderElement.createdCallback')
  @DocsEditable()
  @Experimental() // untriaged
  void createdCallback() 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)
@Native("PopStateEvent")
class PopStateEvent extends Event {
  // 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()
@Native("PositionError")
class PositionError extends Interceptor {
  // 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')
@Native("HTMLPreElement")
class PreElement extends HtmlElement {
  // 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('Presentation')
@Experimental() // untriaged
@Native("Presentation")
class Presentation extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory Presentation._() { 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('ProcessingInstruction')
@Unstable()
@Native("ProcessingInstruction")
class ProcessingInstruction extends CharacterData {
  // 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)
@Native("HTMLProgressElement")
class ProgressElement extends HtmlElement {
  // 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')
@Native("ProgressEvent")
class ProgressEvent extends Event {
  // 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('PushEvent')
@Experimental() // untriaged
@Native("PushEvent")
class PushEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory PushEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('PushEvent.data')
  @DocsEditable()
  @Experimental() // untriaged
  final 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('PushManager')
@Experimental() // untriaged
@Native("PushManager")
class PushManager extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PushManager._() { throw new UnsupportedError("Not supported"); }

  @DomName('PushManager.register')
  @DocsEditable()
  @Experimental() // untriaged
  Future register(String senderId) 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('PushRegistration')
@Experimental() // untriaged
@Native("PushRegistration")
class PushRegistration extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PushRegistration._() { throw new UnsupportedError("Not supported"); }

  @DomName('PushRegistration.pushEndpoint')
  @DocsEditable()
  @Experimental() // untriaged
  final String pushEndpoint;

  @DomName('PushRegistration.pushRegistrationId')
  @DocsEditable()
  @Experimental() // untriaged
  final String pushRegistrationId;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All 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')
@Native("HTMLQuoteElement")
class QuoteElement extends HtmlElement {
  // 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()
@Native("Range")
class Range extends Interceptor {
  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.compareBoundaryPoints')
  @DocsEditable()
  @Experimental() // untriaged
  int compareBoundaryPoints(int how, Range sourceRange) 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;


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


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

  @DomName('ReadableStream.closed')
  @DocsEditable()
  @Experimental() // untriaged
  final Future closed;

  @DomName('ReadableStream.state')
  @DocsEditable()
  @Experimental() // untriaged
  final String state;

  @DomName('ReadableStream.cancel')
  @DocsEditable()
  @Experimental() // untriaged
  Future cancel(Object reason) native;

  @DomName('ReadableStream.read')
  @DocsEditable()
  @Experimental() // untriaged
  Object read() native;

  @DomName('ReadableStream.wait')
  @DocsEditable()
  @Experimental() // untriaged
  Future wait() 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('RelatedEvent')
@Experimental() // untriaged
@Native("RelatedEvent")
class RelatedEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory RelatedEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('RelatedEvent.relatedTarget')
  @DocsEditable()
  @Experimental() // untriaged
  EventTarget get relatedTarget => _convertNativeToDart_EventTarget(this._get_relatedTarget);
  @JSName('relatedTarget')
  @DomName('RelatedEvent.relatedTarget')
  @DocsEditable()
  @Experimental() // untriaged
  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.

// 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
@Native("ResourceProgressEvent")
class ResourceProgressEvent extends ProgressEvent {
  // 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()
@Native("RTCDataChannel,DataChannel")
class RtcDataChannel extends EventTarget {
  // 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()
@Native("RTCDataChannelEvent")
class RtcDataChannelEvent extends Event {
  // 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()
@Native("RTCDTMFSender")
class RtcDtmfSender extends EventTarget {
  // 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()
@Native("RTCDTMFToneChangeEvent")
class RtcDtmfToneChangeEvent extends Event {
  // 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
@Native("RTCIceCandidate,mozRTCIceCandidate")
class RtcIceCandidate extends Interceptor {
  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()
  String candidate;

  @DomName('RTCIceCandidate.sdpMLineIndex')
  @DocsEditable()
  int sdpMLineIndex;

  @DomName('RTCIceCandidate.sdpMid')
  @DocsEditable()
  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()
@Native("RTCIceCandidateEvent,RTCPeerConnectionIceEvent")
class RtcIceCandidateEvent extends Event {
  // 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
@Native("RTCPeerConnection,mozRTCPeerConnection")
class RtcPeerConnection extends EventTarget {
  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 rtcOfferOptions]) {
    if (rtcOfferOptions != null) {
      var rtcOfferOptions_1 = convertDartToNative_Dictionary(rtcOfferOptions);
      _createOffer_1(successCallback, failureCallback, rtcOfferOptions_1);
      return;
    }
    _createOffer_2(successCallback, failureCallback);
    return;
  }
  @JSName('createOffer')
  @DomName('RTCPeerConnection.createOffer')
  @DocsEditable()
  void _createOffer_1(_RtcSessionDescriptionCallback successCallback, _RtcErrorCallback failureCallback, rtcOfferOptions) 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_1 = convertDartToNative_Dictionary(configuration);
      _updateIce_2(configuration_1);
      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
@Native("RTCSessionDescription,mozRTCSessionDescription")
class RtcSessionDescription extends Interceptor {
  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()
@Native("RTCStatsReport")
class RtcStatsReport extends Interceptor {
  // 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()
@Native("RTCStatsResponse")
class RtcStatsResponse extends Interceptor {
  // 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')
@Native("Screen")
class Screen extends Interceptor {

  @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 ScreenOrientation orientation;

  @DomName('Screen.pixelDepth')
  @DocsEditable()
  final int pixelDepth;

  @DomName('Screen.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.


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

  @DomName('ScreenOrientation.changeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> changeEvent = const EventStreamProvider<Event>('change');

  @DomName('ScreenOrientation.angle')
  @DocsEditable()
  @Experimental() // untriaged
  final int angle;

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

  @DomName('ScreenOrientation.lock')
  @DocsEditable()
  @Experimental() // untriaged
  Future lock(String orientation) native;

  @DomName('ScreenOrientation.unlock')
  @DocsEditable()
  @Experimental() // untriaged
  void unlock() native;

  @DomName('ScreenOrientation.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('HTMLScriptElement')
@Native("HTMLScriptElement")
class ScriptElement extends HtmlElement {
  // 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.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String integrity;

  @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()
@Native("SecurityPolicyViolationEvent")
class SecurityPolicyViolationEvent extends Event {
  // 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')
@Native("HTMLSelectElement")
class SelectElement extends HtmlElement {
  // 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.add')
  @DocsEditable()
  @Experimental() // untriaged
  void add(HtmlElement element, int before) 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')
@Native("Selection")
class Selection extends Interceptor {
  // 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 offset]) 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;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

  @DomName('ServiceWorkerClient.id')
  @DocsEditable()
  @Experimental() // untriaged
  final int id;

  @DomName('ServiceWorkerClient.postMessage')
  @DocsEditable()
  @Experimental() // untriaged
  void postMessage(/*SerializedScriptValue*/ message, [List<MessagePort> transfer]) 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('ServiceWorkerClients')
@Experimental() // untriaged
@Native("ServiceWorkerClients")
class ServiceWorkerClients extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ServiceWorkerClients._() { throw new UnsupportedError("Not supported"); }

  @DomName('ServiceWorkerClients.getAll')
  @DocsEditable()
  @Experimental() // untriaged
  Future getAll([Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _getAll_1(options_1);
    }
    return _getAll_2();
  }
  @JSName('getAll')
  @DomName('ServiceWorkerClients.getAll')
  @DocsEditable()
  @Experimental() // untriaged
  Future _getAll_1(options) native;
  @JSName('getAll')
  @DomName('ServiceWorkerClients.getAll')
  @DocsEditable()
  @Experimental() // untriaged
  Future _getAll_2() 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
@Native("ServiceWorkerContainer")
class ServiceWorkerContainer extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ServiceWorkerContainer._() { throw new UnsupportedError("Not supported"); }

  @DomName('ServiceWorkerContainer.controller')
  @DocsEditable()
  @Experimental() // untriaged
  final _ServiceWorker controller;

  @DomName('ServiceWorkerContainer.ready')
  @DocsEditable()
  @Experimental() // untriaged
  final Future ready;

  @DomName('ServiceWorkerContainer.getRegistration')
  @DocsEditable()
  @Experimental() // untriaged
  Future getRegistration([String documentURL]) native;

  @DomName('ServiceWorkerContainer.register')
  @DocsEditable()
  @Experimental() // untriaged
  Future register(String url, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _register_1(url, options_1);
    }
    return _register_2(url);
  }
  @JSName('register')
  @DomName('ServiceWorkerContainer.register')
  @DocsEditable()
  @Experimental() // untriaged
  Future _register_1(url, options) native;
  @JSName('register')
  @DomName('ServiceWorkerContainer.register')
  @DocsEditable()
  @Experimental() // untriaged
  Future _register_2(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('ServiceWorkerGlobalScope')
@Experimental() // untriaged
@Native("ServiceWorkerGlobalScope")
class ServiceWorkerGlobalScope extends WorkerGlobalScope {
  // To suppress missing implicit constructor warnings.
  factory ServiceWorkerGlobalScope._() { throw new UnsupportedError("Not supported"); }

  @DomName('ServiceWorkerGlobalScope.messageEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');

  @DomName('ServiceWorkerGlobalScope.caches')
  @DocsEditable()
  @Experimental() // untriaged
  final CacheStorage caches;

  @DomName('ServiceWorkerGlobalScope.clients')
  @DocsEditable()
  @Experimental() // untriaged
  final ServiceWorkerClients clients;

  @DomName('ServiceWorkerGlobalScope.scope')
  @DocsEditable()
  @Experimental() // untriaged
  final String scope;

  @DomName('ServiceWorkerGlobalScope.fetch')
  @DocsEditable()
  @Experimental() // untriaged
  Future _fetch(request, [Map requestInitDict]) {
    if ((request is String || request == null) && requestInitDict == null) {
      return _fetch_1(request);
    }
    if (requestInitDict != null && (request is String || request == null)) {
      var requestInitDict_1 = convertDartToNative_Dictionary(requestInitDict);
      return _fetch_2(request, requestInitDict_1);
    }
    if ((request is _Request || request == null) && requestInitDict == null) {
      return _fetch_3(request);
    }
    if (requestInitDict != null && (request is _Request || request == null)) {
      var requestInitDict_1 = convertDartToNative_Dictionary(requestInitDict);
      return _fetch_4(request, requestInitDict_1);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  @JSName('fetch')
  @DomName('ServiceWorkerGlobalScope.fetch')
  @DocsEditable()
  @Experimental() // untriaged
  Future _fetch_1(String request) native;
  @JSName('fetch')
  @DomName('ServiceWorkerGlobalScope.fetch')
  @DocsEditable()
  @Experimental() // untriaged
  Future _fetch_2(String request, requestInitDict) native;
  @JSName('fetch')
  @DomName('ServiceWorkerGlobalScope.fetch')
  @DocsEditable()
  @Experimental() // untriaged
  Future _fetch_3(_Request request) native;
  @JSName('fetch')
  @DomName('ServiceWorkerGlobalScope.fetch')
  @DocsEditable()
  @Experimental() // untriaged
  Future _fetch_4(_Request request, requestInitDict) native;

  @DomName('ServiceWorkerGlobalScope.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('ServiceWorkerRegistration')
@Experimental() // untriaged
@Native("ServiceWorkerRegistration")
class ServiceWorkerRegistration extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory ServiceWorkerRegistration._() { throw new UnsupportedError("Not supported"); }

  @DomName('ServiceWorkerRegistration.active')
  @DocsEditable()
  @Experimental() // untriaged
  final _ServiceWorker active;

  @DomName('ServiceWorkerRegistration.installing')
  @DocsEditable()
  @Experimental() // untriaged
  final _ServiceWorker installing;

  @DomName('ServiceWorkerRegistration.scope')
  @DocsEditable()
  @Experimental() // untriaged
  final String scope;

  @DomName('ServiceWorkerRegistration.waiting')
  @DocsEditable()
  @Experimental() // untriaged
  final _ServiceWorker waiting;

  @DomName('ServiceWorkerRegistration.unregister')
  @DocsEditable()
  @Experimental() // untriaged
  Future unregister() 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('HTMLShadowElement')
@SupportedBrowser(SupportedBrowser.CHROME, '26')
@Experimental()
// https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#shadow-element
@Native("HTMLShadowElement")
class ShadowElement extends HtmlElement {
  // 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.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
@Native("ShadowRoot")
class ShadowRoot extends DocumentFragment {
  // To suppress missing implicit constructor warnings.
  factory ShadowRoot._() { throw new UnsupportedError("Not supported"); }

  @DomName('ShadowRoot.activeElement')
  @DocsEditable()
  final Element activeElement;

  @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;

  @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.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.createShadowRoot||'
                 'Element.prototype.webkitCreateShadowRoot)');

  static bool _shadowRootDeprecationReported = false;
  static void _shadowRootDeprecationReport() {
    if (!_shadowRootDeprecationReported) {
      window.console.warn('''
ShadowRoot.resetStyleInheritance and ShadowRoot.applyAuthorStyles now deprecated in dart:html.
Please remove them from your code.
''');
      _shadowRootDeprecationReported = true;
    }
  }

  @deprecated
  bool get resetStyleInheritance {
    _shadowRootDeprecationReport();
    // Default value from when it was specified.
    return false;
  }

  @deprecated
  set resetStyleInheritance(bool value) {
    _shadowRootDeprecationReport();
  }

  @deprecated
  bool get applyAuthorStyles {
    _shadowRootDeprecationReport();
    // Default value from when it was specified.
    return false;
  }

  @deprecated
  set applyAuthorStyles(bool value) {
    _shadowRootDeprecationReport();
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All 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()
@Native("SharedWorker")
class SharedWorker extends EventTarget implements AbstractWorker {
  // 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
@Native("SharedWorkerGlobalScope")
class SharedWorkerGlobalScope extends WorkerGlobalScope {
  // 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()
@Native("SourceBuffer")
class SourceBuffer extends EventTarget {
  // 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()
@Native("SourceBufferList")
class SourceBufferList extends EventTarget with ListMixin<SourceBuffer>, ImmutableListMixin<SourceBuffer> implements JavaScriptIndexingBehavior, List<SourceBuffer> {
  // 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.index(index, this);
    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.


  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')
@Native("HTMLSourceElement")
class SourceElement extends HtmlElement {
  // 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.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String integrity;

  @DomName('HTMLSourceElement.media')
  @DocsEditable()
  String media;

  @DomName('HTMLSourceElement.sizes')
  @DocsEditable()
  @Experimental() // untriaged
  String sizes;

  @DomName('HTMLSourceElement.src')
  @DocsEditable()
  String src;

  @DomName('HTMLSourceElement.srcset')
  @DocsEditable()
  @Experimental() // untriaged
  String srcset;

  @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
@Native("SourceInfo")
class SourceInfo extends Interceptor {
  // 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')
@Native("HTMLSpanElement")
class SpanElement extends HtmlElement {
  // 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()
@Native("SpeechGrammar")
class SpeechGrammar extends Interceptor {
  // 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()
@Native("SpeechGrammarList")
class SpeechGrammarList extends Interceptor with ListMixin<SpeechGrammar>, ImmutableListMixin<SpeechGrammar> implements JavaScriptIndexingBehavior, List<SpeechGrammar> {
  // 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.index(index, this);
    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.


  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) 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
@Native("SpeechRecognition")
class SpeechRecognition extends EventTarget {
  // 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
@Native("SpeechRecognitionAlternative")
class SpeechRecognitionAlternative extends Interceptor {
  // 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
@Native("SpeechRecognitionError")
class SpeechRecognitionError extends Event {
  // 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
@Native("SpeechRecognitionEvent")
class SpeechRecognitionEvent extends Event {
  // 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
@Native("SpeechRecognitionResult")
class SpeechRecognitionResult extends Interceptor {
  // 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()
@Native("SpeechSynthesis")
class SpeechSynthesis extends EventTarget {
  // 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()
@Native("SpeechSynthesisEvent")
class SpeechSynthesisEvent extends Event {
  // 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()
@Native("SpeechSynthesisUtterance")
class SpeechSynthesisUtterance extends EventTarget {
  // 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()
@Native("SpeechSynthesisVoice")
class SpeechSynthesisVoice extends Interceptor {
  // 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()
@Native("Storage")
class Storage extends Interceptor
    implements Map<String, String> {

  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()
@Native("StorageEvent")
class StorageEvent extends Event {
  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()
@Native("StorageInfo")
class StorageInfo extends Interceptor {
  // 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()
@Native("StorageQuota")
class StorageQuota extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory StorageQuota._() { throw new UnsupportedError("Not supported"); }

  @DomName('StorageQuota.supportedTypes')
  @DocsEditable()
  @Experimental() // untriaged
  final List<String> supportedTypes;

  @DomName('StorageQuota.queryInfo')
  @DocsEditable()
  @Experimental() // untriaged
  Future queryInfo(String type) native;

  @DomName('StorageQuota.requestPersistentQuota')
  @DocsEditable()
  @Experimental() // untriaged
  Future requestPersistentQuota(int newQuota) 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('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')
@Native("HTMLStyleElement")
class StyleElement extends HtmlElement {
  // 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.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
@Native("StyleMedia")
class StyleMedia extends Interceptor {
  // 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')
@Native("StyleSheet")
class StyleSheet extends Interceptor {
  // 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')
@Native("HTMLTableCaptionElement")
class TableCaptionElement extends HtmlElement {
  // 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')
@Native("HTMLTableCellElement,HTMLTableDataCellElement,HTMLTableHeaderCellElement")
class TableCellElement extends HtmlElement {
  // 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')
@Native("HTMLTableColElement")
class TableColElement extends HtmlElement {
  // 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')
@Native("HTMLTableElement")
class TableElement extends HtmlElement {

  @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')
@Native("HTMLTableRowElement")
class TableRowElement extends HtmlElement {

  @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')
@Native("HTMLTableSectionElement")
class TableSectionElement extends HtmlElement {

  @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
@Native("HTMLTemplateElement")
class TemplateElement extends HtmlElement {
  // 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')
@Native("Text")
class Text extends CharacterData {
  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')
@Native("HTMLTextAreaElement")
class TextAreaElement extends HtmlElement {
  // 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()
@Native("TextEvent")
class TextEvent extends UIEvent {
  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')
@Native("TextMetrics")
class TextMetrics extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory TextMetrics._() { throw new UnsupportedError("Not supported"); }

  @DomName('TextMetrics.actualBoundingBoxAscent')
  @DocsEditable()
  @Experimental() // untriaged
  final double actualBoundingBoxAscent;

  @DomName('TextMetrics.actualBoundingBoxDescent')
  @DocsEditable()
  @Experimental() // untriaged
  final double actualBoundingBoxDescent;

  @DomName('TextMetrics.actualBoundingBoxLeft')
  @DocsEditable()
  @Experimental() // untriaged
  final double actualBoundingBoxLeft;

  @DomName('TextMetrics.actualBoundingBoxRight')
  @DocsEditable()
  @Experimental() // untriaged
  final double actualBoundingBoxRight;

  @DomName('TextMetrics.alphabeticBaseline')
  @DocsEditable()
  @Experimental() // untriaged
  final double alphabeticBaseline;

  @DomName('TextMetrics.emHeightAscent')
  @DocsEditable()
  @Experimental() // untriaged
  final double emHeightAscent;

  @DomName('TextMetrics.emHeightDescent')
  @DocsEditable()
  @Experimental() // untriaged
  final double emHeightDescent;

  @DomName('TextMetrics.fontBoundingBoxAscent')
  @DocsEditable()
  @Experimental() // untriaged
  final double fontBoundingBoxAscent;

  @DomName('TextMetrics.fontBoundingBoxDescent')
  @DocsEditable()
  @Experimental() // untriaged
  final double fontBoundingBoxDescent;

  @DomName('TextMetrics.hangingBaseline')
  @DocsEditable()
  @Experimental() // untriaged
  final double hangingBaseline;

  @DomName('TextMetrics.ideographicBaseline')
  @DocsEditable()
  @Experimental() // untriaged
  final double ideographicBaseline;

  @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()
@Native("TextTrack")
class TextTrack extends EventTarget {
  // 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()
@Native("TextTrackCue")
class TextTrackCue extends EventTarget {
  // 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()
@Native("TextTrackCueList")
class TextTrackCueList extends Interceptor with ListMixin<TextTrackCue>, ImmutableListMixin<TextTrackCue> implements List<TextTrackCue>, JavaScriptIndexingBehavior {
  // 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.index(index, this);
    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.


  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()
@Native("TextTrackList")
class TextTrackList extends EventTarget with ListMixin<TextTrack>, ImmutableListMixin<TextTrack> implements JavaScriptIndexingBehavior, List<TextTrack> {
  // 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.index(index, this);
    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.


  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()
@Native("TimeRanges")
class TimeRanges extends Interceptor {
  // 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.

// 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
@Native("Timing")
class Timing extends Interceptor {
  // 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.__getter__')
  @DocsEditable()
  @Experimental() // untriaged
  Object __getter__(String name) native;

  @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')
@Native("HTMLTitleElement")
class TitleElement extends HtmlElement {
  // 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()
@Native("Touch")
class Touch extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Touch._() { throw new UnsupportedError("Not supported"); }

  @JSName('clientX')
  @DomName('Touch.clientX')
  @DocsEditable()
  final double _clientX;

  @JSName('clientY')
  @DomName('Touch.clientY')
  @DocsEditable()
  final double _clientY;

  @DomName('Touch.force')
  @DocsEditable()
  @Experimental() // untriaged
  final double force;

  @DomName('Touch.identifier')
  @DocsEditable()
  final int identifier;

  @JSName('pageX')
  @DomName('Touch.pageX')
  @DocsEditable()
  final double _pageX;

  @JSName('pageY')
  @DomName('Touch.pageY')
  @DocsEditable()
  final double _pageY;

  @JSName('radiusX')
  @DomName('Touch.radiusX')
  @DocsEditable()
  @Experimental() // untriaged
  final double _radiusX;

  @JSName('radiusY')
  @DomName('Touch.radiusY')
  @DocsEditable()
  @Experimental() // untriaged
  final double _radiusY;

  @JSName('screenX')
  @DomName('Touch.screenX')
  @DocsEditable()
  final double _screenX;

  @JSName('screenY')
  @DomName('Touch.screenY')
  @DocsEditable()
  final double _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('webkitRotationAngle')
  @DomName('Touch.webkitRotationAngle')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  final double rotationAngle;


// As of Chrome 37, these all changed from long to double.  This code
// preserves backwards compatability for the time being.
  int get __clientX => JS('num', '#.clientX', this).round();
  int get __clientY => JS('num', '#.clientY', this).round();
  int get __screenX => JS('num', '#.screenX', this).round();
  int get __screenY => JS('num', '#.screenY', this).round();
  int get __pageX => JS('num', '#.pageX', this).round();
  int get __pageY => JS('num', '#.pageY', this).round();
  int get __radiusX => JS('num', '#.radiusX', this).round();
  int get __radiusY => JS('num', '#.radiusY', this).round();

  @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);

  @DomName('Touch.radiusX')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  int get radiusX => __radiusX;

  @DomName('Touch.radiusY')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  int get radiusY => __radiusY;

}
// 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()
@Native("TouchEvent")
class TouchEvent extends UIEvent {
  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 unused1, int unused2, int unused3, int unused4, 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()
@Native("TouchList")
class TouchList extends Interceptor with ListMixin<Touch>, ImmutableListMixin<Touch> implements JavaScriptIndexingBehavior, List<Touch> {
  /// 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.index(index, this);
    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.


  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()
@Native("HTMLTrackElement")
class TrackElement extends HtmlElement {
  // 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.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String integrity;

  @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()
@Native("TrackEvent")
class TrackEvent extends Event {
  // 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')
@Native("TransitionEvent,WebKitTransitionEvent")
class TransitionEvent extends Event {
  // 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()
@Native("TreeWalker")
class TreeWalker extends Interceptor {
  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')
@Native("UIEvent")
class UIEvent extends 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 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')
@Native("HTMLUListElement")
class UListElement extends HtmlElement {
  // 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')
@Native("HTMLUnknownElement")
class UnknownElement extends HtmlElement {
  // 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')
@Native("URL")
class Url extends Interceptor implements UrlUtils {

  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);

  @DomName('URL.toString')
  @DocsEditable()
  String toString() => JS('String', 'String(#)', this);

  // 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 origin;

  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')
@Native("ValidityState")
class ValidityState extends Interceptor {
  // 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')
@Native("HTMLVideoElement")
class VideoElement extends MediaElement implements CanvasImageSource {
  // 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
@Native("VideoPlaybackQuality")
class VideoPlaybackQuality extends Interceptor {
  // 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.


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

  @DomName('VideoTrack.id')
  @DocsEditable()
  @Experimental() // untriaged
  final String id;

  @DomName('VideoTrack.kind')
  @DocsEditable()
  @Experimental() // untriaged
  final String kind;

  @DomName('VideoTrack.label')
  @DocsEditable()
  @Experimental() // untriaged
  final String label;

  @DomName('VideoTrack.language')
  @DocsEditable()
  @Experimental() // untriaged
  final String language;

  @DomName('VideoTrack.selected')
  @DocsEditable()
  @Experimental() // untriaged
  bool selected;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

  @DomName('VideoTrackList.changeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> changeEvent = const EventStreamProvider<Event>('change');

  @DomName('VideoTrackList.length')
  @DocsEditable()
  @Experimental() // untriaged
  final int length;

  @DomName('VideoTrackList.selectedIndex')
  @DocsEditable()
  @Experimental() // untriaged
  final int selectedIndex;

  @DomName('VideoTrackList.__getter__')
  @DocsEditable()
  @Experimental() // untriaged
  VideoTrack __getter__(int index) native;

  @DomName('VideoTrackList.getTrackById')
  @DocsEditable()
  @Experimental() // untriaged
  VideoTrack getTrackById(String id) native;

  @DomName('VideoTrackList.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.

// 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
@Native("VTTCue")
class VttCue extends TextTrackCue {
  // 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
@Native("VTTRegion")
class VttRegion extends Interceptor {
  // 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
@Native("VTTRegionList")
class VttRegionList extends Interceptor {
  // 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()
@Native("WebSocket")
class WebSocket extends EventTarget {
  // 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 String || protocol_OR_protocols == null) && (url is String || url == null)) {
      return WebSocket._create_2(url, protocol_OR_protocols);
    }
    if ((protocol_OR_protocols is List<String> || protocol_OR_protocols == null) && (url is String || url == null)) {
      List protocols_1 = convertDartToNative_StringArray(protocol_OR_protocols);
      return WebSocket._create_3(url, protocols_1);
    }
    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')
@Native("WheelEvent")
class WheelEvent extends MouseEvent {

  factory WheelEvent(String type,
      {Window view, num deltaX: 0, num deltaY: 0, num deltaZ: 0,
      int deltaMode: 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}) {

    var options = {
      'view': view,
      'deltaMode': deltaMode,
      'deltaX': deltaX,
      'deltaY': deltaY,
      'deltaZ': deltaZ,
      'detail': detail,
      'screenX': screenX,
      'screenY': screenY,
      'clientX': clientX,
      'clientY': clientY,
      'button': button,
      'bubbles': canBubble,
      'cancelable': cancelable,
      'ctrlKey': ctrlKey,
      'altKey': altKey,
      'shiftKey': shiftKey,
      'metaKey': metaKey,
      'relatedTarget': relatedTarget,
    };

    if (view == null) {
      view = window;
    }

    return JS('WheelEvent', 'new WheelEvent(#, #)',
        type, convertDartToNative_Dictionary(options));

  }

  // 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()
  final double _deltaX;

  @JSName('deltaY')
  @DomName('WheelEvent.deltaY')
  @DocsEditable()
  final double _deltaY;

  @DomName('WheelEvent.deltaZ')
  @DocsEditable()
  final double deltaZ;


  /**
   * 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;
    }
    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;
    }
    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')
@Native("Window,DOMWindow")
class Window extends EventTarget implements WindowEventHandlers, WindowBase, GlobalEventHandlers, _WindowTimers, WindowBase64 {

  /**
   * 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.
   */
  set location(value) {
    _location = value;
  }

  // Native getter and setter to access raw Location object.
  dynamic get _location => JS('Location|Null', '#.location', this);
  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);
  }

  /**
   * convertPointFromNodeToPage and convertPointFromPageToNode are removed.
   * see http://dev.w3.org/csswg/cssom-view/#geometry
   */
  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');

  @DomName('Window.loadstartEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> loadStartEvent = const EventStreamProvider<Event>('loadstart');

  /**
   * 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');

  @DomName('Window.progressEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> progressEvent = const EventStreamProvider<Event>('progress');

  /**
   * 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;

  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;

  @JSName('pageXOffset')
  /**
   * 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 double _pageXOffset;

  @JSName('pageYOffset')
  /**
   * 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 double _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)) {
      return _convertNativeToDart_Window(__getter___1(index_OR_name));
    }
    if ((index_OR_name is String)) {
      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> transfer]) {
    if (transfer != null) {
      var message_1 = convertDartToNative_SerializedScriptValue(message);
      _postMessage_1(message_1, targetOrigin, transfer);
      return;
    }
    var message_1 = convertDartToNative_SerializedScriptValue(message);
    _postMessage_2(message_1, targetOrigin);
    return;
  }
  @JSName('postMessage')
  @DomName('Window.postMessage')
  @DocsEditable()
  void _postMessage_1(message, targetOrigin, List<MessagePort> transfer) 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(x, y, [Map scrollOptions]) {
    if ((y is num) && (x is num) && scrollOptions == null) {
      _scroll_1(x, y);
      return;
    }
    if (scrollOptions != null && (y is num) && (x is num)) {
      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
      _scroll_2(x, y, scrollOptions_1);
      return;
    }
    if ((y is int) && (x is int) && scrollOptions == null) {
      _scroll_3(x, y);
      return;
    }
    if (scrollOptions != null && (y is int) && (x is int)) {
      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
      _scroll_4(x, y, scrollOptions_1);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  @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(num x, num y) 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(num x, num 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_3(int x, int y) 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_4(int x, int y, scrollOptions) 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(x, y, [Map scrollOptions]) {
    if ((y is num) && (x is num) && scrollOptions == null) {
      _scrollBy_1(x, y);
      return;
    }
    if (scrollOptions != null && (y is num) && (x is num)) {
      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
      _scrollBy_2(x, y, scrollOptions_1);
      return;
    }
    if ((y is int) && (x is int) && scrollOptions == null) {
      _scrollBy_3(x, y);
      return;
    }
    if (scrollOptions != null && (y is int) && (x is int)) {
      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
      _scrollBy_4(x, y, scrollOptions_1);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  @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(num x, num y) 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(num x, num 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_3(int x, int y) 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_4(int x, int y, scrollOptions) 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(x, y, [Map scrollOptions]) {
    if ((y is num) && (x is num) && scrollOptions == null) {
      _scrollTo_1(x, y);
      return;
    }
    if (scrollOptions != null && (y is num) && (x is num)) {
      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
      _scrollTo_2(x, y, scrollOptions_1);
      return;
    }
    if ((y is int) && (x is int) && scrollOptions == null) {
      _scrollTo_3(x, y);
      return;
    }
    if (scrollOptions != null && (y is int) && (x is int)) {
      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
      _scrollTo_4(x, y, scrollOptions_1);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  @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(num x, num y) 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(num x, num 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_3(int x, int y) 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_4(int x, int y, scrollOptions) 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;

  @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);

  @DomName('Window.oncanplay')
  @DocsEditable()
  Stream<Event> get onCanPlay => Element.canPlayEvent.forTarget(this);

  @DomName('Window.oncanplaythrough')
  @DocsEditable()
  Stream<Event> get onCanPlayThrough => Element.canPlayThroughEvent.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);

  @DomName('Window.ondurationchange')
  @DocsEditable()
  Stream<Event> get onDurationChange => Element.durationChangeEvent.forTarget(this);

  @DomName('Window.onemptied')
  @DocsEditable()
  Stream<Event> get onEmptied => Element.emptiedEvent.forTarget(this);

  @DomName('Window.onended')
  @DocsEditable()
  Stream<Event> get onEnded => Element.endedEvent.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);

  @DomName('Window.onloadeddata')
  @DocsEditable()
  Stream<Event> get onLoadedData => Element.loadedDataEvent.forTarget(this);

  @DomName('Window.onloadedmetadata')
  @DocsEditable()
  Stream<Event> get onLoadedMetadata => Element.loadedMetadataEvent.forTarget(this);

  @DomName('Window.onloadstart')
  @DocsEditable()
  Stream<Event> get onLoadStart => loadStartEvent.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);

  @DomName('Window.onpause')
  @DocsEditable()
  Stream<Event> get onPause => Element.pauseEvent.forTarget(this);

  @DomName('Window.onplay')
  @DocsEditable()
  Stream<Event> get onPlay => Element.playEvent.forTarget(this);

  @DomName('Window.onplaying')
  @DocsEditable()
  Stream<Event> get onPlaying => Element.playingEvent.forTarget(this);

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

  @DomName('Window.onprogress')
  @DocsEditable()
  Stream<Event> get onProgress => progressEvent.forTarget(this);

  @DomName('Window.onratechange')
  @DocsEditable()
  Stream<Event> get onRateChange => Element.rateChangeEvent.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);

  @DomName('Window.onseeked')
  @DocsEditable()
  Stream<Event> get onSeeked => Element.seekedEvent.forTarget(this);

  @DomName('Window.onseeking')
  @DocsEditable()
  Stream<Event> get onSeeking => Element.seekingEvent.forTarget(this);

  /// Stream of `select` events handled by this [Window].
  @DomName('Window.onselect')
  @DocsEditable()
  Stream<Event> get onSelect => Element.selectEvent.forTarget(this);

  @DomName('Window.onstalled')
  @DocsEditable()
  Stream<Event> get onStalled => Element.stalledEvent.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);

  @DomName('Window.onsuspend')
  @DocsEditable()
  Stream<Event> get onSuspend => Element.suspendEvent.forTarget(this);

  @DomName('Window.ontimeupdate')
  @DocsEditable()
  Stream<Event> get onTimeUpdate => Element.timeUpdateEvent.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);

  @DomName('Window.onvolumechange')
  @DocsEditable()
  Stream<Event> get onVolumeChange => Element.volumeChangeEvent.forTarget(this);

  @DomName('Window.onwaiting')
  @DocsEditable()
  Stream<Event> get onWaiting => Element.waitingEvent.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);
  }

  @DomName('Window.pageXOffset')
  @DocsEditable()
  int get pageXOffset => JS('num', '#.pageXOffset', this).round();

  @DomName('Window.pageYOffset')
  @DocsEditable()
  int get pageYOffset => JS('num', '#.pageYOffset', this).round();

  /**
   * 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.
   */
  @DomName('Window.scrollX')
  @DocsEditable()
  int get scrollX => JS('bool', '("scrollX" in #)', this) ?
      JS('num', '#.scrollX', this).round() :
      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.
   */
  @DomName('Window.scrollY')
  @DocsEditable()
  int get scrollY => JS('bool', '("scrollY" in #)', this) ?
      JS('num', '#.scrollY', this).round() :
      document.documentElement.scrollTop;
}

class _BeforeUnloadEvent extends _WrappedEvent implements BeforeUnloadEvent {
  String _returnValue;

  _BeforeUnloadEvent(Event base): super(base);

  String get returnValue => _returnValue;

  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
@Native("Worker")
class Worker extends EventTarget implements AbstractWorker {
  // 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> transfer]) 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
@Native("WorkerConsole")
class WorkerConsole extends ConsoleBase {
  // 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('WorkerGlobalScope')
@Experimental() // untriaged
@Native("WorkerGlobalScope")
class WorkerGlobalScope extends EventTarget implements _WindowTimers, WindowBase64 {
  // 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 Crypto 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;

  @DomName('WorkerGlobalScope.close')
  @DocsEditable()
  @Experimental() // untriaged
  void close() native;

  @DomName('WorkerGlobalScope.importScripts')
  @DocsEditable()
  @Experimental() // untriaged
  void importScripts(String urls) 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
@Native("WorkerPerformance")
class WorkerPerformance extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory WorkerPerformance._() { throw new UnsupportedError("Not supported"); }

  @DomName('WorkerPerformance.memory')
  @DocsEditable()
  @Experimental() // untriaged
  final MemoryInfo memory;

  @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
@Native("XPathEvaluator")
class XPathEvaluator extends Interceptor {
  // 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
@Native("XPathExpression")
class XPathExpression extends Interceptor {
  // 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
@Native("XPathNSResolver")
class XPathNSResolver extends Interceptor {
  // 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
@Native("XPathResult")
class XPathResult extends Interceptor {
  // 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
@Native("XMLDocument")
class XmlDocument extends Document {
  // 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
@Native("XMLSerializer")
class XmlSerializer extends Interceptor {
  // 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
@Native("XSLTProcessor")
class XsltProcessor extends Interceptor {
  // 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')
@Native("Attr")
class _Attr extends Node {
  // 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;

  // Use implementation from Node.
  // final String nodeValue;

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

  set text(String value) {
    JS("void", "#.textContent = #", this, value);
  }

  @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
@Native("CSSPrimitiveValue")
abstract class _CSSPrimitiveValue extends _CSSValue {
  // 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
@Native("CSSUnknownRule")
abstract class _CSSUnknownRule extends CssRule {
  // 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
@Native("CSSValue")
abstract class _CSSValue extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _CSSValue._() { 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('Cache')
@Experimental() // untriaged
@Native("Cache")
abstract class _Cache extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _Cache._() { 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('CanvasPathMethods')
@Experimental() // untriaged
abstract class _CanvasPathMethods extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _CanvasPathMethods._() { 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')
@Native("ClientRect")
class _ClientRect extends Interceptor implements Rectangle {

  // 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')
@Native("ClientRectList,DOMRectList")
class _ClientRectList extends Interceptor with ListMixin<Rectangle>, ImmutableListMixin<Rectangle> implements List<Rectangle>, JavaScriptIndexingBehavior {
  // 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.index(index, this);
    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.


  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
@Native("Counter")
abstract class _Counter extends Interceptor {
  // 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')
@Native("CSSRuleList")
class _CssRuleList extends Interceptor with ListMixin<CssRule>, ImmutableListMixin<CssRule> implements JavaScriptIndexingBehavior, List<CssRule> {
  // 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.index(index, this);
    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.


  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
@Native("CSSValueList")
class _CssValueList extends _CSSValue with ListMixin<_CSSValue>, ImmutableListMixin<_CSSValue> implements JavaScriptIndexingBehavior, List<_CSSValue> {
  // 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.index(index, this);
    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.


  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
@Native("DOMFileSystemSync")
abstract class _DOMFileSystemSync extends Interceptor {
  // 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('DirectoryEntrySync')
// http://www.w3.org/TR/file-system-api/#the-directoryentrysync-interface
@Experimental()
@Native("DirectoryEntrySync")
abstract class _DirectoryEntrySync extends _EntrySync {
  // 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()
@Native("DirectoryReaderSync")
abstract class _DirectoryReaderSync extends Interceptor {
  // 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
@Native("DocumentType")
abstract class _DocumentType extends Node implements ChildNode {
  // 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('DOMRect')
@Experimental() // untriaged
@Native("DOMRect")
class _DomRect extends DomRectReadOnly {
  // To suppress missing implicit constructor warnings.
  factory _DomRect._() { throw new UnsupportedError("Not supported"); }

  @DomName('DOMRect.DOMRect')
  @DocsEditable()
  factory _DomRect([num x, num y, num width, num height]) {
    if (height != null) {
      return _DomRect._create_1(x, y, width, height);
    }
    if (width != null) {
      return _DomRect._create_2(x, y, width);
    }
    if (y != null) {
      return _DomRect._create_3(x, y);
    }
    if (x != null) {
      return _DomRect._create_4(x);
    }
    return _DomRect._create_5();
  }
  static _DomRect _create_1(x, y, width, height) => JS('_DomRect', 'new DOMRect(#,#,#,#)', x, y, width, height);
  static _DomRect _create_2(x, y, width) => JS('_DomRect', 'new DOMRect(#,#,#)', x, y, width);
  static _DomRect _create_3(x, y) => JS('_DomRect', 'new DOMRect(#,#)', x, y);
  static _DomRect _create_4(x) => JS('_DomRect', 'new DOMRect(#)', x);
  static _DomRect _create_5() => JS('_DomRect', 'new DOMRect()');

  // Shadowing definition.
  num get height => JS("num", "#.height", this);

  set height(num value) {
    JS("void", "#.height = #", this, value);
  }

  // Shadowing definition.
  num get width => JS("num", "#.width", this);

  set width(num value) {
    JS("void", "#.width = #", this, value);
  }

  // Shadowing definition.
  num get x => JS("num", "#.x", this);

  set x(num value) {
    JS("void", "#.x = #", this, value);
  }

  // Shadowing definition.
  num get y => JS("num", "#.y", this);

  set y(num value) {
    JS("void", "#.y = #", 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.


@DocsEditable()
@DomName('EntrySync')
// http://www.w3.org/TR/file-system-api/#idl-def-EntrySync
@Experimental()
@Native("EntrySync")
abstract class _EntrySync extends Interceptor {
  // 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()
@Native("FileEntrySync")
abstract class _FileEntrySync extends _EntrySync {
  // 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()
@Native("FileReaderSync")
abstract class _FileReaderSync extends Interceptor {
  // 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()
@Native("FileWriterSync")
abstract class _FileWriterSync extends Interceptor {
  // 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()
@Native("GamepadList")
class _GamepadList extends Interceptor with ListMixin<Gamepad>, ImmutableListMixin<Gamepad> implements JavaScriptIndexingBehavior, List<Gamepad> {
  // 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.index(index, this);
    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.


  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
@Native("HTMLAllCollection")
abstract class _HTMLAllCollection extends Interceptor {
  // 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
@Native("HTMLAppletElement")
abstract class _HTMLAppletElement extends HtmlElement {
  // 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
@Native("HTMLDirectoryElement")
abstract class _HTMLDirectoryElement extends HtmlElement {
  // 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
@Native("HTMLFontElement")
abstract class _HTMLFontElement extends HtmlElement {
  // 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
@Native("HTMLFrameElement")
abstract class _HTMLFrameElement extends HtmlElement {
  // 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
@Native("HTMLFrameSetElement")
abstract class _HTMLFrameSetElement extends HtmlElement implements WindowEventHandlers {
  // 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
@Native("HTMLMarqueeElement")
abstract class _HTMLMarqueeElement extends HtmlElement {
  // 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
@Native("MutationEvent")
abstract class _MutationEvent extends Event {
  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
@Native("NamedNodeMap,MozNamedAttrMap")
class _NamedNodeMap extends Interceptor with ListMixin<Node>, ImmutableListMixin<Node> implements JavaScriptIndexingBehavior, List<Node> {
  // 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.index(index, this);
    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.


  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('PagePopupController')
@deprecated // nonstandard
@Native("PagePopupController")
abstract class _PagePopupController extends Interceptor {
  // 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
@Native("RGBColor")
abstract class _RGBColor extends Interceptor {
  // 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
@Native("Rect")
abstract class _Rect extends Interceptor {
  // 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('Request')
@Experimental() // untriaged
@Native("Request")
class _Request extends Body {
  // To suppress missing implicit constructor warnings.
  factory _Request._() { throw new UnsupportedError("Not supported"); }

  @DomName('Request.Request')
  @DocsEditable()
  factory _Request(input, [Map requestInitDict]) {
    if ((input is String || input == null) && requestInitDict == null) {
      return _Request._create_1(input);
    }
    if ((requestInitDict is Map || requestInitDict == null) && (input is String || input == null)) {
      var requestInitDict_1 = convertDartToNative_Dictionary(requestInitDict);
      return _Request._create_2(input, requestInitDict_1);
    }
    if ((input is _Request || input == null) && requestInitDict == null) {
      return _Request._create_3(input);
    }
    if ((requestInitDict is Map || requestInitDict == null) && (input is _Request || input == null)) {
      var requestInitDict_1 = convertDartToNative_Dictionary(requestInitDict);
      return _Request._create_4(input, requestInitDict_1);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static _Request _create_1(input) => JS('_Request', 'new Request(#)', input);
  static _Request _create_2(input, requestInitDict) => JS('_Request', 'new Request(#,#)', input, requestInitDict);
  static _Request _create_3(input) => JS('_Request', 'new Request(#)', input);
  static _Request _create_4(input, requestInitDict) => JS('_Request', 'new Request(#,#)', input, requestInitDict);

  @DomName('Request.credentials')
  @DocsEditable()
  @Experimental() // untriaged
  final String credentials;

  @DomName('Request.headers')
  @DocsEditable()
  @Experimental() // untriaged
  final Headers headers;

  @DomName('Request.mode')
  @DocsEditable()
  @Experimental() // untriaged
  final String mode;

  @DomName('Request.referrer')
  @DocsEditable()
  @Experimental() // untriaged
  final String referrer;

  @DomName('Request.url')
  @DocsEditable()
  @Experimental() // untriaged
  final String url;

  @DomName('Request.clone')
  @DocsEditable()
  @Experimental() // untriaged
  _Request clone() 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('Response')
@Experimental() // untriaged
@Native("Response")
abstract class _Response extends Body {
  // To suppress missing implicit constructor warnings.
  factory _Response._() { throw new UnsupportedError("Not supported"); }

  @DomName('Response.Response')
  @DocsEditable()
  factory _Response(body_OR_input, [Map requestInitDict_OR_responseInitDict]) {
    if ((body_OR_input is String || body_OR_input == null) && requestInitDict_OR_responseInitDict == null) {
      return _Response._create_1(body_OR_input);
    }
    if ((requestInitDict_OR_responseInitDict is Map || requestInitDict_OR_responseInitDict == null) && (body_OR_input is String || body_OR_input == null)) {
      var responseInitDict_1 = convertDartToNative_Dictionary(requestInitDict_OR_responseInitDict);
      return _Response._create_2(body_OR_input, responseInitDict_1);
    }
    if ((body_OR_input is Blob || body_OR_input == null) && requestInitDict_OR_responseInitDict == null) {
      return _Response._create_3(body_OR_input);
    }
    if ((requestInitDict_OR_responseInitDict is Map || requestInitDict_OR_responseInitDict == null) && (body_OR_input is Blob || body_OR_input == null)) {
      var responseInitDict_1 = convertDartToNative_Dictionary(requestInitDict_OR_responseInitDict);
      return _Response._create_4(body_OR_input, responseInitDict_1);
    }
    if ((body_OR_input is TypedData || body_OR_input == null) && requestInitDict_OR_responseInitDict == null) {
      return _Response._create_5(body_OR_input);
    }
    if ((requestInitDict_OR_responseInitDict is Map || requestInitDict_OR_responseInitDict == null) && (body_OR_input is TypedData || body_OR_input == null)) {
      var requestInitDict_1 = convertDartToNative_Dictionary(requestInitDict_OR_responseInitDict);
      return _Response._create_6(body_OR_input, requestInitDict_1);
    }
    if ((body_OR_input is ByteBuffer || body_OR_input == null) && requestInitDict_OR_responseInitDict == null) {
      return _Response._create_7(body_OR_input);
    }
    if ((requestInitDict_OR_responseInitDict is Map || requestInitDict_OR_responseInitDict == null) && (body_OR_input is ByteBuffer || body_OR_input == null)) {
      var requestInitDict_1 = convertDartToNative_Dictionary(requestInitDict_OR_responseInitDict);
      return _Response._create_8(body_OR_input, requestInitDict_1);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static _Response _create_1(body_OR_input) => JS('_Response', 'new Response(#)', body_OR_input);
  static _Response _create_2(body_OR_input, requestInitDict_OR_responseInitDict) => JS('_Response', 'new Response(#,#)', body_OR_input, requestInitDict_OR_responseInitDict);
  static _Response _create_3(body_OR_input) => JS('_Response', 'new Response(#)', body_OR_input);
  static _Response _create_4(body_OR_input, requestInitDict_OR_responseInitDict) => JS('_Response', 'new Response(#,#)', body_OR_input, requestInitDict_OR_responseInitDict);
  static _Response _create_5(body_OR_input) => JS('_Response', 'new Response(#)', body_OR_input);
  static _Response _create_6(body_OR_input, requestInitDict_OR_responseInitDict) => JS('_Response', 'new Response(#,#)', body_OR_input, requestInitDict_OR_responseInitDict);
  static _Response _create_7(body_OR_input) => JS('_Response', 'new Response(#)', body_OR_input);
  static _Response _create_8(body_OR_input, requestInitDict_OR_responseInitDict) => JS('_Response', 'new Response(#,#)', body_OR_input, requestInitDict_OR_responseInitDict);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All 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
@Native("ServiceWorker")
abstract class _ServiceWorker extends EventTarget implements AbstractWorker {
  // 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('SpeechRecognitionResultList')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechrecognitionresultlist
@Experimental()
@Native("SpeechRecognitionResultList")
class _SpeechRecognitionResultList extends Interceptor with ListMixin<SpeechRecognitionResult>, ImmutableListMixin<SpeechRecognitionResult> implements JavaScriptIndexingBehavior, List<SpeechRecognitionResult> {
  // 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.index(index, this);
    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.


  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')
@Native("StyleSheetList")
class _StyleSheetList extends Interceptor with ListMixin<StyleSheet>, ImmutableListMixin<StyleSheet> implements JavaScriptIndexingBehavior, List<StyleSheet> {
  // 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.index(index, this);
    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.


  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
@Native("SubtleCrypto")
abstract class _SubtleCrypto extends Interceptor {
  // 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
@Native("WebKitCSSFilterValue")
abstract class _WebKitCSSFilterValue extends _CssValueList {
  // 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
@Native("WebKitCSSMatrix")
abstract class _WebKitCSSMatrix extends Interceptor {
  // 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
@Native("WebKitCSSTransformValue")
abstract class _WebKitCSSTransformValue extends _CssValueList {
  // 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('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()
@Native("WorkerLocation")
abstract class _WorkerLocation extends Interceptor implements UrlUtilsReadOnly {
  // 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()
@Native("WorkerNavigator")
abstract class _WorkerNavigator extends Interceptor implements NavigatorCpu, NavigatorOnLine, NavigatorID {
  // To suppress missing implicit constructor warnings.
  factory _WorkerNavigator._() { throw new UnsupportedError("Not supported"); }

  // From NavigatorCPU

  // 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
@Native("XMLHttpRequestProgressEvent")
abstract class _XMLHttpRequestProgressEvent extends ProgressEvent {
  // 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.
   *
   * If this corresponds to one element, returns `true` if [value] is present
   * after the operation, and returns `false` if [value] is absent after the
   * operation.
   *
   * If this corresponds to many elements, `null` is always returned.
   *
   * [value] must be a valid 'token' representing a single class, i.e. a
   * non-empty string containing no whitespace.  To toggle multiple classes, use
   * [toggleAll].
   */
  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/).
   *
   * [value] must be a valid 'token' representing a single class, i.e. a
   * non-empty string containing no whitespace.
   */
  bool contains(String value);

  /**
   * Add the class [value] to element.
   *
   * [add] and [addAll] are the Dart equivalent of jQuery's
   * [addClass](http://api.jquery.com/addClass/).
   *
   * If this CssClassSet 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.
   *
   * [value] must be a valid 'token' representing a single class, i.e. a
   * non-empty string containing no whitespace.  To add multiple classes use
   * [addAll].
   */
  bool add(String value);

  /**
   * Remove the class [value] from element, and return true on successful
   * removal.
   *
   * [remove] and [removeAll] are the Dart equivalent of jQuery's
   * [removeClass](http://api.jquery.com/removeClass/).
   *
   * [value] must be a valid 'token' representing a single class, i.e. a
   * non-empty string containing no whitespace.  To remove multiple classes, use
   * [removeAll].
   */
  bool remove(Object value);

  /**
   * Add all classes specified in [iterable] to element.
   *
   * [add] and [addAll] are the Dart equivalent of jQuery's
   * [addClass](http://api.jquery.com/addClass/).
   *
   * Each element of [iterable] must be a valid 'token' representing a single
   * class, i.e. a non-empty string containing no whitespace.
   */
  void addAll(Iterable<String> iterable);

  /**
   * Remove all classes specified in [iterable] from element.
   *
   * [remove] and [removeAll] are the Dart equivalent of jQuery's
   * [removeClass](http://api.jquery.com/removeClass/).
   *
   * Each element of [iterable] must be a valid 'token' representing a single
   * class, i.e. a non-empty string containing no whitespace.
   */
  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.
   *
   * Each element of [iterable] must be a valid 'token' representing a single
   * class, i.e. a non-empty string containing no whitespace.
   */
  void toggleAll(Iterable<String> iterable, [bool shouldAdd]);
}
// 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.
   */
  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.
   */
  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.
   */
  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.
   */
  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.
   */
  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.
   */
  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';
// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for 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 (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;

  // TODO(sra): Perhaps we should store the DomTokenList instead.
  final List<CssClassSetImpl> _sets;

  factory _MultiElementCssClassSet(Iterable<Element> elements) {
    return new _MultiElementCssClassSet._(elements,
        elements.map((Element e) => e.classes).toList());
  }

  _MultiElementCssClassSet._(this._elementIterable, this._sets);

  Set<String> readClasses() {
    var s = new LinkedHashSet<String>();
    _sets.forEach((CssClassSetImpl e) => s.addAll(e.readClasses()));
    return s;
  }

  void writeClasses(Set<String> s) {
    var classes = 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)) {
    _sets.forEach((CssClassSetImpl e) => e.modify(f));
  }

  /**
   * Adds the class [value] to the element if it is not on it, removes it if it
   * is.
   *
   * TODO(sra): It seems wrong to collect a 'changed' flag like this when the
   * underlying toggle returns an 'is set' flag.
   */
  bool toggle(String value, [bool shouldAdd]) =>
      _sets.fold(false,
          (bool changed, CssClassSetImpl e) =>
              e.toggle(value, shouldAdd) || changed);

  /**
   * 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) => _sets.fold(false,
      (bool changed, CssClassSetImpl e) => e.remove(value) || changed);
}

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) {
    _element.className = s.join(' ');
  }

  int get length => _classListLength(_classListOf(_element));
  bool get isEmpty => length == 0;
  bool get isNotEmpty => length != 0;

  void clear() {
    _element.className = '';
  }

  bool contains(Object value) {
    return _contains(_element, value);
  }

  bool add(String value) {
    return _add(_element, value);
  }

  bool remove(Object value) {
    return value is String && _remove(_element, value);
  }

  bool toggle(String value, [bool shouldAdd]) {
    return _toggle(_element, value, shouldAdd);
  }

  void addAll(Iterable<String> iterable) {
    _addAll(_element, iterable);
  }

  void removeAll(Iterable<String> iterable) {
    _removeAll(_element, iterable);
  }

  void retainAll(Iterable<String> iterable) {
    _removeWhere(_element, iterable.toSet().contains, false);
  }

  void removeWhere(bool test(String name)) {
    _removeWhere(_element, test, true);
  }

  void retainWhere(bool test(String name)) {
    _removeWhere(_element, test, false);
  }

  static bool _contains(Element _element, Object value) {
    return value is String && _classListContains(_classListOf(_element), value);
  }

  static bool _add(Element _element, String value) {
    DomTokenList list = _classListOf(_element);
    // Compute returned result independently of action upon the set.
    bool added = !_classListContainsBeforeAddOrRemove(list, value);
    _classListAdd(list, value);
    return added;
  }

  static bool _remove(Element _element, String value) {
    DomTokenList list = _classListOf(_element);
    bool removed = _classListContainsBeforeAddOrRemove(list, value);
    _classListRemove(list, value);
    return removed;
  }

  static bool _toggle(Element _element, String value, bool shouldAdd) {
    // There is no value that can be passed as the second argument of
    // DomTokenList.toggle that behaves the same as passing one argument.
    // `null` is seen as false, meaning 'remove'.
    return shouldAdd == null
        ? _toggleDefault(_element, value)
        : _toggleOnOff(_element, value, shouldAdd);
  }

  static bool _toggleDefault(Element _element, String value) {
    DomTokenList list = _classListOf(_element);
    return _classListToggle1(list, value);
  }

  static bool _toggleOnOff(Element _element, String value, bool shouldAdd) {
    DomTokenList list = _classListOf(_element);
    // IE's toggle does not take a second parameter. We would prefer:
    //
    //    return _classListToggle2(list, value, shouldAdd);
    //
    if (shouldAdd) {
      _classListAdd(list, value);
      return true;
    } else {
      _classListRemove(list, value);
      return false;
    }
  }

  static void _addAll(Element _element, Iterable<String> iterable) {
    DomTokenList list = _classListOf(_element);
    for (String value in iterable) {
      _classListAdd(list, value);
    }
  }

  static void _removeAll(Element _element, Iterable<String> iterable) {
    DomTokenList list = _classListOf(_element);
    for (var value in iterable) {
      _classListRemove(list, value);
    }
  }

  static void _removeWhere(
      Element _element, bool test(String name), bool doRemove) {
    DomTokenList list = _classListOf(_element);
    int i = 0;
    while (i < _classListLength(list)) {
      String item = list.item(i);
      if (doRemove == test(item)) {
        _classListRemove(list, item);
      } else {
        ++i;
      }
    }
  }

  // A collection of static methods for DomTokenList. These methods are a
  // work-around for the lack of annotations to express the full behaviour of
  // the DomTokenList methods.

  static DomTokenList _classListOf(Element e) =>
      JS('returns:DomTokenList;creates:DomTokenList;effects:none;depends:all;',
         '#.classList', e);

  static int _classListLength(DomTokenList list) =>
      JS('returns:JSUInt31;effects:none;depends:all;', '#.length', list);

  static bool _classListContains(DomTokenList list, String value) =>
      JS('returns:bool;effects:none;depends:all',
          '#.contains(#)', list, value);

  static bool _classListContainsBeforeAddOrRemove(
      DomTokenList list, String value) =>
      // 'throws:never' is a lie, since 'contains' will throw on an illegal
      // token.  However, we always call this function immediately prior to
      // add/remove/toggle with the same token.  Often the result of 'contains'
      // is unused and the lie makes it possible for the 'contains' instruction
      // to be removed.
      JS('returns:bool;effects:none;depends:all;throws:null(1)',
          '#.contains(#)', list, value);

  static void _classListAdd(DomTokenList list, String value) {
    // list.add(value);
    JS('', '#.add(#)', list, value);
  }

  static void _classListRemove(DomTokenList list, String value) {
    // list.remove(value);
    JS('', '#.remove(#)', list, value);
  }

  static bool _classListToggle1(DomTokenList list, String value) {
    return JS('bool', '#.toggle(#)', list, value);
  }

  static bool _classListToggle2(
      DomTokenList list, String value, bool shouldAdd) {
    return JS('bool', '#.toggle(#, #)', list, value, shouldAdd);
  }
}

/**
 * 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._safeTagName(element));
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    var tagName = Element._safeTagName(element);
    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 = new Set<String>();
  final Set<String> allowedAttributes = new Set<String>();
  final Set<String> allowedUriAttributes = new Set<String>();
  final UriPolicy uriPolicy;

  factory _SimpleNodeValidator.allowNavigation(UriPolicy uriPolicy) {
    return new _SimpleNodeValidator(uriPolicy,
      allowedElements: const [
        'A',
        'FORM'],
      allowedAttributes: const [
        '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: const [
        'A::href',
        'FORM::action',
      ]);
  }

  factory _SimpleNodeValidator.allowImages(UriPolicy uriPolicy) {
    return new _SimpleNodeValidator(uriPolicy,
      allowedElements: const [
        'IMG'
      ],
      allowedAttributes: const [
        'IMG::align',
        'IMG::alt',
        'IMG::border',
        'IMG::height',
        'IMG::hspace',
        'IMG::ismap',
        'IMG::name',
        'IMG::usemap',
        'IMG::vspace',
        'IMG::width',
      ],
      allowedUriAttributes: const [
        'IMG::src',
      ]);
  }

  factory _SimpleNodeValidator.allowTextElements() {
    return new _SimpleNodeValidator(null,
      allowedElements: const [
        '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.addAll(allowedElements ?? const []);
    allowedAttributes = allowedAttributes ?? const [];
    allowedUriAttributes = allowedUriAttributes ?? const [];
    var legalAttributes = allowedAttributes.where(
        (x) => !_Html5NodeValidator._uriAttributes.contains(x));
    var extraUriAttributes = allowedAttributes.where(
        (x) => _Html5NodeValidator._uriAttributes.contains(x));
    this.allowedAttributes.addAll(legalAttributes);
    this.allowedUriAttributes.addAll(allowedUriAttributes);
    this.allowedUriAttributes.addAll(extraUriAttributes);
  }

  bool allowsElement(Element element) {
    return allowedElements.contains(Element._safeTagName(element));
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    var tagName = Element._safeTagName(element);
    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._safeTagName(element));
      }
    }
    return allowCustomTag && allowedElements.contains(Element._safeTagName(element));
  }

  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;
    }
    // Firefox 37 has issues with creating foreign elements inside a
    // foreignobject tag as SvgElement. We don't want foreignobject contents
    // anyway, so just remove the whole tree outright. And we can't rely
    // on IE recognizing the SvgForeignObject type, so go by tagName. Bug 23144
    if (element is svg.SvgElement && Element._safeTagName(element) == 'foreignObject') {
      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; }

  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 postMessage property.  It may be
  // from a different frame - without a patched prototype - so we cannot
  // rely on Dart type checking.
  if (JS('bool', r'"postMessage" 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,
          convertDartToNative_SerializedScriptValue(message), targetOrigin);
    } else {
      JS('void', '#.postMessage(#,#,#)', _window,
          convertDartToNative_SerializedScriptValue(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
  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.');
  // 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;

  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,
      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);
    } 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);
      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');

  /** 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) {
    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<Element> 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<Element> 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);

  /**
   * A sanitizer for trees that we trust. It does no validation and allows
   * any elements. It is also more efficient, since it can pass the text
   * directly through to the underlying APIs without creating a document
   * fragment to be sanitized.
   */
  static const trusted = const _TrustedHtmlTreeSanitizer();
}

/**
 * A sanitizer for trees that we trust. It does no validation and allows
 * any elements.
 */
class _TrustedHtmlTreeSanitizer implements NodeTreeSanitizer {
  const _TrustedHtmlTreeSanitizer();

  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 == ':' || _hiddenAnchor.protocol == ''));
  }
}


class _ThrowsNodeValidator implements NodeValidator {
  final NodeValidator validator;

  _ThrowsNodeValidator(this.validator) {}

  bool allowsElement(Element element) {
    if (!validator.allowsElement(element)) {
      throw new ArgumentError(Element._safeTagName(element));
    }
    return true;
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (!validator.allowsAttribute(element, attributeName, value)) {
      throw new ArgumentError('${Element._safeTagName(element)}[$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, Node parent) {
      sanitizeNode(node, parent);

      var child = node.lastChild;
      while (child != null) {
        // Child may be removed during the walk.
        var nextChild = child.previousNode;
        walk(child, node);
        child = nextChild;
      }
    }
    walk(node, null);
  }

  /// Aggressively try to remove node.
  void _removeNode(Node node, Node parent) {
    // If we have the parent, it's presumably already passed more sanitization
    // or is the fragment, so ask it to remove the child. And if that fails
    // try to set the outer html.
    if (parent == null) {
      node.remove();
    } else {
      parent._removeChild(node);
    }
  }

  /// Sanitize the element, assuming we can't trust anything about it.
  void _sanitizeUntrustedElement(/* Element */ element, Node parent) {
    // If the _hasCorruptedAttributes does not successfully return false,
    // then we consider it corrupted and remove.
    // TODO(alanknight): This is a workaround because on Firefox
    // embed/object
    // tags typeof is "function", not "object". We don't recognize them, and
    // can't call methods. This does mean that you can't explicitly allow an
    // embed tag. The only thing that will let it through is a null
    // sanitizer that doesn't traverse the tree at all. But sanitizing while
    // allowing embeds seems quite unlikely. This is also the reason that we
    // can't declare the type of element, as an embed won't pass any type
    // check in dart2js.
    var corrupted = true;
    var attrs;
    var isAttr;
    try {
      // If getting/indexing attributes throws, count that as corrupt.
      attrs = element.attributes;
      isAttr = attrs['is'];
      var corruptedTest1 = Element._hasCorruptedAttributes(element);

      // On IE, erratically, the hasCorruptedAttributes test can return false,
      // even though it clearly is corrupted. A separate copy of the test
      // inlining just the basic check seems to help.
      corrupted = corruptedTest1 ? true : Element._hasCorruptedAttributesAdditionalCheck(element);
    } catch(e) {}
    var elementText = 'element unprintable';
    try {
      elementText = element.toString();
    } catch(e) {}
    try {
      var elementTagName = Element._safeTagName(element);
      _sanitizeElement(element, parent, corrupted, elementText, elementTagName,
          attrs, isAttr);
    } on ArgumentError { // Thrown by _ThrowsNodeValidator
      rethrow;
    } catch(e) {  // Unexpected exception sanitizing -> remove
      _removeNode(element, parent);
      window.console.warn('Removing corrupted element $elementText');
    }
  }

  /// Having done basic sanity checking on the element, and computed the
  /// important attributes we want to check, remove it if it's not valid
  /// or not allowed, either as a whole or particular attributes.
  void _sanitizeElement(Element element, Node parent, bool corrupted,
      String text, String tag, Map attrs, String isAttr) {
    if (false != corrupted) {
       _removeNode(element, parent);
      window.console.warn(
          'Removing element due to corrupted attributes on <$text>');
       return;
    }
    if (!validator.allowsElement(element)) {
      _removeNode(element, parent);
      window.console.warn(
          'Removing disallowed element <$tag> from $parent');
      return;
    }

    if (isAttr != null) {
      if (!validator.allowsAttribute(element, 'is', isAttr)) {
        _removeNode(element, parent);
        window.console.warn('Removing disallowed type extension '
            '<$tag is="$isAttr">');
        return;
      }
    }

    // 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 '
            '<$tag $name="${attrs[name]}">');
        attrs.remove(name);
      }
    }

    if (element is TemplateElement) {
      TemplateElement template = element;
      sanitizeTree(template.content);
     }
  }

  /// Sanitize the node and its children recursively.
  void sanitizeNode(Node node, Node parent) {
    switch (node.nodeType) {
      case Node.ELEMENT_NODE:
        _sanitizeUntrustedElement(node, parent);
        break;
      case Node.COMMENT_NODE:
      case Node.DOCUMENT_FRAGMENT_NODE:
      case Node.TEXT_NODE:
      case Node.CDATA_SECTION_NODE:
        break;
      default:
        _removeNode(node, parent);
    }
  }
}
