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

import 'dart:async';
import 'dart:collection';
import 'dart:_internal' hide Symbol, deprecated;
import 'dart:html_common';
import 'dart:indexed_db';
import 'dart:isolate';
import "dart:convert";
import 'dart:math';
import 'dart:_native_typed_data';
import 'dart:typed_data';
import 'dart:svg' as svg;
import 'dart:svg' show Matrix;
import 'dart:svg' show SvgSvgElement;
import 'dart:web_audio' as web_audio;
import 'dart:web_gl' as gl;
import 'dart:web_sql';
import 'dart:_isolate_helper' show IsolateNatives;
import 'dart:_foreign_helper' show JS, JS_INTERCEPTOR_CONSTANT;
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

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


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

export 'dart:math' show Rectangle, Point;





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

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

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

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

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

/**
 * Spawn a DOM isolate using the given URI in the same window.
 * This isolate is not concurrent.  It runs on the browser thread
 * with full access to the DOM.
 * Note: this API is still evolving and may move to dart:isolate.
 */
@Experimental()
Future<Isolate> spawnDomUri(Uri uri, List<String> args, message) {
  // TODO(17738): Implement this.
  throw new UnimplementedError();
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

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

  /// Stream of `error` events handled by this [AbstractWorker].
  @DomName('AbstractWorker.onerror')
  @DocsEditable()
  Stream<ErrorEvent> get onError => errorEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

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


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

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

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

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

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

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

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

  // From URLUtils

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

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

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

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

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

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

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

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

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

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

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

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


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

  @DomName('Animation.Animation')
  @DocsEditable()
  factory Animation(Element target, List<Map> keyframes, [timingInput]) {
    if ((timingInput is Map || timingInput == null) && (keyframes is List<Map> || keyframes == null) && (target is Element || target == null)) {
      return Animation._create_1(target, keyframes, timingInput);
    }
    if ((timingInput is num || timingInput == null) && (keyframes is List<Map> || keyframes == null) && (target is Element || target == null)) {
      return Animation._create_2(target, keyframes, timingInput);
    }
    if ((keyframes is List<Map> || keyframes == null) && (target is Element || target == null) && timingInput == null) {
      return Animation._create_3(target, keyframes);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static Animation _create_1(target, keyframes, timingInput) => JS('Animation', 'new Animation(#,#,#)', target, keyframes, timingInput);
  static Animation _create_2(target, keyframes, timingInput) => JS('Animation', 'new Animation(#,#,#)', target, keyframes, timingInput);
  static Animation _create_3(target, keyframes) => JS('Animation', 'new Animation(#,#)', target, keyframes);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  /// Stream of `updateready` events handled by this [ApplicationCache].
  @DomName('ApplicationCache.onupdateready')
  @DocsEditable()
  Stream<Event> get onUpdateReady => updateReadyEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

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

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

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

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

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

  // From URLUtils

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

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

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

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

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

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

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

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

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

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

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

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


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

  @DomName('HTMLAudioElement.HTMLAudioElement')
  @DocsEditable()
  factory AudioElement([String src]) {
    if (src != null) {
      return AudioElement._create_1(src);
    }
    return AudioElement._create_2();
  }
  static AudioElement _create_1(src) => JS('AudioElement', 'new Audio(#)', src);
  static AudioElement _create_2() => JS('AudioElement', 'new Audio()');
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  AudioElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

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


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

  @DomName('HTMLBRElement.HTMLBRElement')
  @DocsEditable()
  factory BRElement() => document.createElement("br");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  BRElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

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


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

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

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

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


@DocsEditable()
@DomName('BeforeLoadEvent')
@Experimental()
class BeforeLoadEvent extends Event native "BeforeLoadEvent" {
  // To suppress missing implicit constructor warnings.
  factory BeforeLoadEvent._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

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

  void set returnValue(String value) {
    JS("void", "#.returnValue = #", this, value);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

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

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

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

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

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

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

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  /// Stream of `unload` events handled by this [BodyElement].
  @DomName('HTMLBodyElement.onunload')
  @DocsEditable()
  ElementStream<Event> get onUnload => unloadEvent.forElement(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


@DocsEditable()
@DomName('CDATASection')
// http://dom.spec.whatwg.org/#cdatasection
@deprecated // deprecated
class CDataSection extends Text native "CDATASection" {
  // To suppress missing implicit constructor warnings.
  factory CDataSection._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

  /**
   * Adds a color stop to this gradient at the offset.
   *
   * The [offset] can range between 0.0 and 1.0.
   *
   * See also:
   *
   * * [Multiple Color Stops](https://developer.mozilla.org/en-US/docs/CSS/linear-gradient#Gradient_with_multiple_color_stops) from MDN.
   */
  @DomName('CanvasGradient.addColorStop')
  @DocsEditable()
  void addColorStop(num offset, String color) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
/**
 * An opaque object representing a pattern of image, canvas, or video.
 *
 * Created by calling [createPattern] on a [CanvasRenderingContext2D] object.
 *
 * Example usage:
 *
 *     var canvas = new CanvasElement(width: 600, height: 600);
 *     var ctx = canvas.context2D;
 *     var img = new ImageElement();
 *     // Image src needs to be loaded before pattern is applied.
 *     img.onLoad.listen((event) {
 *       // When the image is loaded, create a pattern
 *       // from the ImageElement.
 *       CanvasPattern pattern = ctx.createPattern(img, 'repeat');
 *       ctx.rect(0, 0, canvas.width, canvas.height);
 *       ctx.fillStyle = pattern;
 *       ctx.fill();
 *     });
 *     img.src = "images/foo.jpg";
 *     document.body.children.add(canvas);
 *
 * See also:
 * * [CanvasPattern](https://developer.mozilla.org/en-US/docs/DOM/CanvasPattern) from MDN.
 * * [CanvasPattern](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvaspattern) from whatwg.
 * * [CanvasPattern](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvaspattern) from W3C.
 */
@DomName('CanvasPattern')
class CanvasPattern extends Interceptor native "CanvasPattern" {
  // To suppress missing implicit constructor warnings.
  factory CanvasPattern._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

  /// Reference to the canvas element to which this context belongs.
  @DomName('CanvasRenderingContext.canvas')
  @DocsEditable()
  final CanvasElement canvas;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

  /** 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')
class CharacterData extends Node implements ChildNode native "CharacterData" {
  // To suppress missing implicit constructor warnings.
  factory CharacterData._() { throw new UnsupportedError("Not supported"); }

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

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

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

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

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

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

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

  // From ChildNode

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

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


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

  final Element nextElementSibling;

  final Element previousElementSibling;

  void remove();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

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

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

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


@DocsEditable()
@DomName('Comment')
class Comment extends CharacterData native "Comment" {
  factory Comment([String data]) {
    if (data != null) {
      return JS('Comment', '#.createComment(#)', document, data);
    }
    return JS('Comment', '#.createComment("")', document);
  }
  // To suppress missing implicit constructor warnings.
  factory Comment._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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

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

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

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

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

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('Console')
class Console {

  const Console._safe();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

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

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


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

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

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

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

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

  @DomName('HTMLContentElement.getDistributedNodes')
  @DocsEditable()
  @Returns('NodeList')
  @Creates('NodeList')
  List<Node> getDistributedNodes() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

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

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

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

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

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

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

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


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

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

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

  @DomName('Crypto.getRandomValues')
  @DocsEditable()
  @Creates('TypedData')
  @Returns('TypedData|Null')
  TypedData getRandomValues(TypedData array) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

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

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

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

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


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

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

  @JSName('supports')
  @DomName('CSS.supports')
  @DocsEditable()
  bool supportsCondition(String conditionText) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

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


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

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


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

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


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

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


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

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

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

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


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

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

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


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

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

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

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

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

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

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


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

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

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

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

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


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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  /** Sets the value of "mask-size" */
  void set maskSize(String value) {
    setProperty('${Device.cssPrefix}mask-size', value, '');
  }

  /** Gets the value of "max-height" */
  String get maxHeight =>
    getPropertyValue('max-height');

  /** Sets the value of "max-height" */
  void set maxHeight(String value) {
    setProperty('max-height', value, '');
  }

  /** Gets the value of "max-logical-height" */
  String get maxLogicalHeight =>
    getPropertyValue('${Device.cssPrefix}max-logical-height');

  /** Sets the value of "max-logical-height" */
  void set maxLogicalHeight(String value) {
    setProperty('${Device.cssPrefix}max-logical-height', value, '');
  }

  /** Gets the value of "max-logical-width" */
  String get maxLogicalWidth =>
    getPropertyValue('${Device.cssPrefix}max-logical-width');

  /** Sets the value of "max-logical-width" */
  void set maxLogicalWidth(String value) {
    setProperty('${Device.cssPrefix}max-logical-width', value, '');
  }

  /** Gets the value of "max-width" */
  String get maxWidth =>
    getPropertyValue('max-width');

  /** Sets the value of "max-width" */
  void set maxWidth(String value) {
    setProperty('max-width', value, '');
  }

  /** Gets the value of "max-zoom" */
  String get maxZoom =>
    getPropertyValue('max-zoom');

  /** Sets the value of "max-zoom" */
  void set maxZoom(String value) {
    setProperty('max-zoom', value, '');
  }

  /** Gets the value of "min-height" */
  String get minHeight =>
    getPropertyValue('min-height');

  /** Sets the value of "min-height" */
  void set minHeight(String value) {
    setProperty('min-height', value, '');
  }

  /** Gets the value of "min-logical-height" */
  String get minLogicalHeight =>
    getPropertyValue('${Device.cssPrefix}min-logical-height');

  /** Sets the value of "min-logical-height" */
  void set minLogicalHeight(String value) {
    setProperty('${Device.cssPrefix}min-logical-height', value, '');
  }

  /** Gets the value of "min-logical-width" */
  String get minLogicalWidth =>
    getPropertyValue('${Device.cssPrefix}min-logical-width');

  /** Sets the value of "min-logical-width" */
  void set minLogicalWidth(String value) {
    setProperty('${Device.cssPrefix}min-logical-width', value, '');
  }

  /** Gets the value of "min-width" */
  String get minWidth =>
    getPropertyValue('min-width');

  /** Sets the value of "min-width" */
  void set minWidth(String value) {
    setProperty('min-width', value, '');
  }

  /** Gets the value of "min-zoom" */
  String get minZoom =>
    getPropertyValue('min-zoom');

  /** Sets the value of "min-zoom" */
  void set minZoom(String value) {
    setProperty('min-zoom', value, '');
  }

  /** Gets the value of "nbsp-mode" */
  String get nbspMode =>
    getPropertyValue('${Device.cssPrefix}nbsp-mode');

  /** Sets the value of "nbsp-mode" */
  void set nbspMode(String value) {
    setProperty('${Device.cssPrefix}nbsp-mode', value, '');
  }

  /** Gets the value of "opacity" */
  String get opacity =>
    getPropertyValue('opacity');

  /** Sets the value of "opacity" */
  void set opacity(String value) {
    setProperty('opacity', value, '');
  }

  /** Gets the value of "order" */
  String get order =>
    getPropertyValue('${Device.cssPrefix}order');

  /** Sets the value of "order" */
  void set order(String value) {
    setProperty('${Device.cssPrefix}order', value, '');
  }

  /** Gets the value of "orientation" */
  String get orientation =>
    getPropertyValue('orientation');

  /** Sets the value of "orientation" */
  void set orientation(String value) {
    setProperty('orientation', value, '');
  }

  /** Gets the value of "orphans" */
  String get orphans =>
    getPropertyValue('orphans');

  /** Sets the value of "orphans" */
  void set orphans(String value) {
    setProperty('orphans', value, '');
  }

  /** Gets the value of "outline" */
  String get outline =>
    getPropertyValue('outline');

  /** Sets the value of "outline" */
  void set outline(String value) {
    setProperty('outline', value, '');
  }

  /** Gets the value of "outline-color" */
  String get outlineColor =>
    getPropertyValue('outline-color');

  /** Sets the value of "outline-color" */
  void set outlineColor(String value) {
    setProperty('outline-color', value, '');
  }

  /** Gets the value of "outline-offset" */
  String get outlineOffset =>
    getPropertyValue('outline-offset');

  /** Sets the value of "outline-offset" */
  void set outlineOffset(String value) {
    setProperty('outline-offset', value, '');
  }

  /** Gets the value of "outline-style" */
  String get outlineStyle =>
    getPropertyValue('outline-style');

  /** Sets the value of "outline-style" */
  void set outlineStyle(String value) {
    setProperty('outline-style', value, '');
  }

  /** Gets the value of "outline-width" */
  String get outlineWidth =>
    getPropertyValue('outline-width');

  /** Sets the value of "outline-width" */
  void set outlineWidth(String value) {
    setProperty('outline-width', value, '');
  }

  /** Gets the value of "overflow" */
  String get overflow =>
    getPropertyValue('overflow');

  /** Sets the value of "overflow" */
  void set overflow(String value) {
    setProperty('overflow', value, '');
  }

  /** Gets the value of "overflow-scrolling" */
  String get overflowScrolling =>
    getPropertyValue('${Device.cssPrefix}overflow-scrolling');

  /** Sets the value of "overflow-scrolling" */
  void set overflowScrolling(String value) {
    setProperty('${Device.cssPrefix}overflow-scrolling', value, '');
  }

  /** Gets the value of "overflow-wrap" */
  String get overflowWrap =>
    getPropertyValue('overflow-wrap');

  /** Sets the value of "overflow-wrap" */
  void set overflowWrap(String value) {
    setProperty('overflow-wrap', value, '');
  }

  /** Gets the value of "overflow-x" */
  String get overflowX =>
    getPropertyValue('overflow-x');

  /** Sets the value of "overflow-x" */
  void set overflowX(String value) {
    setProperty('overflow-x', value, '');
  }

  /** Gets the value of "overflow-y" */
  String get overflowY =>
    getPropertyValue('overflow-y');

  /** Sets the value of "overflow-y" */
  void set overflowY(String value) {
    setProperty('overflow-y', value, '');
  }

  /** Gets the value of "padding" */
  String get padding =>
    getPropertyValue('padding');

  /** Sets the value of "padding" */
  void set padding(String value) {
    setProperty('padding', value, '');
  }

  /** Gets the value of "padding-after" */
  String get paddingAfter =>
    getPropertyValue('${Device.cssPrefix}padding-after');

  /** Sets the value of "padding-after" */
  void set paddingAfter(String value) {
    setProperty('${Device.cssPrefix}padding-after', value, '');
  }

  /** Gets the value of "padding-before" */
  String get paddingBefore =>
    getPropertyValue('${Device.cssPrefix}padding-before');

  /** Sets the value of "padding-before" */
  void set paddingBefore(String value) {
    setProperty('${Device.cssPrefix}padding-before', value, '');
  }

  /** Gets the value of "padding-bottom" */
  String get paddingBottom =>
    getPropertyValue('padding-bottom');

  /** Sets the value of "padding-bottom" */
  void set paddingBottom(String value) {
    setProperty('padding-bottom', value, '');
  }

  /** Gets the value of "padding-end" */
  String get paddingEnd =>
    getPropertyValue('${Device.cssPrefix}padding-end');

  /** Sets the value of "padding-end" */
  void set paddingEnd(String value) {
    setProperty('${Device.cssPrefix}padding-end', value, '');
  }

  /** Gets the value of "padding-left" */
  String get paddingLeft =>
    getPropertyValue('padding-left');

  /** Sets the value of "padding-left" */
  void set paddingLeft(String value) {
    setProperty('padding-left', value, '');
  }

  /** Gets the value of "padding-right" */
  String get paddingRight =>
    getPropertyValue('padding-right');

  /** Sets the value of "padding-right" */
  void set paddingRight(String value) {
    setProperty('padding-right', value, '');
  }

  /** Gets the value of "padding-start" */
  String get paddingStart =>
    getPropertyValue('${Device.cssPrefix}padding-start');

  /** Sets the value of "padding-start" */
  void set paddingStart(String value) {
    setProperty('${Device.cssPrefix}padding-start', value, '');
  }

  /** Gets the value of "padding-top" */
  String get paddingTop =>
    getPropertyValue('padding-top');

  /** Sets the value of "padding-top" */
  void set paddingTop(String value) {
    setProperty('padding-top', value, '');
  }

  /** Gets the value of "page" */
  String get page =>
    getPropertyValue('page');

  /** Sets the value of "page" */
  void set page(String value) {
    setProperty('page', value, '');
  }

  /** Gets the value of "page-break-after" */
  String get pageBreakAfter =>
    getPropertyValue('page-break-after');

  /** Sets the value of "page-break-after" */
  void set pageBreakAfter(String value) {
    setProperty('page-break-after', value, '');
  }

  /** Gets the value of "page-break-before" */
  String get pageBreakBefore =>
    getPropertyValue('page-break-before');

  /** Sets the value of "page-break-before" */
  void set pageBreakBefore(String value) {
    setProperty('page-break-before', value, '');
  }

  /** Gets the value of "page-break-inside" */
  String get pageBreakInside =>
    getPropertyValue('page-break-inside');

  /** Sets the value of "page-break-inside" */
  void set pageBreakInside(String value) {
    setProperty('page-break-inside', value, '');
  }

  /** Gets the value of "perspective" */
  String get perspective =>
    getPropertyValue('${Device.cssPrefix}perspective');

  /** Sets the value of "perspective" */
  void set perspective(String value) {
    setProperty('${Device.cssPrefix}perspective', value, '');
  }

  /** Gets the value of "perspective-origin" */
  String get perspectiveOrigin =>
    getPropertyValue('${Device.cssPrefix}perspective-origin');

  /** Sets the value of "perspective-origin" */
  void set perspectiveOrigin(String value) {
    setProperty('${Device.cssPrefix}perspective-origin', value, '');
  }

  /** Gets the value of "perspective-origin-x" */
  String get perspectiveOriginX =>
    getPropertyValue('${Device.cssPrefix}perspective-origin-x');

  /** Sets the value of "perspective-origin-x" */
  void set perspectiveOriginX(String value) {
    setProperty('${Device.cssPrefix}perspective-origin-x', value, '');
  }

  /** Gets the value of "perspective-origin-y" */
  String get perspectiveOriginY =>
    getPropertyValue('${Device.cssPrefix}perspective-origin-y');

  /** Sets the value of "perspective-origin-y" */
  void set perspectiveOriginY(String value) {
    setProperty('${Device.cssPrefix}perspective-origin-y', value, '');
  }

  /** Gets the value of "pointer-events" */
  String get pointerEvents =>
    getPropertyValue('pointer-events');

  /** Sets the value of "pointer-events" */
  void set pointerEvents(String value) {
    setProperty('pointer-events', value, '');
  }

  /** Gets the value of "position" */
  String get position =>
    getPropertyValue('position');

  /** Sets the value of "position" */
  void set position(String value) {
    setProperty('position', value, '');
  }

  /** Gets the value of "print-color-adjust" */
  String get printColorAdjust =>
    getPropertyValue('${Device.cssPrefix}print-color-adjust');

  /** Sets the value of "print-color-adjust" */
  void set printColorAdjust(String value) {
    setProperty('${Device.cssPrefix}print-color-adjust', value, '');
  }

  /** Gets the value of "quotes" */
  String get quotes =>
    getPropertyValue('quotes');

  /** Sets the value of "quotes" */
  void set quotes(String value) {
    setProperty('quotes', value, '');
  }

  /** Gets the value of "region-break-after" */
  String get regionBreakAfter =>
    getPropertyValue('${Device.cssPrefix}region-break-after');

  /** Sets the value of "region-break-after" */
  void set regionBreakAfter(String value) {
    setProperty('${Device.cssPrefix}region-break-after', value, '');
  }

  /** Gets the value of "region-break-before" */
  String get regionBreakBefore =>
    getPropertyValue('${Device.cssPrefix}region-break-before');

  /** Sets the value of "region-break-before" */
  void set regionBreakBefore(String value) {
    setProperty('${Device.cssPrefix}region-break-before', value, '');
  }

  /** Gets the value of "region-break-inside" */
  String get regionBreakInside =>
    getPropertyValue('${Device.cssPrefix}region-break-inside');

  /** Sets the value of "region-break-inside" */
  void set regionBreakInside(String value) {
    setProperty('${Device.cssPrefix}region-break-inside', value, '');
  }

  /** Gets the value of "region-overflow" */
  String get regionOverflow =>
    getPropertyValue('${Device.cssPrefix}region-overflow');

  /** Sets the value of "region-overflow" */
  void set regionOverflow(String value) {
    setProperty('${Device.cssPrefix}region-overflow', value, '');
  }

  /** Gets the value of "resize" */
  String get resize =>
    getPropertyValue('resize');

  /** Sets the value of "resize" */
  void set resize(String value) {
    setProperty('resize', value, '');
  }

  /** Gets the value of "right" */
  String get right =>
    getPropertyValue('right');

  /** Sets the value of "right" */
  void set right(String value) {
    setProperty('right', value, '');
  }

  /** Gets the value of "rtl-ordering" */
  String get rtlOrdering =>
    getPropertyValue('${Device.cssPrefix}rtl-ordering');

  /** Sets the value of "rtl-ordering" */
  void set rtlOrdering(String value) {
    setProperty('${Device.cssPrefix}rtl-ordering', value, '');
  }

  /** Gets the value of "shape-inside" */
  String get shapeInside =>
    getPropertyValue('${Device.cssPrefix}shape-inside');

  /** Sets the value of "shape-inside" */
  void set shapeInside(String value) {
    setProperty('${Device.cssPrefix}shape-inside', value, '');
  }

  /** Gets the value of "shape-margin" */
  String get shapeMargin =>
    getPropertyValue('${Device.cssPrefix}shape-margin');

  /** Sets the value of "shape-margin" */
  void set shapeMargin(String value) {
    setProperty('${Device.cssPrefix}shape-margin', value, '');
  }

  /** Gets the value of "shape-outside" */
  String get shapeOutside =>
    getPropertyValue('${Device.cssPrefix}shape-outside');

  /** Sets the value of "shape-outside" */
  void set shapeOutside(String value) {
    setProperty('${Device.cssPrefix}shape-outside', value, '');
  }

  /** Gets the value of "shape-padding" */
  String get shapePadding =>
    getPropertyValue('${Device.cssPrefix}shape-padding');

  /** Sets the value of "shape-padding" */
  void set shapePadding(String value) {
    setProperty('${Device.cssPrefix}shape-padding', value, '');
  }

  /** Gets the value of "size" */
  String get size =>
    getPropertyValue('size');

  /** Sets the value of "size" */
  void set size(String value) {
    setProperty('size', value, '');
  }

  /** Gets the value of "speak" */
  String get speak =>
    getPropertyValue('speak');

  /** Sets the value of "speak" */
  void set speak(String value) {
    setProperty('speak', value, '');
  }

  /** Gets the value of "src" */
  String get src =>
    getPropertyValue('src');

  /** Sets the value of "src" */
  void set src(String value) {
    setProperty('src', value, '');
  }

  /** Gets the value of "tab-size" */
  String get tabSize =>
    getPropertyValue('tab-size');

  /** Sets the value of "tab-size" */
  void set tabSize(String value) {
    setProperty('tab-size', value, '');
  }

  /** Gets the value of "table-layout" */
  String get tableLayout =>
    getPropertyValue('table-layout');

  /** Sets the value of "table-layout" */
  void set tableLayout(String value) {
    setProperty('table-layout', value, '');
  }

  /** Gets the value of "tap-highlight-color" */
  String get tapHighlightColor =>
    getPropertyValue('${Device.cssPrefix}tap-highlight-color');

  /** Sets the value of "tap-highlight-color" */
  void set tapHighlightColor(String value) {
    setProperty('${Device.cssPrefix}tap-highlight-color', value, '');
  }

  /** Gets the value of "text-align" */
  String get textAlign =>
    getPropertyValue('text-align');

  /** Sets the value of "text-align" */
  void set textAlign(String value) {
    setProperty('text-align', value, '');
  }

  /** Gets the value of "text-align-last" */
  String get textAlignLast =>
    getPropertyValue('${Device.cssPrefix}text-align-last');

  /** Sets the value of "text-align-last" */
  void set textAlignLast(String value) {
    setProperty('${Device.cssPrefix}text-align-last', value, '');
  }

  /** Gets the value of "text-combine" */
  String get textCombine =>
    getPropertyValue('${Device.cssPrefix}text-combine');

  /** Sets the value of "text-combine" */
  void set textCombine(String value) {
    setProperty('${Device.cssPrefix}text-combine', value, '');
  }

  /** Gets the value of "text-decoration" */
  String get textDecoration =>
    getPropertyValue('text-decoration');

  /** Sets the value of "text-decoration" */
  void set textDecoration(String value) {
    setProperty('text-decoration', value, '');
  }

  /** Gets the value of "text-decoration-line" */
  String get textDecorationLine =>
    getPropertyValue('${Device.cssPrefix}text-decoration-line');

  /** Sets the value of "text-decoration-line" */
  void set textDecorationLine(String value) {
    setProperty('${Device.cssPrefix}text-decoration-line', value, '');
  }

  /** Gets the value of "text-decoration-style" */
  String get textDecorationStyle =>
    getPropertyValue('${Device.cssPrefix}text-decoration-style');

  /** Sets the value of "text-decoration-style" */
  void set textDecorationStyle(String value) {
    setProperty('${Device.cssPrefix}text-decoration-style', value, '');
  }

  /** Gets the value of "text-decorations-in-effect" */
  String get textDecorationsInEffect =>
    getPropertyValue('${Device.cssPrefix}text-decorations-in-effect');

  /** Sets the value of "text-decorations-in-effect" */
  void set textDecorationsInEffect(String value) {
    setProperty('${Device.cssPrefix}text-decorations-in-effect', value, '');
  }

  /** Gets the value of "text-emphasis" */
  String get textEmphasis =>
    getPropertyValue('${Device.cssPrefix}text-emphasis');

  /** Sets the value of "text-emphasis" */
  void set textEmphasis(String value) {
    setProperty('${Device.cssPrefix}text-emphasis', value, '');
  }

  /** Gets the value of "text-emphasis-color" */
  String get textEmphasisColor =>
    getPropertyValue('${Device.cssPrefix}text-emphasis-color');

  /** Sets the value of "text-emphasis-color" */
  void set textEmphasisColor(String value) {
    setProperty('${Device.cssPrefix}text-emphasis-color', value, '');
  }

  /** Gets the value of "text-emphasis-position" */
  String get textEmphasisPosition =>
    getPropertyValue('${Device.cssPrefix}text-emphasis-position');

  /** Sets the value of "text-emphasis-position" */
  void set textEmphasisPosition(String value) {
    setProperty('${Device.cssPrefix}text-emphasis-position', value, '');
  }

  /** Gets the value of "text-emphasis-style" */
  String get textEmphasisStyle =>
    getPropertyValue('${Device.cssPrefix}text-emphasis-style');

  /** Sets the value of "text-emphasis-style" */
  void set textEmphasisStyle(String value) {
    setProperty('${Device.cssPrefix}text-emphasis-style', value, '');
  }

  /** Gets the value of "text-fill-color" */
  String get textFillColor =>
    getPropertyValue('${Device.cssPrefix}text-fill-color');

  /** Sets the value of "text-fill-color" */
  void set textFillColor(String value) {
    setProperty('${Device.cssPrefix}text-fill-color', value, '');
  }

  /** Gets the value of "text-indent" */
  String get textIndent =>
    getPropertyValue('text-indent');

  /** Sets the value of "text-indent" */
  void set textIndent(String value) {
    setProperty('text-indent', value, '');
  }

  /** Gets the value of "text-line-through" */
  String get textLineThrough =>
    getPropertyValue('text-line-through');

  /** Sets the value of "text-line-through" */
  void set textLineThrough(String value) {
    setProperty('text-line-through', value, '');
  }

  /** Gets the value of "text-line-through-color" */
  String get textLineThroughColor =>
    getPropertyValue('text-line-through-color');

  /** Sets the value of "text-line-through-color" */
  void set textLineThroughColor(String value) {
    setProperty('text-line-through-color', value, '');
  }

  /** Gets the value of "text-line-through-mode" */
  String get textLineThroughMode =>
    getPropertyValue('text-line-through-mode');

  /** Sets the value of "text-line-through-mode" */
  void set textLineThroughMode(String value) {
    setProperty('text-line-through-mode', value, '');
  }

  /** Gets the value of "text-line-through-style" */
  String get textLineThroughStyle =>
    getPropertyValue('text-line-through-style');

  /** Sets the value of "text-line-through-style" */
  void set textLineThroughStyle(String value) {
    setProperty('text-line-through-style', value, '');
  }

  /** Gets the value of "text-line-through-width" */
  String get textLineThroughWidth =>
    getPropertyValue('text-line-through-width');

  /** Sets the value of "text-line-through-width" */
  void set textLineThroughWidth(String value) {
    setProperty('text-line-through-width', value, '');
  }

  /** Gets the value of "text-orientation" */
  String get textOrientation =>
    getPropertyValue('${Device.cssPrefix}text-orientation');

  /** Sets the value of "text-orientation" */
  void set textOrientation(String value) {
    setProperty('${Device.cssPrefix}text-orientation', value, '');
  }

  /** Gets the value of "text-overflow" */
  String get textOverflow =>
    getPropertyValue('text-overflow');

  /** Sets the value of "text-overflow" */
  void set textOverflow(String value) {
    setProperty('text-overflow', value, '');
  }

  /** Gets the value of "text-overline" */
  String get textOverline =>
    getPropertyValue('text-overline');

  /** Sets the value of "text-overline" */
  void set textOverline(String value) {
    setProperty('text-overline', value, '');
  }

  /** Gets the value of "text-overline-color" */
  String get textOverlineColor =>
    getPropertyValue('text-overline-color');

  /** Sets the value of "text-overline-color" */
  void set textOverlineColor(String value) {
    setProperty('text-overline-color', value, '');
  }

  /** Gets the value of "text-overline-mode" */
  String get textOverlineMode =>
    getPropertyValue('text-overline-mode');

  /** Sets the value of "text-overline-mode" */
  void set textOverlineMode(String value) {
    setProperty('text-overline-mode', value, '');
  }

  /** Gets the value of "text-overline-style" */
  String get textOverlineStyle =>
    getPropertyValue('text-overline-style');

  /** Sets the value of "text-overline-style" */
  void set textOverlineStyle(String value) {
    setProperty('text-overline-style', value, '');
  }

  /** Gets the value of "text-overline-width" */
  String get textOverlineWidth =>
    getPropertyValue('text-overline-width');

  /** Sets the value of "text-overline-width" */
  void set textOverlineWidth(String value) {
    setProperty('text-overline-width', value, '');
  }

  /** Gets the value of "text-rendering" */
  String get textRendering =>
    getPropertyValue('text-rendering');

  /** Sets the value of "text-rendering" */
  void set textRendering(String value) {
    setProperty('text-rendering', value, '');
  }

  /** Gets the value of "text-security" */
  String get textSecurity =>
    getPropertyValue('${Device.cssPrefix}text-security');

  /** Sets the value of "text-security" */
  void set textSecurity(String value) {
    setProperty('${Device.cssPrefix}text-security', value, '');
  }

  /** Gets the value of "text-shadow" */
  String get textShadow =>
    getPropertyValue('text-shadow');

  /** Sets the value of "text-shadow" */
  void set textShadow(String value) {
    setProperty('text-shadow', value, '');
  }

  /** Gets the value of "text-size-adjust" */
  String get textSizeAdjust =>
    getPropertyValue('${Device.cssPrefix}text-size-adjust');

  /** Sets the value of "text-size-adjust" */
  void set textSizeAdjust(String value) {
    setProperty('${Device.cssPrefix}text-size-adjust', value, '');
  }

  /** Gets the value of "text-stroke" */
  String get textStroke =>
    getPropertyValue('${Device.cssPrefix}text-stroke');

  /** Sets the value of "text-stroke" */
  void set textStroke(String value) {
    setProperty('${Device.cssPrefix}text-stroke', value, '');
  }

  /** Gets the value of "text-stroke-color" */
  String get textStrokeColor =>
    getPropertyValue('${Device.cssPrefix}text-stroke-color');

  /** Sets the value of "text-stroke-color" */
  void set textStrokeColor(String value) {
    setProperty('${Device.cssPrefix}text-stroke-color', value, '');
  }

  /** Gets the value of "text-stroke-width" */
  String get textStrokeWidth =>
    getPropertyValue('${Device.cssPrefix}text-stroke-width');

  /** Sets the value of "text-stroke-width" */
  void set textStrokeWidth(String value) {
    setProperty('${Device.cssPrefix}text-stroke-width', value, '');
  }

  /** Gets the value of "text-transform" */
  String get textTransform =>
    getPropertyValue('text-transform');

  /** Sets the value of "text-transform" */
  void set textTransform(String value) {
    setProperty('text-transform', value, '');
  }

  /** Gets the value of "text-underline" */
  String get textUnderline =>
    getPropertyValue('text-underline');

  /** Sets the value of "text-underline" */
  void set textUnderline(String value) {
    setProperty('text-underline', value, '');
  }

  /** Gets the value of "text-underline-color" */
  String get textUnderlineColor =>
    getPropertyValue('text-underline-color');

  /** Sets the value of "text-underline-color" */
  void set textUnderlineColor(String value) {
    setProperty('text-underline-color', value, '');
  }

  /** Gets the value of "text-underline-mode" */
  String get textUnderlineMode =>
    getPropertyValue('text-underline-mode');

  /** Sets the value of "text-underline-mode" */
  void set textUnderlineMode(String value) {
    setProperty('text-underline-mode', value, '');
  }

  /** Gets the value of "text-underline-style" */
  String get textUnderlineStyle =>
    getPropertyValue('text-underline-style');

  /** Sets the value of "text-underline-style" */
  void set textUnderlineStyle(String value) {
    setProperty('text-underline-style', value, '');
  }

  /** Gets the value of "text-underline-width" */
  String get textUnderlineWidth =>
    getPropertyValue('text-underline-width');

  /** Sets the value of "text-underline-width" */
  void set textUnderlineWidth(String value) {
    setProperty('text-underline-width', value, '');
  }

  /** Gets the value of "top" */
  String get top =>
    getPropertyValue('top');

  /** Sets the value of "top" */
  void set top(String value) {
    setProperty('top', value, '');
  }

  /** Gets the value of "transform" */
  String get transform =>
    getPropertyValue('${Device.cssPrefix}transform');

  /** Sets the value of "transform" */
  void set transform(String value) {
    setProperty('${Device.cssPrefix}transform', value, '');
  }

  /** Gets the value of "transform-origin" */
  String get transformOrigin =>
    getPropertyValue('${Device.cssPrefix}transform-origin');

  /** Sets the value of "transform-origin" */
  void set transformOrigin(String value) {
    setProperty('${Device.cssPrefix}transform-origin', value, '');
  }

  /** Gets the value of "transform-origin-x" */
  String get transformOriginX =>
    getPropertyValue('${Device.cssPrefix}transform-origin-x');

  /** Sets the value of "transform-origin-x" */
  void set transformOriginX(String value) {
    setProperty('${Device.cssPrefix}transform-origin-x', value, '');
  }

  /** Gets the value of "transform-origin-y" */
  String get transformOriginY =>
    getPropertyValue('${Device.cssPrefix}transform-origin-y');

  /** Sets the value of "transform-origin-y" */
  void set transformOriginY(String value) {
    setProperty('${Device.cssPrefix}transform-origin-y', value, '');
  }

  /** Gets the value of "transform-origin-z" */
  String get transformOriginZ =>
    getPropertyValue('${Device.cssPrefix}transform-origin-z');

  /** Sets the value of "transform-origin-z" */
  void set transformOriginZ(String value) {
    setProperty('${Device.cssPrefix}transform-origin-z', value, '');
  }

  /** Gets the value of "transform-style" */
  String get transformStyle =>
    getPropertyValue('${Device.cssPrefix}transform-style');

  /** Sets the value of "transform-style" */
  void set transformStyle(String value) {
    setProperty('${Device.cssPrefix}transform-style', value, '');
  }

  /** Gets the value of "transition" */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  String get transition =>
    getPropertyValue('${Device.cssPrefix}transition');

  /** Sets the value of "transition" */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void set transition(String value) {
    setProperty('${Device.cssPrefix}transition', value, '');
  }

  /** Gets the value of "transition-delay" */
  String get transitionDelay =>
    getPropertyValue('${Device.cssPrefix}transition-delay');

  /** Sets the value of "transition-delay" */
  void set transitionDelay(String value) {
    setProperty('${Device.cssPrefix}transition-delay', value, '');
  }

  /** Gets the value of "transition-duration" */
  String get transitionDuration =>
    getPropertyValue('${Device.cssPrefix}transition-duration');

  /** Sets the value of "transition-duration" */
  void set transitionDuration(String value) {
    setProperty('${Device.cssPrefix}transition-duration', value, '');
  }

  /** Gets the value of "transition-property" */
  String get transitionProperty =>
    getPropertyValue('${Device.cssPrefix}transition-property');

  /** Sets the value of "transition-property" */
  void set transitionProperty(String value) {
    setProperty('${Device.cssPrefix}transition-property', value, '');
  }

  /** Gets the value of "transition-timing-function" */
  String get transitionTimingFunction =>
    getPropertyValue('${Device.cssPrefix}transition-timing-function');

  /** Sets the value of "transition-timing-function" */
  void set transitionTimingFunction(String value) {
    setProperty('${Device.cssPrefix}transition-timing-function', value, '');
  }

  /** Gets the value of "unicode-bidi" */
  String get unicodeBidi =>
    getPropertyValue('unicode-bidi');

  /** Sets the value of "unicode-bidi" */
  void set unicodeBidi(String value) {
    setProperty('unicode-bidi', value, '');
  }

  /** Gets the value of "unicode-range" */
  String get unicodeRange =>
    getPropertyValue('unicode-range');

  /** Sets the value of "unicode-range" */
  void set unicodeRange(String value) {
    setProperty('unicode-range', value, '');
  }

  /** Gets the value of "user-drag" */
  String get userDrag =>
    getPropertyValue('${Device.cssPrefix}user-drag');

  /** Sets the value of "user-drag" */
  void set userDrag(String value) {
    setProperty('${Device.cssPrefix}user-drag', value, '');
  }

  /** Gets the value of "user-modify" */
  String get userModify =>
    getPropertyValue('${Device.cssPrefix}user-modify');

  /** Sets the value of "user-modify" */
  void set userModify(String value) {
    setProperty('${Device.cssPrefix}user-modify', value, '');
  }

  /** Gets the value of "user-select" */
  String get userSelect =>
    getPropertyValue('${Device.cssPrefix}user-select');

  /** Sets the value of "user-select" */
  void set userSelect(String value) {
    setProperty('${Device.cssPrefix}user-select', value, '');
  }

  /** Gets the value of "user-zoom" */
  String get userZoom =>
    getPropertyValue('user-zoom');

  /** Sets the value of "user-zoom" */
  void set userZoom(String value) {
    setProperty('user-zoom', value, '');
  }

  /** Gets the value of "vertical-align" */
  String get verticalAlign =>
    getPropertyValue('vertical-align');

  /** Sets the value of "vertical-align" */
  void set verticalAlign(String value) {
    setProperty('vertical-align', value, '');
  }

  /** Gets the value of "visibility" */
  String get visibility =>
    getPropertyValue('visibility');

  /** Sets the value of "visibility" */
  void set visibility(String value) {
    setProperty('visibility', value, '');
  }

  /** Gets the value of "white-space" */
  String get whiteSpace =>
    getPropertyValue('white-space');

  /** Sets the value of "white-space" */
  void set whiteSpace(String value) {
    setProperty('white-space', value, '');
  }

  /** Gets the value of "widows" */
  String get widows =>
    getPropertyValue('widows');

  /** Sets the value of "widows" */
  void set widows(String value) {
    setProperty('widows', value, '');
  }

  /** Gets the value of "width" */
  String get width =>
    getPropertyValue('width');

  /** Sets the value of "width" */
  void set width(String value) {
    setProperty('width', value, '');
  }

  /** Gets the value of "word-break" */
  String get wordBreak =>
    getPropertyValue('word-break');

  /** Sets the value of "word-break" */
  void set wordBreak(String value) {
    setProperty('word-break', value, '');
  }

  /** Gets the value of "word-spacing" */
  String get wordSpacing =>
    getPropertyValue('word-spacing');

  /** Sets the value of "word-spacing" */
  void set wordSpacing(String value) {
    setProperty('word-spacing', value, '');
  }

  /** Gets the value of "word-wrap" */
  String get wordWrap =>
    getPropertyValue('word-wrap');

  /** Sets the value of "word-wrap" */
  void set wordWrap(String value) {
    setProperty('word-wrap', value, '');
  }

  /** Gets the value of "wrap" */
  String get wrap =>
    getPropertyValue('${Device.cssPrefix}wrap');

  /** Sets the value of "wrap" */
  void set wrap(String value) {
    setProperty('${Device.cssPrefix}wrap', value, '');
  }

  /** Gets the value of "wrap-flow" */
  String get wrapFlow =>
    getPropertyValue('${Device.cssPrefix}wrap-flow');

  /** Sets the value of "wrap-flow" */
  void set wrapFlow(String value) {
    setProperty('${Device.cssPrefix}wrap-flow', value, '');
  }

  /** Gets the value of "wrap-through" */
  String get wrapThrough =>
    getPropertyValue('${Device.cssPrefix}wrap-through');

  /** Sets the value of "wrap-through" */
  void set wrapThrough(String value) {
    setProperty('${Device.cssPrefix}wrap-through', value, '');
  }

  /** Gets the value of "writing-mode" */
  String get writingMode =>
    getPropertyValue('${Device.cssPrefix}writing-mode');

  /** Sets the value of "writing-mode" */
  void set writingMode(String value) {
    setProperty('${Device.cssPrefix}writing-mode', value, '');
  }

  /** Gets the value of "z-index" */
  String get zIndex =>
    getPropertyValue('z-index');

  /** Sets the value of "z-index" */
  void set zIndex(String value) {
    setProperty('z-index', value, '');
  }

  /** Gets the value of "zoom" */
  String get zoom =>
    getPropertyValue('zoom');

  /** Sets the value of "zoom" */
  void set zoom(String value) {
    setProperty('zoom', value, '');
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('CSSStyleRule')
class CssStyleRule extends CssRule native "CSSStyleRule" {
  // To suppress missing implicit constructor warnings.
  factory CssStyleRule._() { throw new UnsupportedError("Not supported"); }

  @DomName('CSSStyleRule.selectorText')
  @DocsEditable()
  String selectorText;

  @DomName('CSSStyleRule.style')
  @DocsEditable()
  final CssStyleDeclaration style;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('CSSStyleSheet')
class CssStyleSheet extends StyleSheet native "CSSStyleSheet" {
  // To suppress missing implicit constructor warnings.
  factory CssStyleSheet._() { throw new UnsupportedError("Not supported"); }

  @DomName('CSSStyleSheet.cssRules')
  @DocsEditable()
  @Returns('_CssRuleList')
  @Creates('_CssRuleList')
  final List<CssRule> cssRules;

  @DomName('CSSStyleSheet.ownerRule')
  @DocsEditable()
  final CssRule ownerRule;

  @DomName('CSSStyleSheet.rules')
  @DocsEditable()
  @Experimental() // non-standard
  @Returns('_CssRuleList')
  @Creates('_CssRuleList')
  final List<CssRule> rules;

  @DomName('CSSStyleSheet.addRule')
  @DocsEditable()
  @Experimental() // non-standard
  int addRule(String selector, String style, [int index]) native;

  @DomName('CSSStyleSheet.deleteRule')
  @DocsEditable()
  void deleteRule(int index) native;

  @DomName('CSSStyleSheet.insertRule')
  @DocsEditable()
  int insertRule(String rule, [int index]) native;

  @DomName('CSSStyleSheet.removeRule')
  @DocsEditable()
  @Experimental() // non-standard
  void removeRule(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('CSSSupportsRule')
class CssSupportsRule extends CssRule native "CSSSupportsRule" {
  // To suppress missing implicit constructor warnings.
  factory CssSupportsRule._() { throw new UnsupportedError("Not supported"); }

  @DomName('CSSSupportsRule.conditionText')
  @DocsEditable()
  final String conditionText;

  @DomName('CSSSupportsRule.cssRules')
  @DocsEditable()
  @Returns('_CssRuleList')
  @Creates('_CssRuleList')
  final List<CssRule> cssRules;

  @DomName('CSSSupportsRule.deleteRule')
  @DocsEditable()
  void deleteRule(int index) native;

  @DomName('CSSSupportsRule.insertRule')
  @DocsEditable()
  int insertRule(String rule, int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('CSSViewportRule')
@Experimental() // untriaged
class CssViewportRule extends CssRule native "CSSViewportRule" {
  // To suppress missing implicit constructor warnings.
  factory CssViewportRule._() { throw new UnsupportedError("Not supported"); }

  @DomName('CSSViewportRule.style')
  @DocsEditable()
  @Experimental() // untriaged
  final CssStyleDeclaration style;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('CustomEvent')
class CustomEvent extends Event native "CustomEvent" {
    @Creates('Null')  // Set from Dart code; does not instantiate a native type.
  var _dartDetail;

  factory CustomEvent(String type,
      {bool canBubble: true, bool cancelable: true, Object detail}) {

    final CustomEvent e = document._createEvent('CustomEvent');

    e._dartDetail = detail;

    // Only try setting the detail if it's one of these types to avoid
    // first-chance exceptions. Can expand this list in the future as needed.
    if (detail is List || detail is Map || detail is String || detail is num) {
      try {
        detail = convertDartToNative_SerializedScriptValue(detail);
        e._initCustomEvent(type, canBubble, cancelable, detail);
      } catch(_) {
        e._initCustomEvent(type, canBubble, cancelable, null);
      }
    } else {
      e._initCustomEvent(type, canBubble, cancelable, null);
    }

    return e;
  }

  @DomName('CustomEvent.detail')
  get detail {
    if (_dartDetail != null) {
      return _dartDetail;
    }
    return _detail;
  }
  // To suppress missing implicit constructor warnings.
  factory CustomEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('CustomEvent._detail')
  @DocsEditable()
  @Experimental() // untriaged
  dynamic get _detail => convertNativeToDart_SerializedScriptValue(this._get__detail);
  @JSName('detail')
  @DomName('CustomEvent._detail')
  @DocsEditable()
  @Experimental() // untriaged
  @Creates('Null')
  final dynamic _get__detail;

  @JSName('initCustomEvent')
  @DomName('CustomEvent.initCustomEvent')
  @DocsEditable()
  void _initCustomEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Object detailArg) native;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLDListElement')
class DListElement extends HtmlElement native "HTMLDListElement" {
  // To suppress missing implicit constructor warnings.
  factory DListElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLDListElement.HTMLDListElement')
  @DocsEditable()
  factory DListElement() => document.createElement("dl");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DListElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLDataListElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
class DataListElement extends HtmlElement native "HTMLDataListElement" {
  // To suppress missing implicit constructor warnings.
  factory DataListElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLDataListElement.HTMLDataListElement')
  @DocsEditable()
  factory DataListElement() => document.createElement("datalist");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DataListElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('datalist');

  @DomName('HTMLDataListElement.options')
  @DocsEditable()
  @Returns('HtmlCollection')
  @Creates('HtmlCollection')
  final List<Node> options;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('Clipboard')
class DataTransfer extends Interceptor native "Clipboard,DataTransfer" {
  // To suppress missing implicit constructor warnings.
  factory DataTransfer._() { throw new UnsupportedError("Not supported"); }

  @DomName('Clipboard.dropEffect')
  @DocsEditable()
  String dropEffect;

  @DomName('Clipboard.effectAllowed')
  @DocsEditable()
  String effectAllowed;

  @DomName('Clipboard.files')
  @DocsEditable()
  @Returns('FileList')
  @Creates('FileList')
  final List<File> files;

  @DomName('Clipboard.items')
  @DocsEditable()
  final DataTransferItemList items;

  @DomName('Clipboard.types')
  @DocsEditable()
  final List<String> types;

  @DomName('Clipboard.clearData')
  @DocsEditable()
  void clearData([String type]) native;

  /**
   * Gets the data for the specified type.
   *
   * The data is only available from within a drop operation (such as an
   * [Element.onDrop] event) and will return null before the event is
   * triggered.
   *
   * Data transfer is prohibited across domains. If a drag originates
   * from content from another domain or protocol (HTTP vs HTTPS) then the
   * data cannot be accessed.
   *
   * The [type] can have values such as:
   *
   * * `'Text'`
   * * `'URL'`
   */
  @DomName('Clipboard.getData')
  @DocsEditable()
  String getData(String type) native;

  @DomName('Clipboard.setData')
  @DocsEditable()
  bool setData(String type, String data) native;

  @DomName('Clipboard.setDragImage')
  @DocsEditable()
  void setDragImage(Element image, int x, int y) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('DataTransferItem')
// http://www.w3.org/TR/2011/WD-html5-20110113/dnd.html#the-datatransferitem-interface
@Experimental()
class DataTransferItem extends Interceptor native "DataTransferItem" {
  // To suppress missing implicit constructor warnings.
  factory DataTransferItem._() { throw new UnsupportedError("Not supported"); }

  @DomName('DataTransferItem.kind')
  @DocsEditable()
  final String kind;

  @DomName('DataTransferItem.type')
  @DocsEditable()
  final String type;

  @DomName('DataTransferItem.getAsFile')
  @DocsEditable()
  Blob getAsFile() native;

  @JSName('getAsString')
  @DomName('DataTransferItem.getAsString')
  @DocsEditable()
  void _getAsString(_StringCallback callback) native;

  @JSName('getAsString')
  @DomName('DataTransferItem.getAsString')
  @DocsEditable()
  Future<String> getAsString() {
    var completer = new Completer<String>();
    _getAsString(
        (value) { completer.complete(value); });
    return completer.future;
  }

  @JSName('webkitGetAsEntry')
  @DomName('DataTransferItem.webkitGetAsEntry')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  Entry getAsEntry() native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('DataTransferItemList')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#the-datatransferitemlist-interface
@Experimental()
class DataTransferItemList extends Interceptor native "DataTransferItemList" {
  // To suppress missing implicit constructor warnings.
  factory DataTransferItemList._() { throw new UnsupportedError("Not supported"); }

  @DomName('DataTransferItemList.length')
  @DocsEditable()
  final int length;

  @DomName('DataTransferItemList.__getter__')
  @DocsEditable()
  @Experimental() // untriaged
  DataTransferItem __getter__(int index) native;

  @DomName('DataTransferItemList.add')
  @DocsEditable()
  DataTransferItem add(data_OR_file, [String type]) native;

  @JSName('add')
  @DomName('DataTransferItemList.add')
  @DocsEditable()
  DataTransferItem addData(String data, String type) native;

  @JSName('add')
  @DomName('DataTransferItemList.add')
  @DocsEditable()
  DataTransferItem addFile(File file) native;

  @DomName('DataTransferItemList.clear')
  @DocsEditable()
  void clear() native;

  @DomName('DataTransferItemList.remove')
  @DocsEditable()
  @Experimental() // untriaged
  void remove(int index) native;


  DataTransferItem operator[] (int index) {
    return JS('DataTransferItem', '#[#]', this, index);
  }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('DatabaseCallback')
// http://www.w3.org/TR/webdatabase/#databasecallback
@Experimental() // deprecated
typedef void DatabaseCallback(database);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('DedicatedWorkerGlobalScope')
@Experimental() // untriaged
class DedicatedWorkerGlobalScope extends WorkerGlobalScope native "DedicatedWorkerGlobalScope" {
  // To suppress missing implicit constructor warnings.
  factory DedicatedWorkerGlobalScope._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [DedicatedWorkerGlobalScope].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('DedicatedWorkerGlobalScope.messageEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');

  @DomName('DedicatedWorkerGlobalScope.postMessage')
  @DocsEditable()
  @Experimental() // untriaged
  void postMessage(Object message, [List<MessagePort> messagePorts]) native;

  /// Stream of `message` events handled by this [DedicatedWorkerGlobalScope].
  @DomName('DedicatedWorkerGlobalScope.onmessage')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('DeprecatedStorageInfo')
@Experimental() // untriaged
class DeprecatedStorageInfo extends Interceptor native "DeprecatedStorageInfo" {
  // To suppress missing implicit constructor warnings.
  factory DeprecatedStorageInfo._() { throw new UnsupportedError("Not supported"); }

  @DomName('DeprecatedStorageInfo.PERSISTENT')
  @DocsEditable()
  @Experimental() // untriaged
  static const int PERSISTENT = 1;

  @DomName('DeprecatedStorageInfo.TEMPORARY')
  @DocsEditable()
  @Experimental() // untriaged
  static const int TEMPORARY = 0;

  @DomName('DeprecatedStorageInfo.queryUsageAndQuota')
  @DocsEditable()
  @Experimental() // untriaged
  void queryUsageAndQuota(int storageType, [StorageUsageCallback usageCallback, StorageErrorCallback errorCallback]) native;

  @DomName('DeprecatedStorageInfo.requestQuota')
  @DocsEditable()
  @Experimental() // untriaged
  void requestQuota(int storageType, int newQuotaInBytes, [StorageQuotaCallback quotaCallback, StorageErrorCallback errorCallback]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('DeprecatedStorageQuota')
@Experimental() // untriaged
class DeprecatedStorageQuota extends Interceptor native "DeprecatedStorageQuota" {
  // To suppress missing implicit constructor warnings.
  factory DeprecatedStorageQuota._() { throw new UnsupportedError("Not supported"); }

  @DomName('DeprecatedStorageQuota.queryUsageAndQuota')
  @DocsEditable()
  @Experimental() // untriaged
  void queryUsageAndQuota(StorageUsageCallback usageCallback, [StorageErrorCallback errorCallback]) native;

  @DomName('DeprecatedStorageQuota.requestQuota')
  @DocsEditable()
  @Experimental() // untriaged
  void requestQuota(int newQuotaInBytes, [StorageQuotaCallback quotaCallback, StorageErrorCallback errorCallback]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLDetailsElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
class DetailsElement extends HtmlElement native "HTMLDetailsElement" {
  // To suppress missing implicit constructor warnings.
  factory DetailsElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLDetailsElement.HTMLDetailsElement')
  @DocsEditable()
  factory DetailsElement() => document.createElement("details");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DetailsElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('details');

  @DomName('HTMLDetailsElement.open')
  @DocsEditable()
  bool open;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('DeviceAcceleration')
// http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
@Experimental()
class DeviceAcceleration extends Interceptor native "DeviceAcceleration" {
  // To suppress missing implicit constructor warnings.
  factory DeviceAcceleration._() { throw new UnsupportedError("Not supported"); }

  @DomName('DeviceAcceleration.x')
  @DocsEditable()
  final double x;

  @DomName('DeviceAcceleration.y')
  @DocsEditable()
  final double y;

  @DomName('DeviceAcceleration.z')
  @DocsEditable()
  final double z;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('DeviceMotionEvent')
// http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
@Experimental()
class DeviceMotionEvent extends Event native "DeviceMotionEvent" {
  // To suppress missing implicit constructor warnings.
  factory DeviceMotionEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('DeviceMotionEvent.acceleration')
  @DocsEditable()
  final DeviceAcceleration acceleration;

  @DomName('DeviceMotionEvent.accelerationIncludingGravity')
  @DocsEditable()
  final DeviceAcceleration accelerationIncludingGravity;

  @DomName('DeviceMotionEvent.interval')
  @DocsEditable()
  final double interval;

  @DomName('DeviceMotionEvent.rotationRate')
  @DocsEditable()
  final DeviceRotationRate rotationRate;

  @DomName('DeviceMotionEvent.initDeviceMotionEvent')
  @DocsEditable()
  @Experimental() // untriaged
  void initDeviceMotionEvent(String type, bool bubbles, bool cancelable, DeviceAcceleration acceleration, DeviceAcceleration accelerationIncludingGravity, DeviceRotationRate rotationRate, num interval) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('DeviceOrientationEvent')
// http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
@Experimental()
class DeviceOrientationEvent extends Event native "DeviceOrientationEvent" {
  factory DeviceOrientationEvent(String type,
      {bool canBubble: true, bool cancelable: true, num alpha: 0, num beta: 0,
      num gamma: 0, bool absolute: false}) {
    var e = document._createEvent("DeviceOrientationEvent");
    e._initDeviceOrientationEvent(type, canBubble, cancelable, alpha, beta,
        gamma, absolute);
    return e;
  }
  // To suppress missing implicit constructor warnings.
  factory DeviceOrientationEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('DeviceOrientationEvent.absolute')
  @DocsEditable()
  final bool absolute;

  @DomName('DeviceOrientationEvent.alpha')
  @DocsEditable()
  final double alpha;

  @DomName('DeviceOrientationEvent.beta')
  @DocsEditable()
  final double beta;

  @DomName('DeviceOrientationEvent.gamma')
  @DocsEditable()
  final double gamma;

  @JSName('initDeviceOrientationEvent')
  @DomName('DeviceOrientationEvent.initDeviceOrientationEvent')
  @DocsEditable()
  void _initDeviceOrientationEvent(String type, bool bubbles, bool cancelable, num alpha, num beta, num gamma, bool absolute) native;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('DeviceRotationRate')
// http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
@Experimental()
class DeviceRotationRate extends Interceptor native "DeviceRotationRate" {
  // To suppress missing implicit constructor warnings.
  factory DeviceRotationRate._() { throw new UnsupportedError("Not supported"); }

  @DomName('DeviceRotationRate.alpha')
  @DocsEditable()
  final double alpha;

  @DomName('DeviceRotationRate.beta')
  @DocsEditable()
  final double beta;

  @DomName('DeviceRotationRate.gamma')
  @DocsEditable()
  final double gamma;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLDialogElement')
@Unstable()
class DialogElement extends HtmlElement native "HTMLDialogElement" {
  // To suppress missing implicit constructor warnings.
  factory DialogElement._() { throw new UnsupportedError("Not supported"); }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DialogElement.created() : super.created();

  @DomName('HTMLDialogElement.open')
  @DocsEditable()
  bool open;

  @DomName('HTMLDialogElement.returnValue')
  @DocsEditable()
  @Experimental() // untriaged
  String returnValue;

  @DomName('HTMLDialogElement.close')
  @DocsEditable()
  void close(String returnValue) native;

  @DomName('HTMLDialogElement.show')
  @DocsEditable()
  void show() native;

  @DomName('HTMLDialogElement.showModal')
  @DocsEditable()
  void showModal() native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('DirectoryEntry')
// http://www.w3.org/TR/file-system-api/#the-directoryentry-interface
@Experimental()
class DirectoryEntry extends Entry native "DirectoryEntry" {

  /**
   * Create a new directory with the specified `path`. If `exclusive` is true,
   * the returned Future will complete with an error if a directory already
   * exists with the specified `path`.
   */
  Future<Entry> createDirectory(String path, {bool exclusive: false}) {
    return _getDirectory(path, options:
        {'create': true, 'exclusive': exclusive});
  }

  /**
   * Retrieve an already existing directory entry. The returned future will
   * result in an error if a directory at `path` does not exist or if the item
   * at `path` is not a directory.
   */
  Future<Entry> getDirectory(String path) {
    return _getDirectory(path);
  }

  /**
   * Create a new file with the specified `path`. If `exclusive` is true,
   * the returned Future will complete with an error if a file already
   * exists at the specified `path`.
   */
  Future<Entry> createFile(String path, {bool exclusive: false}) {
    return _getFile(path, options: {'create': true, 'exclusive': exclusive});
  }

  /**
   * Retrieve an already existing file entry. The returned future will
   * result in an error if a file at `path` does not exist or if the item at
   * `path` is not a file.
   */
  Future<Entry> getFile(String path) {
    return _getFile(path);
  }
  // To suppress missing implicit constructor warnings.
  factory DirectoryEntry._() { throw new UnsupportedError("Not supported"); }

  @DomName('DirectoryEntry.createReader')
  @DocsEditable()
  DirectoryReader createReader() native;

  @DomName('DirectoryEntry.getDirectory')
  @DocsEditable()
  void __getDirectory(String path, {Map options, _EntryCallback successCallback, _ErrorCallback errorCallback}) {
    if (errorCallback != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      __getDirectory_1(path, options_1, successCallback, errorCallback);
      return;
    }
    if (successCallback != null) {
      var options_2 = convertDartToNative_Dictionary(options);
      __getDirectory_2(path, options_2, successCallback);
      return;
    }
    if (options != null) {
      var options_3 = convertDartToNative_Dictionary(options);
      __getDirectory_3(path, options_3);
      return;
    }
    __getDirectory_4(path);
    return;
  }
  @JSName('getDirectory')
  @DomName('DirectoryEntry.getDirectory')
  @DocsEditable()
  void __getDirectory_1(path, options, _EntryCallback successCallback, _ErrorCallback errorCallback) native;
  @JSName('getDirectory')
  @DomName('DirectoryEntry.getDirectory')
  @DocsEditable()
  void __getDirectory_2(path, options, _EntryCallback successCallback) native;
  @JSName('getDirectory')
  @DomName('DirectoryEntry.getDirectory')
  @DocsEditable()
  void __getDirectory_3(path, options) native;
  @JSName('getDirectory')
  @DomName('DirectoryEntry.getDirectory')
  @DocsEditable()
  void __getDirectory_4(path) native;

  @JSName('getDirectory')
  @DomName('DirectoryEntry.getDirectory')
  @DocsEditable()
  Future<Entry> _getDirectory(String path, {Map options}) {
    var completer = new Completer<Entry>();
    __getDirectory(path, options : options,
        successCallback : (value) { completer.complete(value); },
        errorCallback : (error) { completer.completeError(error); });
    return completer.future;
  }

  @DomName('DirectoryEntry.getFile')
  @DocsEditable()
  void __getFile(String path, {Map options, _EntryCallback successCallback, _ErrorCallback errorCallback}) {
    if (errorCallback != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      __getFile_1(path, options_1, successCallback, errorCallback);
      return;
    }
    if (successCallback != null) {
      var options_2 = convertDartToNative_Dictionary(options);
      __getFile_2(path, options_2, successCallback);
      return;
    }
    if (options != null) {
      var options_3 = convertDartToNative_Dictionary(options);
      __getFile_3(path, options_3);
      return;
    }
    __getFile_4(path);
    return;
  }
  @JSName('getFile')
  @DomName('DirectoryEntry.getFile')
  @DocsEditable()
  void __getFile_1(path, options, _EntryCallback successCallback, _ErrorCallback errorCallback) native;
  @JSName('getFile')
  @DomName('DirectoryEntry.getFile')
  @DocsEditable()
  void __getFile_2(path, options, _EntryCallback successCallback) native;
  @JSName('getFile')
  @DomName('DirectoryEntry.getFile')
  @DocsEditable()
  void __getFile_3(path, options) native;
  @JSName('getFile')
  @DomName('DirectoryEntry.getFile')
  @DocsEditable()
  void __getFile_4(path) native;

  @JSName('getFile')
  @DomName('DirectoryEntry.getFile')
  @DocsEditable()
  Future<Entry> _getFile(String path, {Map options}) {
    var completer = new Completer<Entry>();
    __getFile(path, options : options,
        successCallback : (value) { completer.complete(value); },
        errorCallback : (error) { completer.completeError(error); });
    return completer.future;
  }

  @JSName('removeRecursively')
  @DomName('DirectoryEntry.removeRecursively')
  @DocsEditable()
  void _removeRecursively(VoidCallback successCallback, [_ErrorCallback errorCallback]) native;

  @JSName('removeRecursively')
  @DomName('DirectoryEntry.removeRecursively')
  @DocsEditable()
  Future removeRecursively() {
    var completer = new Completer();
    _removeRecursively(
        () { completer.complete(); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('DirectoryReader')
// http://www.w3.org/TR/file-system-api/#the-directoryreader-interface
@Experimental()
class DirectoryReader extends Interceptor native "DirectoryReader" {
  // To suppress missing implicit constructor warnings.
  factory DirectoryReader._() { throw new UnsupportedError("Not supported"); }

  @JSName('readEntries')
  @DomName('DirectoryReader.readEntries')
  @DocsEditable()
  void _readEntries(_EntriesCallback successCallback, [_ErrorCallback errorCallback]) native;

  @JSName('readEntries')
  @DomName('DirectoryReader.readEntries')
  @DocsEditable()
  Future<List<Entry>> readEntries() {
    var completer = new Completer<List<Entry>>();
    _readEntries(
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); });
    return completer.future;
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
/**
 * A generic container for content on an HTML page;
 * corresponds to the &lt;div&gt; tag.
 *
 * The [DivElement] is a generic container and does not have any semantic
 * significance. It is functionally similar to [SpanElement].
 *
 * The [DivElement] is a block-level element, as opposed to [SpanElement],
 * which is an inline-level element.
 *
 * Example usage:
 *
 *     DivElement div = new DivElement();
 *     div.text = 'Here's my new DivElem
 *     document.body.elements.add(elem);
 *
 * See also:
 *
 * * [HTML <div> element](http://www.w3.org/TR/html-markup/div.html) from W3C.
 * * [Block-level element](http://www.w3.org/TR/CSS2/visuren.html#block-boxes) from W3C.
 * * [Inline-level element](http://www.w3.org/TR/CSS2/visuren.html#inline-boxes) from W3C.
 */
@DomName('HTMLDivElement')
class DivElement extends HtmlElement native "HTMLDivElement" {
  // To suppress missing implicit constructor warnings.
  factory DivElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLDivElement.HTMLDivElement')
  @DocsEditable()
  factory DivElement() => document.createElement("div");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DivElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
/**
 * The base class for all documents.
 *
 * Each web page loaded in the browser has its own [Document] object, which is
 * typically an [HtmlDocument].
 *
 * If you aren't comfortable with DOM concepts, see the Dart tutorial
 * [Target 2: Connect Dart & HTML](http://www.dartlang.org/docs/tutorials/connect-dart-html/).
 */
@DomName('Document')
class Document extends Node  native "Document"
{

  // To suppress missing implicit constructor warnings.
  factory Document._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `readystatechange` events to event
   * handlers that are not necessarily instances of [Document].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Document.readystatechangeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> readyStateChangeEvent = const EventStreamProvider<Event>('readystatechange');

  /**
   * Static factory designed to expose `securitypolicyviolation` events to event
   * handlers that are not necessarily instances of [Document].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Document.securitypolicyviolationEvent')
  @DocsEditable()
  // https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#widl-Document-onsecuritypolicyviolation
  @Experimental()
  static const EventStreamProvider<SecurityPolicyViolationEvent> securityPolicyViolationEvent = const EventStreamProvider<SecurityPolicyViolationEvent>('securitypolicyviolation');

  /**
   * Static factory designed to expose `selectionchange` events to event
   * handlers that are not necessarily instances of [Document].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Document.selectionchangeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> selectionChangeEvent = const EventStreamProvider<Event>('selectionchange');

  /**
   * Static factory designed to expose `pointerlockchange` events to event
   * handlers that are not necessarily instances of [Document].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Document.webkitpointerlockchangeEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html#widl-Document-onpointerlockchange
  static const EventStreamProvider<Event> pointerLockChangeEvent = const EventStreamProvider<Event>('webkitpointerlockchange');

  /**
   * Static factory designed to expose `pointerlockerror` events to event
   * handlers that are not necessarily instances of [Document].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Document.webkitpointerlockerrorEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html#widl-Document-onpointerlockerror
  static const EventStreamProvider<Event> pointerLockErrorEvent = const EventStreamProvider<Event>('webkitpointerlockerror');

  @DomName('Document.activeElement')
  @DocsEditable()
  @Experimental() // untriaged
  final Element activeElement;

  @JSName('body')
  @DomName('Document.body')
  @DocsEditable()
  HtmlElement _body;

  @DomName('Document.cookie')
  @DocsEditable()
  String cookie;

  @DomName('Document.currentScript')
  @DocsEditable()
  @Experimental() // untriaged
  final ScriptElement currentScript;

  @DomName('Document.window')
  @DocsEditable()
  @Experimental() // untriaged
  WindowBase get window => _convertNativeToDart_Window(this._get_window);
  @JSName('defaultView')
  @DomName('Document.window')
  @DocsEditable()
  @Experimental() // untriaged
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  @Creates('Window|=Object|Null')
  @Returns('Window|=Object|Null')
  final dynamic _get_window;

  @DomName('Document.documentElement')
  @DocsEditable()
  final Element documentElement;

  @DomName('Document.domain')
  @DocsEditable()
  final String domain;

  @DomName('Document.fonts')
  @DocsEditable()
  @Experimental() // untriaged
  final FontFaceSet fonts;

  @JSName('head')
  @DomName('Document.head')
  @DocsEditable()
  final HeadElement _head;

  @DomName('Document.hidden')
  @DocsEditable()
  @Experimental() // untriaged
  final bool hidden;

  @DomName('Document.implementation')
  @DocsEditable()
  final DomImplementation implementation;

  @JSName('lastModified')
  @DomName('Document.lastModified')
  @DocsEditable()
  final String _lastModified;

  @JSName('preferredStylesheetSet')
  @DomName('Document.preferredStylesheetSet')
  @DocsEditable()
  final String _preferredStylesheetSet;

  @DomName('Document.readyState')
  @DocsEditable()
  final String readyState;

  @JSName('referrer')
  @DomName('Document.referrer')
  @DocsEditable()
  final String _referrer;

  @DomName('Document.rootElement')
  @DocsEditable()
  @Experimental() // untriaged
  final SvgSvgElement rootElement;

  @JSName('selectedStylesheetSet')
  @DomName('Document.selectedStylesheetSet')
  @DocsEditable()
  String _selectedStylesheetSet;

  @JSName('styleSheets')
  @DomName('Document.styleSheets')
  @DocsEditable()
  @Returns('_StyleSheetList')
  @Creates('_StyleSheetList')
  final List<StyleSheet> _styleSheets;

  @DomName('Document.timeline')
  @DocsEditable()
  @Experimental() // untriaged
  final Timeline timeline;

  @JSName('title')
  @DomName('Document.title')
  @DocsEditable()
  String _title;

  @DomName('Document.visibilityState')
  @DocsEditable()
  @Experimental() // untriaged
  final String visibilityState;

  @JSName('webkitFullscreenElement')
  @DomName('Document.webkitFullscreenElement')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#dom-document-fullscreenelement
  final Element _webkitFullscreenElement;

  @JSName('webkitFullscreenEnabled')
  @DomName('Document.webkitFullscreenEnabled')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#dom-document-fullscreenenabled
  final bool _webkitFullscreenEnabled;

  @JSName('webkitHidden')
  @DomName('Document.webkitHidden')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/PageVisibility/Overview.html#document
  final bool _webkitHidden;

  @JSName('webkitPointerLockElement')
  @DomName('Document.webkitPointerLockElement')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html#widl-Document-pointerLockElement
  final Element _webkitPointerLockElement;

  @JSName('webkitVisibilityState')
  @DomName('Document.webkitVisibilityState')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/PageVisibility/Overview.html#dom-document-visibilitystate
  final String _webkitVisibilityState;

  @DomName('Document.adoptNode')
  @DocsEditable()
  Node adoptNode(Node node) native;

  @JSName('caretRangeFromPoint')
  @DomName('Document.caretRangeFromPoint')
  @DocsEditable()
  // http://www.w3.org/TR/2009/WD-cssom-view-20090804/#dom-documentview-caretrangefrompoint
  @Experimental()
  Range _caretRangeFromPoint(int x, int y) native;

  @DomName('Document.createDocumentFragment')
  @DocsEditable()
  DocumentFragment createDocumentFragment() native;

  @JSName('createElement')
  @DomName('Document.createElement')
  @DocsEditable()
  Element _createElement(String localName_OR_tagName, [String typeExtension]) native;

  @DomName('Document.createElementNS')
  @DocsEditable()
  Element createElementNS(String namespaceURI, String qualifiedName, [String typeExtension]) native;

  @JSName('createEvent')
  @DomName('Document.createEvent')
  @DocsEditable()
  Event _createEvent([String eventType]) native;

  @DomName('Document.createRange')
  @DocsEditable()
  Range createRange() native;

  @JSName('createTextNode')
  @DomName('Document.createTextNode')
  @DocsEditable()
  Text _createTextNode(String data) native;

  @DomName('Document.createTouch')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Touch _createTouch(Window window, EventTarget target, int identifier, int pageX, int pageY, int screenX, int screenY, int webkitRadiusX, int webkitRadiusY, num webkitRotationAngle, num webkitForce) {
    var target_1 = _convertDartToNative_EventTarget(target);
    return _createTouch_1(window, target_1, identifier, pageX, pageY, screenX, screenY, webkitRadiusX, webkitRadiusY, webkitRotationAngle, webkitForce);
  }
  @JSName('createTouch')
  @DomName('Document.createTouch')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Touch _createTouch_1(Window window, target, identifier, pageX, pageY, screenX, screenY, webkitRadiusX, webkitRadiusY, webkitRotationAngle, webkitForce) native;

  @JSName('elementFromPoint')
  @DomName('Document.elementFromPoint')
  @DocsEditable()
  Element _elementFromPoint(int x, int y) native;

  @DomName('Document.execCommand')
  @DocsEditable()
  bool execCommand(String command, bool userInterface, String value) native;

  @JSName('getCSSCanvasContext')
  @DomName('Document.getCSSCanvasContext')
  @DocsEditable()
  // https://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariCSSRef/Articles/Functions.html
  @Experimental() // non-standard
  CanvasRenderingContext _getCssCanvasContext(String contextId, String name, int width, int height) native;

  @DomName('Document.getElementById')
  @DocsEditable()
  Element getElementById(String elementId) native;

  @DomName('Document.getElementsByClassName')
  @DocsEditable()
  @Creates('NodeList|HtmlCollection')
  @Returns('NodeList|HtmlCollection')
  List<Node> getElementsByClassName(String classNames) native;

  @DomName('Document.getElementsByName')
  @DocsEditable()
  @Returns('NodeList')
  @Creates('NodeList')
  List<Node> getElementsByName(String elementName) native;

  @DomName('Document.getElementsByTagName')
  @DocsEditable()
  @Creates('NodeList|HtmlCollection')
  @Returns('NodeList|HtmlCollection')
  List<Node> getElementsByTagName(String localName) native;

  @DomName('Document.importNode')
  @DocsEditable()
  Node importNode(Node node, [bool deep]) native;

  @DomName('Document.queryCommandEnabled')
  @DocsEditable()
  bool queryCommandEnabled(String command) native;

  @DomName('Document.queryCommandIndeterm')
  @DocsEditable()
  bool queryCommandIndeterm(String command) native;

  @DomName('Document.queryCommandState')
  @DocsEditable()
  bool queryCommandState(String command) native;

  @DomName('Document.queryCommandSupported')
  @DocsEditable()
  bool queryCommandSupported(String command) native;

  @DomName('Document.queryCommandValue')
  @DocsEditable()
  String queryCommandValue(String command) native;

  /**
   * Finds the first descendant element of this document that matches the
   * specified group of selectors.
   *
   * Unless your webpage contains multiple documents, the top-level
   * [querySelector]
   * method behaves the same as this method, so you should use it instead to
   * save typing a few characters.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var element1 = document.querySelector('.className');
   *     var element2 = document.querySelector('#id');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  @DomName('Document.querySelector')
  @DocsEditable()
  Element querySelector(String selectors) native;

  @JSName('querySelectorAll')
  @DomName('Document.querySelectorAll')
  @DocsEditable()
  @Returns('NodeList')
  @Creates('NodeList')
  List<Node> _querySelectorAll(String selectors) native;

  @JSName('webkitExitFullscreen')
  @DomName('Document.webkitExitFullscreen')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#dom-document-exitfullscreen
  void _webkitExitFullscreen() native;

  @JSName('webkitExitPointerLock')
  @DomName('Document.webkitExitPointerLock')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html#widl-Document-exitPointerLock-void
  void _webkitExitPointerLock() native;

  // From ParentNode

  @JSName('childElementCount')
  @DomName('Document.childElementCount')
  @DocsEditable()
  final int _childElementCount;

  @JSName('children')
  @DomName('Document.children')
  @DocsEditable()
  @Returns('HtmlCollection')
  @Creates('HtmlCollection')
  final List<Node> _children;

  @JSName('firstElementChild')
  @DomName('Document.firstElementChild')
  @DocsEditable()
  final Element _firstElementChild;

  @JSName('lastElementChild')
  @DomName('Document.lastElementChild')
  @DocsEditable()
  final Element _lastElementChild;

  /// Stream of `abort` events handled by this [Document].
  @DomName('Document.onabort')
  @DocsEditable()
  Stream<Event> get onAbort => Element.abortEvent.forTarget(this);

  /// Stream of `beforecopy` events handled by this [Document].
  @DomName('Document.onbeforecopy')
  @DocsEditable()
  Stream<Event> get onBeforeCopy => Element.beforeCopyEvent.forTarget(this);

  /// Stream of `beforecut` events handled by this [Document].
  @DomName('Document.onbeforecut')
  @DocsEditable()
  Stream<Event> get onBeforeCut => Element.beforeCutEvent.forTarget(this);

  /// Stream of `beforepaste` events handled by this [Document].
  @DomName('Document.onbeforepaste')
  @DocsEditable()
  Stream<Event> get onBeforePaste => Element.beforePasteEvent.forTarget(this);

  /// Stream of `blur` events handled by this [Document].
  @DomName('Document.onblur')
  @DocsEditable()
  Stream<Event> get onBlur => Element.blurEvent.forTarget(this);

  /// Stream of `change` events handled by this [Document].
  @DomName('Document.onchange')
  @DocsEditable()
  Stream<Event> get onChange => Element.changeEvent.forTarget(this);

  /// Stream of `click` events handled by this [Document].
  @DomName('Document.onclick')
  @DocsEditable()
  Stream<MouseEvent> get onClick => Element.clickEvent.forTarget(this);

  /// Stream of `contextmenu` events handled by this [Document].
  @DomName('Document.oncontextmenu')
  @DocsEditable()
  Stream<MouseEvent> get onContextMenu => Element.contextMenuEvent.forTarget(this);

  /// Stream of `copy` events handled by this [Document].
  @DomName('Document.oncopy')
  @DocsEditable()
  Stream<Event> get onCopy => Element.copyEvent.forTarget(this);

  /// Stream of `cut` events handled by this [Document].
  @DomName('Document.oncut')
  @DocsEditable()
  Stream<Event> get onCut => Element.cutEvent.forTarget(this);

  /// Stream of `doubleclick` events handled by this [Document].
  @DomName('Document.ondblclick')
  @DocsEditable()
  Stream<Event> get onDoubleClick => Element.doubleClickEvent.forTarget(this);

  /// Stream of `drag` events handled by this [Document].
  @DomName('Document.ondrag')
  @DocsEditable()
  Stream<MouseEvent> get onDrag => Element.dragEvent.forTarget(this);

  /// Stream of `dragend` events handled by this [Document].
  @DomName('Document.ondragend')
  @DocsEditable()
  Stream<MouseEvent> get onDragEnd => Element.dragEndEvent.forTarget(this);

  /// Stream of `dragenter` events handled by this [Document].
  @DomName('Document.ondragenter')
  @DocsEditable()
  Stream<MouseEvent> get onDragEnter => Element.dragEnterEvent.forTarget(this);

  /// Stream of `dragleave` events handled by this [Document].
  @DomName('Document.ondragleave')
  @DocsEditable()
  Stream<MouseEvent> get onDragLeave => Element.dragLeaveEvent.forTarget(this);

  /// Stream of `dragover` events handled by this [Document].
  @DomName('Document.ondragover')
  @DocsEditable()
  Stream<MouseEvent> get onDragOver => Element.dragOverEvent.forTarget(this);

  /// Stream of `dragstart` events handled by this [Document].
  @DomName('Document.ondragstart')
  @DocsEditable()
  Stream<MouseEvent> get onDragStart => Element.dragStartEvent.forTarget(this);

  /// Stream of `drop` events handled by this [Document].
  @DomName('Document.ondrop')
  @DocsEditable()
  Stream<MouseEvent> get onDrop => Element.dropEvent.forTarget(this);

  /// Stream of `error` events handled by this [Document].
  @DomName('Document.onerror')
  @DocsEditable()
  Stream<Event> get onError => Element.errorEvent.forTarget(this);

  /// Stream of `focus` events handled by this [Document].
  @DomName('Document.onfocus')
  @DocsEditable()
  Stream<Event> get onFocus => Element.focusEvent.forTarget(this);

  /// Stream of `input` events handled by this [Document].
  @DomName('Document.oninput')
  @DocsEditable()
  Stream<Event> get onInput => Element.inputEvent.forTarget(this);

  /// Stream of `invalid` events handled by this [Document].
  @DomName('Document.oninvalid')
  @DocsEditable()
  Stream<Event> get onInvalid => Element.invalidEvent.forTarget(this);

  /// Stream of `keydown` events handled by this [Document].
  @DomName('Document.onkeydown')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyDown => Element.keyDownEvent.forTarget(this);

  /// Stream of `keypress` events handled by this [Document].
  @DomName('Document.onkeypress')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyPress => Element.keyPressEvent.forTarget(this);

  /// Stream of `keyup` events handled by this [Document].
  @DomName('Document.onkeyup')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyUp => Element.keyUpEvent.forTarget(this);

  /// Stream of `load` events handled by this [Document].
  @DomName('Document.onload')
  @DocsEditable()
  Stream<Event> get onLoad => Element.loadEvent.forTarget(this);

  /// Stream of `mousedown` events handled by this [Document].
  @DomName('Document.onmousedown')
  @DocsEditable()
  Stream<MouseEvent> get onMouseDown => Element.mouseDownEvent.forTarget(this);

  /// Stream of `mouseenter` events handled by this [Document].
  @DomName('Document.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseEnter => Element.mouseEnterEvent.forTarget(this);

  /// Stream of `mouseleave` events handled by this [Document].
  @DomName('Document.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseLeave => Element.mouseLeaveEvent.forTarget(this);

  /// Stream of `mousemove` events handled by this [Document].
  @DomName('Document.onmousemove')
  @DocsEditable()
  Stream<MouseEvent> get onMouseMove => Element.mouseMoveEvent.forTarget(this);

  /// Stream of `mouseout` events handled by this [Document].
  @DomName('Document.onmouseout')
  @DocsEditable()
  Stream<MouseEvent> get onMouseOut => Element.mouseOutEvent.forTarget(this);

  /// Stream of `mouseover` events handled by this [Document].
  @DomName('Document.onmouseover')
  @DocsEditable()
  Stream<MouseEvent> get onMouseOver => Element.mouseOverEvent.forTarget(this);

  /// Stream of `mouseup` events handled by this [Document].
  @DomName('Document.onmouseup')
  @DocsEditable()
  Stream<MouseEvent> get onMouseUp => Element.mouseUpEvent.forTarget(this);

  /// Stream of `mousewheel` events handled by this [Document].
  @DomName('Document.onmousewheel')
  @DocsEditable()
  Stream<WheelEvent> get onMouseWheel => Element.mouseWheelEvent.forTarget(this);

  /// Stream of `paste` events handled by this [Document].
  @DomName('Document.onpaste')
  @DocsEditable()
  Stream<Event> get onPaste => Element.pasteEvent.forTarget(this);

  /// Stream of `readystatechange` events handled by this [Document].
  @DomName('Document.onreadystatechange')
  @DocsEditable()
  Stream<Event> get onReadyStateChange => readyStateChangeEvent.forTarget(this);

  /// Stream of `reset` events handled by this [Document].
  @DomName('Document.onreset')
  @DocsEditable()
  Stream<Event> get onReset => Element.resetEvent.forTarget(this);

  @DomName('Document.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onResize => Element.resizeEvent.forTarget(this);

  /// Stream of `scroll` events handled by this [Document].
  @DomName('Document.onscroll')
  @DocsEditable()
  Stream<Event> get onScroll => Element.scrollEvent.forTarget(this);

  /// Stream of `search` events handled by this [Document].
  @DomName('Document.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  Stream<Event> get onSearch => Element.searchEvent.forTarget(this);

  /// Stream of `securitypolicyviolation` events handled by this [Document].
  @DomName('Document.onsecuritypolicyviolation')
  @DocsEditable()
  // https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#widl-Document-onsecuritypolicyviolation
  @Experimental()
  Stream<SecurityPolicyViolationEvent> get onSecurityPolicyViolation => securityPolicyViolationEvent.forTarget(this);

  /// Stream of `select` events handled by this [Document].
  @DomName('Document.onselect')
  @DocsEditable()
  Stream<Event> get onSelect => Element.selectEvent.forTarget(this);

  /// Stream of `selectionchange` events handled by this [Document].
  @DomName('Document.onselectionchange')
  @DocsEditable()
  Stream<Event> get onSelectionChange => selectionChangeEvent.forTarget(this);

  /// Stream of `selectstart` events handled by this [Document].
  @DomName('Document.onselectstart')
  @DocsEditable()
  Stream<Event> get onSelectStart => Element.selectStartEvent.forTarget(this);

  /// Stream of `submit` events handled by this [Document].
  @DomName('Document.onsubmit')
  @DocsEditable()
  Stream<Event> get onSubmit => Element.submitEvent.forTarget(this);

  /// Stream of `touchcancel` events handled by this [Document].
  @DomName('Document.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchCancel => Element.touchCancelEvent.forTarget(this);

  /// Stream of `touchend` events handled by this [Document].
  @DomName('Document.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchEnd => Element.touchEndEvent.forTarget(this);

  /// Stream of `touchmove` events handled by this [Document].
  @DomName('Document.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchMove => Element.touchMoveEvent.forTarget(this);

  /// Stream of `touchstart` events handled by this [Document].
  @DomName('Document.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchStart => Element.touchStartEvent.forTarget(this);

  /// Stream of `fullscreenchange` events handled by this [Document].
  @DomName('Document.onwebkitfullscreenchange')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  Stream<Event> get onFullscreenChange => Element.fullscreenChangeEvent.forTarget(this);

  /// Stream of `fullscreenerror` events handled by this [Document].
  @DomName('Document.onwebkitfullscreenerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  Stream<Event> get onFullscreenError => Element.fullscreenErrorEvent.forTarget(this);

  /// Stream of `pointerlockchange` events handled by this [Document].
  @DomName('Document.onwebkitpointerlockchange')
  @DocsEditable()
  // https://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html#widl-Document-onpointerlockchange
  @Experimental()
  Stream<Event> get onPointerLockChange => pointerLockChangeEvent.forTarget(this);

  /// Stream of `pointerlockerror` events handled by this [Document].
  @DomName('Document.onwebkitpointerlockerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html#widl-Document-onpointerlockerror
  @Experimental()
  Stream<Event> get onPointerLockError => pointerLockErrorEvent.forTarget(this);

  /**
   * Finds all descendant elements of this document that match the specified
   * group of selectors.
   *
   * Unless your webpage contains multiple documents, the top-level
   * [querySelectorAll]
   * method behaves the same as this method, so you should use it instead to
   * save typing a few characters.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var items = document.querySelectorAll('.itemClassName');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  ElementList querySelectorAll(String selectors) {
    return new _FrozenElementList._wrap(_querySelectorAll(selectors));
  }

  /**
   * Alias for [querySelector]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @Experimental()
  @DomName('Document.querySelector')
  Element query(String relativeSelectors) => querySelector(relativeSelectors);

  /**
   * Alias for [querySelectorAll]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @Experimental()
  @DomName('Document.querySelectorAll')
  ElementList queryAll(String relativeSelectors) =>
      querySelectorAll(relativeSelectors);

  /// Checks if [registerElement] is supported on the current platform.
  bool get supportsRegisterElement {
    return JS('bool', '("registerElement" in #)', this);
  }

  /// *Deprecated*: use [supportsRegisterElement] instead.
  @deprecated
  bool get supportsRegister => supportsRegisterElement;

  @DomName('Document.createElement')
  Element createElement(String tagName, [String typeExtension]) {
    return _createElement(tagName, typeExtension);
  }

  @DomName('Document.createNodeIterator')
  NodeIterator _createNodeIterator(Node root,
      [int whatToShow, NodeFilter filter])
      => JS('NodeIterator', '#.createNodeIterator(#, #, #, false)',
          this, root, whatToShow, filter);

  @DomName('Document.createTreeWalker')
  TreeWalker _createTreeWalker(Node root,
      [int whatToShow, NodeFilter filter])
      => JS('TreeWalker', '#.createTreeWalker(#, #, #, false)',
          this, root, whatToShow, filter);
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('DocumentFragment')
class DocumentFragment extends Node implements ParentNode native "DocumentFragment" {
  factory DocumentFragment() => document.createDocumentFragment();

  factory DocumentFragment.html(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {

    return document.body.createFragment(html,
      validator: validator, treeSanitizer: treeSanitizer);
  }

  factory DocumentFragment.svg(String svgContent,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {

    return new svg.SvgSvgElement().createFragment(svgContent,
        validator: validator, treeSanitizer: treeSanitizer);
  }

  HtmlCollection get _children => throw new UnimplementedError(
      'Use _docChildren instead');

  // Native field is used only by Dart code so does not lead to instantiation
  // of native classes
  @Creates('Null')
  List<Element> _docChildren;

  List<Element> get children {
    if (_docChildren == null) {
      _docChildren = new FilteredElementList(this);
    }
    return _docChildren;
  }

  void set children(List<Element> value) {
    // Copy list first since we don't want liveness during iteration.
    List copy = new List.from(value);
    var children = this.children;
    children.clear();
    children.addAll(copy);
  }

  /**
   * Finds all descendant elements of this document fragment that match the
   * specified group of selectors.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var items = document.querySelectorAll('.itemClassName');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  ElementList querySelectorAll(String selectors) =>
    new _FrozenElementList._wrap(_querySelectorAll(selectors));



  String get innerHtml {
    final e = new Element.tag("div");
    e.append(this.clone(true));
    return e.innerHtml;
  }

  void set innerHtml(String value) {
    this.setInnerHtml(value);
  }

  void setInnerHtml(String html,
    {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {

    this.nodes.clear();
    append(document.body.createFragment(
        html, validator: validator, treeSanitizer: treeSanitizer));
  }

  /**
   * Adds the specified text as a text node after the last child of this
   * document fragment.
   */
  void appendText(String text) {
    this.append(new Text(text));
  }


  /**
   * Parses the specified text as HTML and adds the resulting node after the
   * last child of this document fragment.
   */
  void appendHtml(String text) {
    this.append(new DocumentFragment.html(text));
  }

  /** 
   * Alias for [querySelector]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @Experimental()
  @DomName('DocumentFragment.querySelector')
  Element query(String relativeSelectors) {
    return querySelector(relativeSelectors);
  }

  /** 
   * Alias for [querySelectorAll]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @Experimental()
  @DomName('DocumentFragment.querySelectorAll')
  ElementList queryAll(String relativeSelectors) {
    return querySelectorAll(relativeSelectors);
  }
  // To suppress missing implicit constructor warnings.
  factory DocumentFragment._() { throw new UnsupportedError("Not supported"); }

  /**
   * Finds the first descendant element of this document fragment that matches
   * the specified group of selectors.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var element1 = fragment.querySelector('.className');
   *     var element2 = fragment.querySelector('#id');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  @DomName('DocumentFragment.querySelector')
  @DocsEditable()
  Element querySelector(String selectors) native;

  @JSName('querySelectorAll')
  @DomName('DocumentFragment.querySelectorAll')
  @DocsEditable()
  @Returns('NodeList')
  @Creates('NodeList')
  List<Node> _querySelectorAll(String selectors) native;

  // From ParentNode

  @JSName('childElementCount')
  @DomName('DocumentFragment.childElementCount')
  @DocsEditable()
  final int _childElementCount;

  @JSName('firstElementChild')
  @DomName('DocumentFragment.firstElementChild')
  @DocsEditable()
  final Element _firstElementChild;

  @JSName('lastElementChild')
  @DomName('DocumentFragment.lastElementChild')
  @DocsEditable()
  final Element _lastElementChild;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('DOMError')
class DomError extends Interceptor native "DOMError" {
  // To suppress missing implicit constructor warnings.
  factory DomError._() { throw new UnsupportedError("Not supported"); }

  @DomName('DOMError.message')
  @DocsEditable()
  @Experimental() // untriaged
  final String message;

  @DomName('DOMError.name')
  @DocsEditable()
  final String name;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('DOMException')
@Unstable()
class DomException extends Interceptor native "DOMException" {

  static const String INDEX_SIZE = 'IndexSizeError';
  static const String HIERARCHY_REQUEST = 'HierarchyRequestError';
  static const String WRONG_DOCUMENT = 'WrongDocumentError';
  static const String INVALID_CHARACTER = 'InvalidCharacterError';
  static const String NO_MODIFICATION_ALLOWED = 'NoModificationAllowedError';
  static const String NOT_FOUND = 'NotFoundError';
  static const String NOT_SUPPORTED = 'NotSupportedError';
  static const String INVALID_STATE = 'InvalidStateError';
  static const String SYNTAX = 'SyntaxError';
  static const String INVALID_MODIFICATION = 'InvalidModificationError';
  static const String NAMESPACE = 'NamespaceError';
  static const String INVALID_ACCESS = 'InvalidAccessError';
  static const String TYPE_MISMATCH = 'TypeMismatchError';
  static const String SECURITY = 'SecurityError';
  static const String NETWORK = 'NetworkError';
  static const String ABORT = 'AbortError';
  static const String URL_MISMATCH = 'URLMismatchError';
  static const String QUOTA_EXCEEDED = 'QuotaExceededError';
  static const String TIMEOUT = 'TimeoutError';
  static const String INVALID_NODE_TYPE = 'InvalidNodeTypeError';
  static const String DATA_CLONE = 'DataCloneError';

  String get name {
    var errorName = JS('String', '#.name', this);
    // Although Safari nightly has updated the name to SecurityError, Safari 5
    // and 6 still return SECURITY_ERR.
    if (Device.isWebKit && errorName == 'SECURITY_ERR') return 'SecurityError';
    // Chrome release still uses old string, remove this line when Chrome stable
    // also prints out SyntaxError.
    if (Device.isWebKit && errorName == 'SYNTAX_ERR') return 'SyntaxError';
    return errorName;
  }
  // To suppress missing implicit constructor warnings.
  factory DomException._() { throw new UnsupportedError("Not supported"); }

  @DomName('DOMException.message')
  @DocsEditable()
  final String message;

  @DomName('DOMException.toString')
  @DocsEditable()
  String toString() native;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('DOMImplementation')
class DomImplementation extends Interceptor native "DOMImplementation" {
  // To suppress missing implicit constructor warnings.
  factory DomImplementation._() { throw new UnsupportedError("Not supported"); }

  @DomName('DOMImplementation.createDocument')
  @DocsEditable()
  XmlDocument createDocument(String namespaceURI, String qualifiedName, _DocumentType doctype) native;

  @DomName('DOMImplementation.createDocumentType')
  @DocsEditable()
  _DocumentType createDocumentType(String qualifiedName, String publicId, String systemId) native;

  @JSName('createHTMLDocument')
  @DomName('DOMImplementation.createHTMLDocument')
  @DocsEditable()
  HtmlDocument createHtmlDocument(String title) native;

  @DomName('DOMImplementation.hasFeature')
  @DocsEditable()
  bool hasFeature(String feature, String version) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('DOMParser')
class DomParser extends Interceptor native "DOMParser" {
  // To suppress missing implicit constructor warnings.
  factory DomParser._() { throw new UnsupportedError("Not supported"); }

  @DomName('DOMParser.DOMParser')
  @DocsEditable()
  factory DomParser() {
    return DomParser._create_1();
  }
  static DomParser _create_1() => JS('DomParser', 'new DOMParser()');

  @DomName('DOMParser.parseFromString')
  @DocsEditable()
  Document parseFromString(String str, String contentType) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('DOMSettableTokenList')
class DomSettableTokenList extends DomTokenList native "DOMSettableTokenList" {
  // To suppress missing implicit constructor warnings.
  factory DomSettableTokenList._() { throw new UnsupportedError("Not supported"); }

  @DomName('DOMSettableTokenList.value')
  @DocsEditable()
  String value;

  @DomName('DOMSettableTokenList.__getter__')
  @DocsEditable()
  String __getter__(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('DOMStringList')
class DomStringList extends Interceptor with ListMixin<String>, ImmutableListMixin<String> implements JavaScriptIndexingBehavior, List<String> native "DOMStringList" {
  // To suppress missing implicit constructor warnings.
  factory DomStringList._() { throw new UnsupportedError("Not supported"); }

  @DomName('DOMStringList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  String operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("String", "#[#]", this, index);
  }
  void operator[]=(int index, String value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<String> mixins.
  // String is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  String get first {
    if (this.length > 0) {
      return JS('String', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  String get last {
    int len = this.length;
    if (len > 0) {
      return JS('String', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  String get single {
    int len = this.length;
    if (len == 1) {
      return JS('String', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  String elementAt(int index) => this[index];
  // -- end List<String> mixins.

  @DomName('DOMStringList.contains')
  @DocsEditable()
  bool contains(String string) native;

  @DomName('DOMStringList.item')
  @DocsEditable()
  String item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('DOMStringMap')
abstract class DomStringMap extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomStringMap._() { throw new UnsupportedError("Not supported"); }

  bool __delete__(index_OR_name);

  String __getter__(index_OR_name);

  void __setter__(index_OR_name, String value);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('DOMTokenList')
class DomTokenList extends Interceptor native "DOMTokenList" {
  // To suppress missing implicit constructor warnings.
  factory DomTokenList._() { throw new UnsupportedError("Not supported"); }

  @DomName('DOMTokenList.length')
  @DocsEditable()
  final int length;

  @DomName('DOMTokenList.contains')
  @DocsEditable()
  bool contains(String token) native;

  @DomName('DOMTokenList.item')
  @DocsEditable()
  String item(int index) native;

  @DomName('DOMTokenList.toString')
  @DocsEditable()
  String toString() native;

  @DomName('DOMTokenList.toggle')
  @DocsEditable()
  bool toggle(String token, [bool force]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


class _ChildrenElementList extends ListBase<Element>
    implements NodeListWrapper {
  // Raw Element.
  final Element _element;
  final HtmlCollection _childElements;

  _ChildrenElementList._wrap(Element element)
    : _childElements = element._children,
      _element = element;

  bool contains(Object element) => _childElements.contains(element);


  bool get isEmpty {
    return _element._firstElementChild == null;
  }

  int get length {
    return _childElements.length;
  }

  Element operator [](int index) {
    return _childElements[index];
  }

  void operator []=(int index, Element value) {
    _element._replaceChild(value, _childElements[index]);
  }

  void set length(int newLength) {
    // TODO(jacobr): remove children when length is reduced.
    throw new UnsupportedError('Cannot resize element lists');
  }

  Element add(Element value) {
    _element.append(value);
    return value;
  }

  Iterator<Element> get iterator => toList().iterator;

  void addAll(Iterable<Element> iterable) {
    if (iterable is _ChildNodeListLazy) {
      iterable = new List.from(iterable);
    }

    for (Element element in iterable) {
      _element.append(element);
    }
  }

  void sort([int compare(Element a, Element b)]) {
    throw new UnsupportedError('Cannot sort element lists');
  }

  void shuffle([Random random]) {
    throw new UnsupportedError('Cannot shuffle element lists');
  }

  void removeWhere(bool test(Element element)) {
    _filter(test, false);
  }

  void retainWhere(bool test(Element element)) {
    _filter(test, true);
  }

  void _filter(bool test(var element), bool retainMatching) {
    var removed;
    if (retainMatching) {
      removed = _element.children.where((e) => !test(e));
    } else {
      removed = _element.children.where(test);
    }
    for (var e in removed) e.remove();
  }

  void setRange(int start, int end, Iterable<Element> iterable,
                [int skipCount = 0]) {
    throw new UnimplementedError();
  }

  void replaceRange(int start, int end, Iterable<Element> iterable) {
    throw new UnimplementedError();
  }

  void fillRange(int start, int end, [Element fillValue]) {
    throw new UnimplementedError();
  }

  bool remove(Object object) {
    if (object is Element) {
      Element element = object;
      if (identical(element.parentNode, _element)) {
        _element._removeChild(element);
        return true;
      }
    }
    return false;
  }

  void insert(int index, Element element) {
    if (index < 0 || index > length) {
      throw new RangeError.range(index, 0, length);
    }
    if (index == length) {
      _element.append(element);
    } else {
      _element.insertBefore(element, this[index]);
    }
  }

  void setAll(int index, Iterable<Element> iterable) {
    throw new UnimplementedError();
  }

  void clear() {
    _element._clearChildren();
  }

  Element removeAt(int index) {
    final result = this[index];
    if (result != null) {
      _element._removeChild(result);
    }
    return result;
  }

  Element removeLast() {
    final result = this.last;
    if (result != null) {
      _element._removeChild(result);
    }
    return result;
  }

  Element get first {
    Element result = _element._firstElementChild;
    if (result == null) throw new StateError("No elements");
    return result;
  }


  Element get last {
    Element result = _element._lastElementChild;
    if (result == null) throw new StateError("No elements");
    return result;
  }

  Element get single {
    if (length > 1) throw new StateError("More than one element");
    return first;
  }

  List<Node> get rawList => _childElements;
}

/**
 * An immutable list containing HTML elements. This list contains some
 * additional methods when compared to regular lists for ease of CSS
 * manipulation on a group of elements.
 */
abstract class ElementList<T extends Element> extends ListBase<T> {
  /**
   * The union of all CSS classes applied to the elements in this list.
   *
   * This set makes it easy to add, remove or toggle (add if not present, remove
   * if present) the classes applied to a collection of elements.
   *
   *     htmlList.classes.add('selected');
   *     htmlList.classes.toggle('isOnline');
   *     htmlList.classes.remove('selected');
   */
  CssClassSet get classes;

  /** Replace the classes with `value` for every element in this list. */
  set classes(Iterable<String> value);

  /**
   * Access the union of all [CssStyleDeclaration]s that are associated with an
   * [ElementList].
   *
   * Grouping the style objects all together provides easy editing of specific
   * properties of a collection of elements. Setting a specific property value
   * will set that property in all [Element]s in the [ElementList]. Getting a
   * specific property value will return the value of the property of the first
   * element in the [ElementList].
   */
  CssStyleDeclarationBase get style;

  /**
   * Access dimensions and position of the Elements in this list.
   *
   * Setting the height or width properties will set the height or width
   * property for all elements in the list. This returns a rectangle with the
   * dimenions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Getting the height or width returns the height or width of the
   * first Element in this list.
   *
   * Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not.
   */
  @Experimental()
  CssRect get contentEdge;

  /**
   * Access dimensions and position of the first Element's content + padding box
   * in this list.
   *
   * This returns a rectangle with the dimenions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's `innerHeight` value for an element. This
   * is also a rectangle equalling the dimensions of clientHeight and
   * clientWidth.
   */
  @Experimental()
  CssRect get paddingEdge;

  /**
   * Access dimensions and position of the first Element's content + padding +
   * border box in this list.
   *
   * This returns a rectangle with the dimenions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's `outerHeight` value for an element.
   */
  @Experimental()
  CssRect get borderEdge;

  /**
   * Access dimensions and position of the first Element's content + padding +
   * border + margin box in this list.
   *
   * This returns a rectangle with the dimenions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's `outerHeight` value for an element.
   */
  @Experimental()
  CssRect get marginEdge;

  /// Stream of `abort` events handled by this [Element].
  @DomName('Element.onabort')
  @DocsEditable()
  ElementStream<Event> get onAbort;

  /// Stream of `beforecopy` events handled by this [Element].
  @DomName('Element.onbeforecopy')
  @DocsEditable()
  ElementStream<Event> get onBeforeCopy;

  /// Stream of `beforecut` events handled by this [Element].
  @DomName('Element.onbeforecut')
  @DocsEditable()
  ElementStream<Event> get onBeforeCut;

  /// Stream of `beforepaste` events handled by this [Element].
  @DomName('Element.onbeforepaste')
  @DocsEditable()
  ElementStream<Event> get onBeforePaste;

  /// Stream of `blur` events handled by this [Element].
  @DomName('Element.onblur')
  @DocsEditable()
  ElementStream<Event> get onBlur;

  /// Stream of `change` events handled by this [Element].
  @DomName('Element.onchange')
  @DocsEditable()
  ElementStream<Event> get onChange;

  /// Stream of `click` events handled by this [Element].
  @DomName('Element.onclick')
  @DocsEditable()
  ElementStream<MouseEvent> get onClick;

  /// Stream of `contextmenu` events handled by this [Element].
  @DomName('Element.oncontextmenu')
  @DocsEditable()
  ElementStream<MouseEvent> get onContextMenu;

  /// Stream of `copy` events handled by this [Element].
  @DomName('Element.oncopy')
  @DocsEditable()
  ElementStream<Event> get onCopy;

  /// Stream of `cut` events handled by this [Element].
  @DomName('Element.oncut')
  @DocsEditable()
  ElementStream<Event> get onCut;

  /// Stream of `doubleclick` events handled by this [Element].
  @DomName('Element.ondblclick')
  @DocsEditable()
  ElementStream<Event> get onDoubleClick;

  /**
   * A stream of `drag` events fired when this element currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondrag')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrag;

  /**
   * A stream of `dragend` events fired when this element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragend')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnd;

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragenter')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnter;

  /**
   * A stream of `dragleave` events fired when an object being dragged over this
   * element leaves this element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragleave')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragLeave;

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragover')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragOver;

  /**
   * A stream of `dragstart` events fired when this element starts being
   * dragged.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragstart')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragStart;

  /**
   * A stream of `drop` events fired when a dragged object is dropped on this
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondrop')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrop;

  /// Stream of `error` events handled by this [Element].
  @DomName('Element.onerror')
  @DocsEditable()
  ElementStream<Event> get onError;

  /// Stream of `focus` events handled by this [Element].
  @DomName('Element.onfocus')
  @DocsEditable()
  ElementStream<Event> get onFocus;

  /// Stream of `input` events handled by this [Element].
  @DomName('Element.oninput')
  @DocsEditable()
  ElementStream<Event> get onInput;

  /// Stream of `invalid` events handled by this [Element].
  @DomName('Element.oninvalid')
  @DocsEditable()
  ElementStream<Event> get onInvalid;

  /// Stream of `keydown` events handled by this [Element].
  @DomName('Element.onkeydown')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyDown;

  /// Stream of `keypress` events handled by this [Element].
  @DomName('Element.onkeypress')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyPress;

  /// Stream of `keyup` events handled by this [Element].
  @DomName('Element.onkeyup')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyUp;

  /// Stream of `load` events handled by this [Element].
  @DomName('Element.onload')
  @DocsEditable()
  ElementStream<Event> get onLoad;

  /// Stream of `mousedown` events handled by this [Element].
  @DomName('Element.onmousedown')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseDown;

  /// Stream of `mouseenter` events handled by this [Element].
  @DomName('Element.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseEnter;

  /// Stream of `mouseleave` events handled by this [Element].
  @DomName('Element.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseLeave;

  /// Stream of `mousemove` events handled by this [Element].
  @DomName('Element.onmousemove')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseMove;

  /// Stream of `mouseout` events handled by this [Element].
  @DomName('Element.onmouseout')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOut;

  /// Stream of `mouseover` events handled by this [Element].
  @DomName('Element.onmouseover')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOver;

  /// Stream of `mouseup` events handled by this [Element].
  @DomName('Element.onmouseup')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseUp;

  /// Stream of `mousewheel` events handled by this [Element].
  @DomName('Element.onmousewheel')
  @DocsEditable()
  // http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents
  @Experimental() // non-standard
  ElementStream<WheelEvent> get onMouseWheel;

  /// Stream of `paste` events handled by this [Element].
  @DomName('Element.onpaste')
  @DocsEditable()
  ElementStream<Event> get onPaste;

  /// Stream of `reset` events handled by this [Element].
  @DomName('Element.onreset')
  @DocsEditable()
  ElementStream<Event> get onReset;

  @DomName('Element.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onResize;

  /// Stream of `scroll` events handled by this [Element].
  @DomName('Element.onscroll')
  @DocsEditable()
  ElementStream<Event> get onScroll;

  /// Stream of `search` events handled by this [Element].
  @DomName('Element.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  ElementStream<Event> get onSearch;

  /// Stream of `select` events handled by this [Element].
  @DomName('Element.onselect')
  @DocsEditable()
  ElementStream<Event> get onSelect;

  /// Stream of `selectstart` events handled by this [Element].
  @DomName('Element.onselectstart')
  @DocsEditable()
  @Experimental() // nonstandard
  ElementStream<Event> get onSelectStart;

  /// Stream of `submit` events handled by this [Element].
  @DomName('Element.onsubmit')
  @DocsEditable()
  ElementStream<Event> get onSubmit;

  /// Stream of `touchcancel` events handled by this [Element].
  @DomName('Element.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchCancel;

  /// Stream of `touchend` events handled by this [Element].
  @DomName('Element.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnd;

  /// Stream of `touchenter` events handled by this [Element].
  @DomName('Element.ontouchenter')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnter;

  /// Stream of `touchleave` events handled by this [Element].
  @DomName('Element.ontouchleave')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchLeave;

  /// Stream of `touchmove` events handled by this [Element].
  @DomName('Element.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchMove;

  /// Stream of `touchstart` events handled by this [Element].
  @DomName('Element.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchStart;

  /// Stream of `transitionend` events handled by this [Element].
  @DomName('Element.ontransitionend')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  ElementStream<TransitionEvent> get onTransitionEnd;

  /// Stream of `fullscreenchange` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenchange')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenChange;

  /// Stream of `fullscreenerror` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenError;

}

// TODO(jacobr): this is an inefficient implementation but it is hard to see
// a better option given that we cannot quite force NodeList to be an
// ElementList as there are valid cases where a NodeList JavaScript object
// contains Node objects that are not Elements.
class _FrozenElementList<T extends Element> extends ListBase<T>
    implements ElementList<T>, NodeListWrapper {
  final List<Node> _nodeList;
  // The subset of _nodeList that are Elements.
  List<Element> _elementList;

  _FrozenElementList._wrap(this._nodeList) {
    _elementList = _nodeList.where((e) => e is Element).toList();
  }

  int get length => _nodeList.length;

  Element operator [](int index) => _nodeList[index];

  void operator []=(int index, Element value) {
    throw new UnsupportedError('Cannot modify list');
  }

  void set length(int newLength) {
    throw new UnsupportedError('Cannot modify list');
  }

  void sort([Comparator<Element> compare]) {
    throw new UnsupportedError('Cannot sort list');
  }

  void shuffle([Random random]) {
    throw new UnsupportedError('Cannot shuffle list');
  }

  Element get first => _nodeList.first;

  Element get last => _nodeList.last;

  Element get single => _nodeList.single;

  CssClassSet get classes => new _MultiElementCssClassSet(_elementList);

  CssStyleDeclarationBase get style =>
      new _CssStyleDeclarationSet(_elementList);

  void set classes(Iterable<String> value) {
    _elementList.forEach((e) => e.classes = value);
  }

  CssRect get contentEdge => new _ContentCssListRect(_elementList);

  CssRect get paddingEdge => _elementList.first.paddingEdge;

  CssRect get borderEdge => _elementList.first.borderEdge;

  CssRect get marginEdge => _elementList.first.marginEdge;

  List<Node> get rawList => _nodeList;


  /// Stream of `abort` events handled by this [Element].
  @DomName('Element.onabort')
  @DocsEditable()
  ElementStream<Event> get onAbort => Element.abortEvent._forElementList(this);

  /// Stream of `beforecopy` events handled by this [Element].
  @DomName('Element.onbeforecopy')
  @DocsEditable()
  ElementStream<Event> get onBeforeCopy => Element.beforeCopyEvent._forElementList(this);

  /// Stream of `beforecut` events handled by this [Element].
  @DomName('Element.onbeforecut')
  @DocsEditable()
  ElementStream<Event> get onBeforeCut => Element.beforeCutEvent._forElementList(this);

  /// Stream of `beforepaste` events handled by this [Element].
  @DomName('Element.onbeforepaste')
  @DocsEditable()
  ElementStream<Event> get onBeforePaste => Element.beforePasteEvent._forElementList(this);

  /// Stream of `blur` events handled by this [Element].
  @DomName('Element.onblur')
  @DocsEditable()
  ElementStream<Event> get onBlur => Element.blurEvent._forElementList(this);

  /// Stream of `change` events handled by this [Element].
  @DomName('Element.onchange')
  @DocsEditable()
  ElementStream<Event> get onChange => Element.changeEvent._forElementList(this);

  /// Stream of `click` events handled by this [Element].
  @DomName('Element.onclick')
  @DocsEditable()
  ElementStream<MouseEvent> get onClick => Element.clickEvent._forElementList(this);

  /// Stream of `contextmenu` events handled by this [Element].
  @DomName('Element.oncontextmenu')
  @DocsEditable()
  ElementStream<MouseEvent> get onContextMenu => Element.contextMenuEvent._forElementList(this);

  /// Stream of `copy` events handled by this [Element].
  @DomName('Element.oncopy')
  @DocsEditable()
  ElementStream<Event> get onCopy => Element.copyEvent._forElementList(this);

  /// Stream of `cut` events handled by this [Element].
  @DomName('Element.oncut')
  @DocsEditable()
  ElementStream<Event> get onCut => Element.cutEvent._forElementList(this);

  /// Stream of `doubleclick` events handled by this [Element].
  @DomName('Element.ondblclick')
  @DocsEditable()
  ElementStream<Event> get onDoubleClick => Element.doubleClickEvent._forElementList(this);

  /**
   * A stream of `drag` events fired when this element currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondrag')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrag => Element.dragEvent._forElementList(this);

  /**
   * A stream of `dragend` events fired when this element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragend')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnd => Element.dragEndEvent._forElementList(this);

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragenter')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnter => Element.dragEnterEvent._forElementList(this);

  /**
   * A stream of `dragleave` events fired when an object being dragged over this
   * element leaves this element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragleave')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragLeave => Element.dragLeaveEvent._forElementList(this);

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragover')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragOver => Element.dragOverEvent._forElementList(this);

  /**
   * A stream of `dragstart` events fired when this element starts being
   * dragged.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragstart')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragStart => Element.dragStartEvent._forElementList(this);

  /**
   * A stream of `drop` events fired when a dragged object is dropped on this
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondrop')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrop => Element.dropEvent._forElementList(this);

  /// Stream of `error` events handled by this [Element].
  @DomName('Element.onerror')
  @DocsEditable()
  ElementStream<Event> get onError => Element.errorEvent._forElementList(this);

  /// Stream of `focus` events handled by this [Element].
  @DomName('Element.onfocus')
  @DocsEditable()
  ElementStream<Event> get onFocus => Element.focusEvent._forElementList(this);

  /// Stream of `input` events handled by this [Element].
  @DomName('Element.oninput')
  @DocsEditable()
  ElementStream<Event> get onInput => Element.inputEvent._forElementList(this);

  /// Stream of `invalid` events handled by this [Element].
  @DomName('Element.oninvalid')
  @DocsEditable()
  ElementStream<Event> get onInvalid => Element.invalidEvent._forElementList(this);

  /// Stream of `keydown` events handled by this [Element].
  @DomName('Element.onkeydown')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyDown => Element.keyDownEvent._forElementList(this);

  /// Stream of `keypress` events handled by this [Element].
  @DomName('Element.onkeypress')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyPress => Element.keyPressEvent._forElementList(this);

  /// Stream of `keyup` events handled by this [Element].
  @DomName('Element.onkeyup')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyUp => Element.keyUpEvent._forElementList(this);

  /// Stream of `load` events handled by this [Element].
  @DomName('Element.onload')
  @DocsEditable()
  ElementStream<Event> get onLoad => Element.loadEvent._forElementList(this);

  /// Stream of `mousedown` events handled by this [Element].
  @DomName('Element.onmousedown')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseDown => Element.mouseDownEvent._forElementList(this);

  /// Stream of `mouseenter` events handled by this [Element].
  @DomName('Element.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseEnter => Element.mouseEnterEvent._forElementList(this);

  /// Stream of `mouseleave` events handled by this [Element].
  @DomName('Element.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseLeave => Element.mouseLeaveEvent._forElementList(this);

  /// Stream of `mousemove` events handled by this [Element].
  @DomName('Element.onmousemove')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseMove => Element.mouseMoveEvent._forElementList(this);

  /// Stream of `mouseout` events handled by this [Element].
  @DomName('Element.onmouseout')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOut => Element.mouseOutEvent._forElementList(this);

  /// Stream of `mouseover` events handled by this [Element].
  @DomName('Element.onmouseover')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOver => Element.mouseOverEvent._forElementList(this);

  /// Stream of `mouseup` events handled by this [Element].
  @DomName('Element.onmouseup')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseUp => Element.mouseUpEvent._forElementList(this);

  /// Stream of `mousewheel` events handled by this [Element].
  @DomName('Element.onmousewheel')
  @DocsEditable()
  // http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents
  @Experimental() // non-standard
  ElementStream<WheelEvent> get onMouseWheel => Element.mouseWheelEvent._forElementList(this);

  /// Stream of `paste` events handled by this [Element].
  @DomName('Element.onpaste')
  @DocsEditable()
  ElementStream<Event> get onPaste => Element.pasteEvent._forElementList(this);

  /// Stream of `reset` events handled by this [Element].
  @DomName('Element.onreset')
  @DocsEditable()
  ElementStream<Event> get onReset => Element.resetEvent._forElementList(this);

  @DomName('Element.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onResize => Element.resizeEvent._forElementList(this);

  /// Stream of `scroll` events handled by this [Element].
  @DomName('Element.onscroll')
  @DocsEditable()
  ElementStream<Event> get onScroll => Element.scrollEvent._forElementList(this);

  /// Stream of `search` events handled by this [Element].
  @DomName('Element.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  ElementStream<Event> get onSearch => Element.searchEvent._forElementList(this);

  /// Stream of `select` events handled by this [Element].
  @DomName('Element.onselect')
  @DocsEditable()
  ElementStream<Event> get onSelect => Element.selectEvent._forElementList(this);

  /// Stream of `selectstart` events handled by this [Element].
  @DomName('Element.onselectstart')
  @DocsEditable()
  @Experimental() // nonstandard
  ElementStream<Event> get onSelectStart => Element.selectStartEvent._forElementList(this);

  /// Stream of `submit` events handled by this [Element].
  @DomName('Element.onsubmit')
  @DocsEditable()
  ElementStream<Event> get onSubmit => Element.submitEvent._forElementList(this);

  /// Stream of `touchcancel` events handled by this [Element].
  @DomName('Element.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchCancel => Element.touchCancelEvent._forElementList(this);

  /// Stream of `touchend` events handled by this [Element].
  @DomName('Element.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnd => Element.touchEndEvent._forElementList(this);

  /// Stream of `touchenter` events handled by this [Element].
  @DomName('Element.ontouchenter')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnter => Element.touchEnterEvent._forElementList(this);

  /// Stream of `touchleave` events handled by this [Element].
  @DomName('Element.ontouchleave')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchLeave => Element.touchLeaveEvent._forElementList(this);

  /// Stream of `touchmove` events handled by this [Element].
  @DomName('Element.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchMove => Element.touchMoveEvent._forElementList(this);

  /// Stream of `touchstart` events handled by this [Element].
  @DomName('Element.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchStart => Element.touchStartEvent._forElementList(this);

  /// Stream of `transitionend` events handled by this [Element].
  @DomName('Element.ontransitionend')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  ElementStream<TransitionEvent> get onTransitionEnd => Element.transitionEndEvent._forElementList(this);

  /// Stream of `fullscreenchange` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenchange')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenChange => Element.fullscreenChangeEvent._forElementList(this);

  /// Stream of `fullscreenerror` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenError => Element.fullscreenErrorEvent._forElementList(this);

}

@DocsEditable()
/**
 * An abstract class, which all HTML elements extend.
 */
@DomName('Element')
abstract class Element extends Node implements GlobalEventHandlers, ParentNode, ChildNode native "Element" {

  /**
   * Creates an HTML element from a valid fragment of HTML.
   *
   *     var element = new Element.html('<div class="foo">content</div>');
   *
   * The HTML fragment should contain only one single root element, any
   * leading or trailing text nodes will be removed.
   *
   * The HTML fragment is parsed as if it occurred within the context of a
   * `<body>` tag, this means that special elements such as `<caption>` which
   * must be parsed within the scope of a `<table>` element will be dropped. Use
   * [createFragment] to parse contextual HTML fragments.
   *
   * Unless a validator is provided this will perform the default validation
   * and remove all scriptable elements and attributes.
   *
   * See also:
   *
   * * [NodeValidator]
   *
   */
  factory Element.html(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    var fragment = document.body.createFragment(html, validator: validator,
        treeSanitizer: treeSanitizer);

    return fragment.nodes.where((e) => e is Element).single;
  }

  /**
   * Custom element creation constructor.
   *
   * This constructor is used by the DOM when a custom element has been
   * created. It can only be invoked by subclasses of Element from
   * that classes created constructor.
   *
   *     class CustomElement extends Element {
   *       factory CustomElement() => new Element.tag('x-custom');
   *
   *       CustomElement.created() : super.created() {
   *          // Perform any element initialization.
   *       }
   *     }
   *     document.registerElement('x-custom', CustomElement);
   */
  Element.created() : super._created() {
    // Validate that this is a custom element & perform any additional
    // initialization.
    _initializeCustomElement(this);
  }

  /**
   * Creates the HTML element specified by the tag name.
   *
   * This is similar to [Document.createElement].
   * [tag] should be a valid HTML tag name. If [tag] is an unknown tag then
   * this will create an [UnknownElement].
   *
   *     var divElement = new Element.tag('div');
   *     print(divElement is DivElement); // 'true'
   *     var myElement = new Element.tag('unknownTag');
   *     print(myElement is UnknownElement); // 'true'
   *
   * For standard elements it is more preferable to use the type constructors:
   *     var element = new DivElement();
   *
   * See also:
   *
   * * [isTagSupported]
   */
  factory Element.tag(String tag, [String typeExtention]) =>
      _ElementFactoryProvider.createElement_tag(tag, typeExtention);

  /// Creates a new `<a>` element.
  ///
  /// This is identical to calling `new Element.tag('a')`.
  factory Element.a() => new Element.tag('a');

  /// Creates a new `<article>` element.
  ///
  /// This is identical to calling `new Element.tag('article')`.
  factory Element.article() => new Element.tag('article');

  /// Creates a new `<aside>` element.
  ///
  /// This is identical to calling `new Element.tag('aside')`.
  factory Element.aside() => new Element.tag('aside');

  /// Creates a new `<audio>` element.
  ///
  /// This is identical to calling `new Element.tag('audio')`.
  factory Element.audio() => new Element.tag('audio');

  /// Creates a new `<br>` element.
  ///
  /// This is identical to calling `new Element.tag('br')`.
  factory Element.br() => new Element.tag('br');

  /// Creates a new `<canvas>` element.
  ///
  /// This is identical to calling `new Element.tag('canvas')`.
  factory Element.canvas() => new Element.tag('canvas');

  /// Creates a new `<div>` element.
  ///
  /// This is identical to calling `new Element.tag('div')`.
  factory Element.div() => new Element.tag('div');

  /// Creates a new `<footer>` element.
  ///
  /// This is identical to calling `new Element.tag('footer')`.
  factory Element.footer() => new Element.tag('footer');

  /// Creates a new `<header>` element.
  ///
  /// This is identical to calling `new Element.tag('header')`.
  factory Element.header() => new Element.tag('header');

  /// Creates a new `<hr>` element.
  ///
  /// This is identical to calling `new Element.tag('hr')`.
  factory Element.hr() => new Element.tag('hr');

  /// Creates a new `<iframe>` element.
  ///
  /// This is identical to calling `new Element.tag('iframe')`.
  factory Element.iframe() => new Element.tag('iframe');

  /// Creates a new `<img>` element.
  ///
  /// This is identical to calling `new Element.tag('img')`.
  factory Element.img() => new Element.tag('img');

  /// Creates a new `<li>` element.
  ///
  /// This is identical to calling `new Element.tag('li')`.
  factory Element.li() => new Element.tag('li');

  /// Creates a new `<nav>` element.
  ///
  /// This is identical to calling `new Element.tag('nav')`.
  factory Element.nav() => new Element.tag('nav');

  /// Creates a new `<ol>` element.
  ///
  /// This is identical to calling `new Element.tag('ol')`.
  factory Element.ol() => new Element.tag('ol');

  /// Creates a new `<option>` element.
  ///
  /// This is identical to calling `new Element.tag('option')`.
  factory Element.option() => new Element.tag('option');

  /// Creates a new `<p>` element.
  ///
  /// This is identical to calling `new Element.tag('p')`.
  factory Element.p() => new Element.tag('p');

  /// Creates a new `<pre>` element.
  ///
  /// This is identical to calling `new Element.tag('pre')`.
  factory Element.pre() => new Element.tag('pre');

  /// Creates a new `<section>` element.
  ///
  /// This is identical to calling `new Element.tag('section')`.
  factory Element.section() => new Element.tag('section');

  /// Creates a new `<select>` element.
  ///
  /// This is identical to calling `new Element.tag('select')`.
  factory Element.select() => new Element.tag('select');

  /// Creates a new `<span>` element.
  ///
  /// This is identical to calling `new Element.tag('span')`.
  factory Element.span() => new Element.tag('span');

  /// Creates a new `<svg>` element.
  ///
  /// This is identical to calling `new Element.tag('svg')`.
  factory Element.svg() => new Element.tag('svg');

  /// Creates a new `<table>` element.
  ///
  /// This is identical to calling `new Element.tag('table')`.
  factory Element.table() => new Element.tag('table');

  /// Creates a new `<td>` element.
  ///
  /// This is identical to calling `new Element.tag('td')`.
  factory Element.td() => new Element.tag('td');

  /// Creates a new `<textarea>` element.
  ///
  /// This is identical to calling `new Element.tag('textarea')`.
  factory Element.textarea() => new Element.tag('textarea');

  /// Creates a new `<th>` element.
  ///
  /// This is identical to calling `new Element.tag('th')`.
  factory Element.th() => new Element.tag('th');

  /// Creates a new `<tr>` element.
  ///
  /// This is identical to calling `new Element.tag('tr')`.
  factory Element.tr() => new Element.tag('tr');

  /// Creates a new `<ul>` element.
  ///
  /// This is identical to calling `new Element.tag('ul')`.
  factory Element.ul() => new Element.tag('ul');

  /// Creates a new `<video>` element.
  ///
  /// This is identical to calling `new Element.tag('video')`.
  factory Element.video() => new Element.tag('video');

  /**
   * All attributes on this element.
   *
   * Any modifications to the attribute map will automatically be applied to
   * this element.
   *
   * This only includes attributes which are not in a namespace
   * (such as 'xlink:href'), additional attributes can be accessed via
   * [getNamespacedAttributes].
   */
  Map<String, String> get attributes => new _ElementAttributeMap(this);

  void set attributes(Map<String, String> value) {
    Map<String, String> attributes = this.attributes;
    attributes.clear();
    for (String key in value.keys) {
      attributes[key] = value[key];
    }
  }

  /**
   * List of the direct children of this element.
   *
   * This collection can be used to add and remove elements from the document.
   *
   *     var item = new DivElement();
   *     item.text = 'Something';
   *     document.body.children.add(item) // Item is now displayed on the page.
   *     for (var element in document.body.children) {
   *       element.style.background = 'red'; // Turns every child of body red.
   *     }
   */
  List<Element> get children => new _ChildrenElementList._wrap(this);

  void set children(List<Element> value) {
    // Copy list first since we don't want liveness during iteration.
    List copy = new List.from(value);
    var children = this.children;
    children.clear();
    children.addAll(copy);
  }

  /**
   * Finds all descendent elements of this element that match the specified
   * group of selectors.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var items = element.querySelectorAll('.itemClassName');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  @DomName('Element.querySelectorAll')
  ElementList querySelectorAll(String selectors) =>
    new _FrozenElementList._wrap(_querySelectorAll(selectors));

  /**
   * Alias for [querySelector]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @DomName('Element.querySelector')
  @Experimental()
  Element query(String relativeSelectors) => querySelector(relativeSelectors);

  /**
   * Alias for [querySelectorAll]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @DomName('Element.querySelectorAll')
  @Experimental()
  ElementList queryAll(String relativeSelectors) =>
      querySelectorAll(relativeSelectors);

  /**
   * The set of CSS classes applied to this element.
   *
   * This set makes it easy to add, remove or toggle the classes applied to
   * this element.
   *
   *     element.classes.add('selected');
   *     element.classes.toggle('isOnline');
   *     element.classes.remove('selected');
   */
  CssClassSet get classes => new _ElementCssClassSet(this);

  void set classes(Iterable<String> value) {
    CssClassSet classSet = classes;
    classSet.clear();
    classSet.addAll(value);
  }

  /**
   * Allows access to all custom data attributes (data-*) set on this element.
   *
   * The keys for the map must follow these rules:
   *
   * * The name must not begin with 'xml'.
   * * The name cannot contain a semi-colon (';').
   * * The name cannot contain any capital letters.
   *
   * Any keys from markup will be converted to camel-cased keys in the map.
   *
   * For example, HTML specified as:
   *
   *     <div data-my-random-value='value'></div>
   *
   * Would be accessed in Dart as:
   *
   *     var value = element.dataset['myRandomValue'];
   *
   * See also:
   *
   * * [Custom data attributes](http://www.w3.org/TR/html5/global-attributes.html#custom-data-attribute)
   */
  Map<String, String> get dataset =>
    new _DataAttributeMap(attributes);

  void set dataset(Map<String, String> value) {
    final data = this.dataset;
    data.clear();
    for (String key in value.keys) {
      data[key] = value[key];
    }
  }

  /**
   * Gets a map for manipulating the attributes of a particular namespace.
   *
   * This is primarily useful for SVG attributes such as xref:link.
   */
  Map<String, String> getNamespacedAttributes(String namespace) {
    return new _NamespacedAttributeMap(this, namespace);
  }

  /**
   * The set of all CSS values applied to this element, including inherited
   * and default values.
   *
   * The computedStyle contains values that are inherited from other
   * sources, such as parent elements or stylesheets. This differs from the
   * [style] property, which contains only the values specified directly on this
   * element.
   *
   * PseudoElement can be values such as `::after`, `::before`, `::marker`,
   * `::line-marker`.
   *
   * See also:
   *
   * * [CSS Inheritance and Cascade](http://docs.webplatform.org/wiki/tutorials/inheritance_and_cascade)
   * * [Pseudo-elements](http://docs.webplatform.org/wiki/css/selectors/pseudo-elements)
   */
  CssStyleDeclaration getComputedStyle([String pseudoElement]) {
    if (pseudoElement == null) {
      pseudoElement = '';
    }
    // TODO(jacobr): last param should be null, see b/5045788
    return window._getComputedStyle(this, pseudoElement);
  }

  /**
   * Gets the position of this element relative to the client area of the page.
   */
  Rectangle get client => new Rectangle(clientLeft, clientTop, clientWidth,
      clientHeight);

  /**
   * Gets the offset of this element relative to its offsetParent.
   */
  Rectangle get offset => new Rectangle(offsetLeft, offsetTop, offsetWidth,
      offsetHeight);

  /**
   * Adds the specified text after the last child of this element.
   */
  void appendText(String text) {
    this.insertAdjacentText('beforeend', text);
  }

  /**
   * Parses the specified text as HTML and adds the resulting node after the
   * last child of this element.
   */
  void appendHtml(String text) {
    this.insertAdjacentHtml('beforeend', text);
  }

  /**
   * Checks to see if the tag name is supported by the current platform.
   *
   * The tag should be a valid HTML tag name.
   */
  static bool isTagSupported(String tag) {
    var e = _ElementFactoryProvider.createElement_tag(tag, null);
    return e is Element && !(e is UnknownElement);
  }

  /**
   * Called by the DOM when this element has been inserted into the live
   * document.
   *
   * More information can be found in the
   * [Custom Elements](http://w3c.github.io/webcomponents/spec/custom/#dfn-attached-callback)
   * draft specification.
   */
  @Experimental()
  void attached() {
    // For the deprecation period, call the old callback.
    enteredView();
  }

  /**
   * Called by the DOM when this element has been removed from the live
   * document.
   *
   * More information can be found in the
   * [Custom Elements](http://w3c.github.io/webcomponents/spec/custom/#dfn-detached-callback)
   * draft specification.
   */
  @Experimental()
  void detached() {
    // For the deprecation period, call the old callback.
    leftView();
  }

  /** *Deprecated*: override [attached] instead. */
  @Experimental()
  @deprecated
  void enteredView() {}

  /** *Deprecated*: override [detached] instead. */
  @Experimental()
  @deprecated
  void leftView() {}

  /**
   * Called by the DOM whenever an attribute on this has been changed.
   */
  void attributeChanged(String name, String oldValue, String newValue) {}

  // Hooks to support custom WebComponents.

  @Creates('Null')  // Set from Dart code; does not instantiate a native type.
  Element _xtag;

  /**
   * Experimental support for [web components][wc]. This field stores a
   * reference to the component implementation. It was inspired by Mozilla's
   * [x-tags][] project. Please note: in the future it may be possible to
   * `extend Element` from your class, in which case this field will be
   * deprecated.
   *
   * If xtag has not been set, it will simply return `this` [Element].
   *
   * [wc]: http://dvcs.w3.org/hg/webcomponents/raw-file/tip/explainer/index.html
   * [x-tags]: http://x-tags.org/
   */
  // Note: return type is `dynamic` for convenience to suppress warnings when
  // members of the component are used. The actual type is a subtype of Element.
  get xtag => _xtag != null ? _xtag : this;

  void set xtag(Element value) {
    _xtag = value;
  }

  @DomName('Element.localName')
  @DocsEditable()
  String get localName => _localName;

  /**
   * A URI that identifies the XML namespace of this element.
   *
   * `null` if no namespace URI is specified.
   *
   * ## Other resources
   *
   * * [Node.namespaceURI]
   * (http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-NodeNSname) from W3C.
   */
  @DomName('Element.namespaceUri')
  String get namespaceUri => _namespaceUri;

  /**
   * The string representation of this element.
   *
   * This is equivalent to reading the [localName] property.
   */
  String toString() => localName;

  /**
   * Scrolls this element into view.
   *
   * Only one of of the alignment options may be specified at a time.
   *
   * If no options are specified then this will attempt to scroll the minimum
   * amount needed to bring the element into view.
   *
   * Note that alignCenter is currently only supported on WebKit platforms. If
   * alignCenter is specified but not supported then this will fall back to
   * alignTop.
   *
   * See also:
   *
   * * [scrollIntoView](http://docs.webplatform.org/wiki/dom/methods/scrollIntoView)
   * * [scrollIntoViewIfNeeded](http://docs.webplatform.org/wiki/dom/methods/scrollIntoViewIfNeeded)
   */
  void scrollIntoView([ScrollAlignment alignment]) {
    var hasScrollIntoViewIfNeeded = true;
    hasScrollIntoViewIfNeeded =
        JS('bool', '!!(#.scrollIntoViewIfNeeded)', this);
    if (alignment == ScrollAlignment.TOP) {
      this._scrollIntoView(true);
    } else if (alignment == ScrollAlignment.BOTTOM) {
      this._scrollIntoView(false);
    } else if (hasScrollIntoViewIfNeeded) {
      if (alignment == ScrollAlignment.CENTER) {
        this._scrollIntoViewIfNeeded(true);
      } else {
        this._scrollIntoViewIfNeeded();
      }
    } else {
      this._scrollIntoView();
    }
  }

  /**
   * Static factory designed to expose `mousewheel` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mouseWheelEvent')
  static const EventStreamProvider<WheelEvent> mouseWheelEvent =
      const _CustomEventStreamProvider<WheelEvent>(
        Element._determineMouseWheelEventType);

  static String _determineMouseWheelEventType(EventTarget e) {
    if (JS('bool', '#.onwheel !== undefined', e)) {
      // W3C spec, and should be IE9+, but IE has a bug exposing onwheel.
      return 'wheel';
    } else if (JS('bool', '#.onmousewheel !== undefined', e)) {
      // Chrome & IE
      return 'mousewheel';
    } else {
      // Firefox
      return 'DOMMouseScroll';
    }
  }

  /**
   * Static factory designed to expose `transitionend` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.transitionEndEvent')
  static const EventStreamProvider<TransitionEvent> transitionEndEvent =
      const _CustomEventStreamProvider<TransitionEvent>(
        Element._determineTransitionEventType);

  static String _determineTransitionEventType(EventTarget e) {
    // Unfortunately the normal 'ontransitionend' style checks don't work here.
    if (Device.isWebKit) {
      return 'webkitTransitionEnd';
    } else if (Device.isOpera) {
      return 'oTransitionEnd';
    }
    return 'transitionend';
  }
  /**
   * Inserts text into the DOM at the specified location.
   *
   * To see the possible values for [where], read the doc for
   * [insertAdjacentHtml].
   *
   * See also:
   *
   * * [insertAdjacentHtml]
   */
  void insertAdjacentText(String where, String text) {
    if (JS('bool', '!!#.insertAdjacentText', this)) {
      _insertAdjacentText(where, text);
    } else {
      _insertAdjacentNode(where, new Text(text));
    }
  }

  @JSName('insertAdjacentText')
  void _insertAdjacentText(String where, String text) native;

  /**
   * Parses text as an HTML fragment and inserts it into the DOM at the
   * specified location.
   *
   * The [where] parameter indicates where to insert the HTML fragment:
   *
   * * 'beforeBegin': Immediately before this element.
   * * 'afterBegin': As the first child of this element.
   * * 'beforeEnd': As the last child of this element.
   * * 'afterEnd': Immediately after this element.
   *
   *     var html = '<div class="something">content</div>';
   *     // Inserts as the first child
   *     document.body.insertAdjacentHtml('afterBegin', html);
   *     var createdElement = document.body.children[0];
   *     print(createdElement.classes[0]); // Prints 'something'
   *
   * See also:
   *
   * * [insertAdjacentText]
   * * [insertAdjacentElement]
   */
  void insertAdjacentHtml(String where, String html) {
    if (JS('bool', '!!#.insertAdjacentHTML', this)) {
      _insertAdjacentHtml(where, html);
    } else {
      _insertAdjacentNode(where, new DocumentFragment.html(html));
    }
  }

  @JSName('insertAdjacentHTML')
  void _insertAdjacentHtml(String where, String text) native;

  /**
   * Inserts [element] into the DOM at the specified location.
   *
   * To see the possible values for [where], read the doc for
   * [insertAdjacentHtml].
   *
   * See also:
   *
   * * [insertAdjacentHtml]
   */
  Element insertAdjacentElement(String where, Element element) {
    if (JS('bool', '!!#.insertAdjacentElement', this)) {
      _insertAdjacentElement(where, element);
    } else {
      _insertAdjacentNode(where, element);
    }
    return element;
  }

  @JSName('insertAdjacentElement')
  void _insertAdjacentElement(String where, Element element) native;

  void _insertAdjacentNode(String where, Node node) {
    switch (where.toLowerCase()) {
      case 'beforebegin':
        this.parentNode.insertBefore(node, this);
        break;
      case 'afterbegin':
        var first = this.nodes.length > 0 ? this.nodes[0] : null;
        this.insertBefore(node, first);
        break;
      case 'beforeend':
        this.append(node);
        break;
      case 'afterend':
        this.parentNode.insertBefore(node, this.nextNode);
        break;
      default:
        throw new ArgumentError("Invalid position ${where}");
    }
  }

  /**
   * Checks if this element matches the CSS selectors.
   */
  @Experimental()
  bool matches(String selectors) {
    if (JS('bool', '!!#.matches', this)) {
      return JS('bool', '#.matches(#)', this, selectors);
    } else if (JS('bool', '!!#.webkitMatchesSelector', this)) {
      return JS('bool', '#.webkitMatchesSelector(#)', this, selectors);
    } else if (JS('bool', '!!#.mozMatchesSelector', this)) {
      return JS('bool', '#.mozMatchesSelector(#)', this, selectors);
    } else if (JS('bool', '!!#.msMatchesSelector', this)) {
      return JS('bool', '#.msMatchesSelector(#)', this, selectors);
    } else if (JS('bool', '!!#.oMatchesSelector', this)) {
      return JS('bool', '#.oMatchesSelector(#)', this, selectors);
    } else {
      throw new UnsupportedError("Not supported on this platform");
    }
  }

  /** Checks if this element or any of its parents match the CSS selectors. */
  @Experimental()
  bool matchesWithAncestors(String selectors) {
    var elem = this;
    do {
      if (elem.matches(selectors)) return true;
      elem = elem.parent;
    } while(elem != null);
    return false;
  }

  /**
   * Creates a new shadow root for this shadow host.
   *
   * ## Other resources
   *
   * * [Shadow DOM 101]
   * (http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
   * from HTML5Rocks.
   * * [Shadow DOM specification]
   * (http://www.w3.org/TR/shadow-dom/) from W3C.
   */
  @DomName('Element.createShadowRoot')
  @SupportedBrowser(SupportedBrowser.CHROME, '25')
  @Experimental()
  ShadowRoot createShadowRoot() {
    return JS('ShadowRoot',
      '(#.createShadowRoot || #.webkitCreateShadowRoot).call(#)',
      this, this, this);
  }

  /**
   * The shadow root of this shadow host.
   *
   * ## Other resources
   *
   * * [Shadow DOM 101]
   * (http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
   * from HTML5Rocks.
   * * [Shadow DOM specification]
   * (http://www.w3.org/TR/shadow-dom/) from W3C.
   */
  @DomName('Element.shadowRoot')
  @SupportedBrowser(SupportedBrowser.CHROME, '25')
  @Experimental()
  ShadowRoot get shadowRoot =>
      JS('ShadowRoot|Null', '#.shadowRoot || #.webkitShadowRoot', this, this);

  /**
   * Access this element's content position.
   *
   * This returns a rectangle with the dimenions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not.
   *
   * _Important_ _note_: use of this method _will_ perform CSS calculations that
   * can trigger a browser reflow. Therefore, use of this property _during_ an
   * animation frame is discouraged. See also:
   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
   */
  @Experimental()
  CssRect get contentEdge => new _ContentCssRect(this);

  /**
   * Access the dimensions and position of this element's content + padding box.
   *
   * This returns a rectangle with the dimenions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's
   * [innerHeight](http://api.jquery.com/innerHeight/) value for an element.
   * This is also a rectangle equalling the dimensions of clientHeight and
   * clientWidth.
   *
   * _Important_ _note_: use of this method _will_ perform CSS calculations that
   * can trigger a browser reflow. Therefore, use of this property _during_ an
   * animation frame is discouraged. See also:
   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
   */
  @Experimental()
  CssRect get paddingEdge => new _PaddingCssRect(this);

  /**
   * Access the dimensions and position of this element's content + padding +
   * border box.
   *
   * This returns a rectangle with the dimenions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's
   * [outerHeight](http://api.jquery.com/outerHeight/) value for an element.
   *
   * _Important_ _note_: use of this method _will_ perform CSS calculations that
   * can trigger a browser reflow. Therefore, use of this property _during_ an
   * animation frame is discouraged. See also:
   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
   */
  @Experimental()
  CssRect get borderEdge => new _BorderCssRect(this);

  /**
   * Access the dimensions and position of this element's content + padding +
   * border + margin box.
   *
   * This returns a rectangle with the dimenions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's
   * [outerHeight](http://api.jquery.com/outerHeight/) value for an element.
   *
   * _Important_ _note_: use of this method will perform CSS calculations that
   * can trigger a browser reflow. Therefore, use of this property _during_ an
   * animation frame is discouraged. See also:
   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
   */
  @Experimental()
  CssRect get marginEdge => new _MarginCssRect(this);

  /**
   * Provides the coordinates of the element relative to the top of the
   * document.
   *
   * This method is the Dart equivalent to jQuery's
   * [offset](http://api.jquery.com/offset/) method.
   */
  @Experimental()
  Point get documentOffset => offsetTo(document.documentElement);

  /**
   * Provides the offset of this element's [borderEdge] relative to the
   * specified [parent].
   *
   * This is the Dart equivalent of jQuery's
   * [position](http://api.jquery.com/position/) method. Unlike jQuery's
   * position, however, [parent] can be any parent element of `this`,
   * rather than only `this`'s immediate [offsetParent]. If the specified
   * element is _not_ an offset parent or transitive offset parent to this
   * element, an [ArgumentError] is thrown.
   */
  @Experimental()
  Point offsetTo(Element parent) {
    return Element._offsetToHelper(this, parent);
  }

  static Point _offsetToHelper(Element current, Element parent) {
    // We're hopping from _offsetParent_ to offsetParent (not just parent), so
    // offsetParent, "tops out" at BODY. But people could conceivably pass in
    // the document.documentElement and I want it to return an absolute offset,
    // so we have the special case checking for HTML.
    bool foundAsParent = identical(current, parent) || parent.tagName == 'HTML';
    if (current == null || identical(current, parent)) {
      if (foundAsParent) return new Point(0, 0);
      throw new ArgumentError("Specified element is not a transitive offset "
          "parent of this element.");
    }
    Element parentOffset = current.offsetParent;
    Point p = Element._offsetToHelper(parentOffset, parent);
    return new Point(p.x + current.offsetLeft, p.y + current.offsetTop);
  }

  static HtmlDocument _parseDocument;
  static Range _parseRange;
  static NodeValidatorBuilder _defaultValidator;
  static _ValidatingTreeSanitizer _defaultSanitizer;

  /**
   * Create a DocumentFragment from the HTML fragment and ensure that it follows
   * the sanitization rules specified by the validator or treeSanitizer.
   *
   * If the default validation behavior is too restrictive then a new
   * NodeValidator should be created, either extending or wrapping a default
   * validator and overriding the validation APIs.
   *
   * The treeSanitizer is used to walk the generated node tree and sanitize it.
   * A custom treeSanitizer can also be provided to perform special validation
   * rules but since the API is more complex to implement this is discouraged.
   *
   * The returned tree is guaranteed to only contain nodes and attributes which
   * are allowed by the provided validator.
   *
   * See also:
   *
   * * [NodeValidator]
   * * [NodeTreeSanitizer]
   */
  DocumentFragment createFragment(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    if (treeSanitizer == null) {
      if (validator == null) {
        if (_defaultValidator == null) {
          _defaultValidator = new NodeValidatorBuilder.common();
        }
        validator = _defaultValidator;
      }
      if (_defaultSanitizer == null) {
        _defaultSanitizer = new _ValidatingTreeSanitizer(validator);
      } else {
        _defaultSanitizer.validator = validator;
      }
      treeSanitizer = _defaultSanitizer;
    } else if (validator != null) {
      throw new ArgumentError(
          'validator can only be passed if treeSanitizer is null');
    }

    if (_parseDocument == null) {
      _parseDocument = document.implementation.createHtmlDocument('');
      _parseRange = _parseDocument.createRange();

      // Workaround for Chrome bug 229142- URIs are not resolved in new doc.
      var base = _parseDocument.createElement('base');
      base.href = document.baseUri;
      _parseDocument.head.append(base);
    }
    var contextElement;
    if (this is BodyElement) {
      contextElement = _parseDocument.body;
    } else {
      contextElement = _parseDocument.createElement(tagName);
      _parseDocument.body.append(contextElement);
    }
    var fragment;
    if (Range.supportsCreateContextualFragment) {
      _parseRange.selectNodeContents(contextElement);
      fragment = _parseRange.createContextualFragment(html);
    } else {
      contextElement._innerHtml = html;

      fragment = _parseDocument.createDocumentFragment();
      while (contextElement.firstChild != null) {
        fragment.append(contextElement.firstChild);
      }
    }
    if (contextElement != _parseDocument.body) {
      contextElement.remove();
    }

    treeSanitizer.sanitizeTree(fragment);
    // Copy the fragment over to the main document (fix for 14184)
    document.adoptNode(fragment);

    return fragment;
  }

  /**
   * Parses the HTML fragment and sets it as the contents of this element.
   *
   * This uses the default sanitization behavior to sanitize the HTML fragment,
   * use [setInnerHtml] to override the default behavior.
   */
  void set innerHtml(String html) {
    this.setInnerHtml(html);
  }

  /**
   * Parses the HTML fragment and sets it as the contents of this element.
   * This ensures that the generated content follows the sanitization rules
   * specified by the validator or treeSanitizer.
   *
   * If the default validation behavior is too restrictive then a new
   * NodeValidator should be created, either extending or wrapping a default
   * validator and overriding the validation APIs.
   *
   * The treeSanitizer is used to walk the generated node tree and sanitize it.
   * A custom treeSanitizer can also be provided to perform special validation
   * rules but since the API is more complex to implement this is discouraged.
   *
   * The resulting tree is guaranteed to only contain nodes and attributes which
   * are allowed by the provided validator.
   *
   * See also:
   *
   * * [NodeValidator]
   * * [NodeTreeSanitizer]
   */
  void setInnerHtml(String html,
    {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    text = null;
    append(createFragment(
        html, validator: validator, treeSanitizer: treeSanitizer));
  }
  String get innerHtml => _innerHtml;

  /**
   * This is an ease-of-use accessor for event streams which should only be
   * used when an explicit accessor is not available.
   */
  ElementEvents get on => new ElementEvents(this);

  @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()
  void 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()
  void 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');

  /**
   * Static factory designed to expose `change` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.changeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> changeEvent = const EventStreamProvider<Event>('change');

  /**
   * Static factory designed to expose `click` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.clickEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> clickEvent = const EventStreamProvider<MouseEvent>('click');

  /**
   * Static factory designed to expose `contextmenu` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.contextmenuEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> contextMenuEvent = const EventStreamProvider<MouseEvent>('contextmenu');

  /**
   * Static factory designed to expose `copy` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.copyEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> copyEvent = const EventStreamProvider<Event>('copy');

  /**
   * Static factory designed to expose `cut` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.cutEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> cutEvent = const EventStreamProvider<Event>('cut');

  /**
   * Static factory designed to expose `doubleclick` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.dblclickEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> doubleClickEvent = const EventStreamProvider<Event>('dblclick');

  /**
   * A stream of `drag` events fired when an element is currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dragEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragEvent = const EventStreamProvider<MouseEvent>('drag');

  /**
   * A stream of `dragend` events fired when an element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dragendEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragEndEvent = const EventStreamProvider<MouseEvent>('dragend');

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over an element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dragenterEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragEnterEvent = const EventStreamProvider<MouseEvent>('dragenter');

  /**
   * A stream of `dragleave` events fired when an object being dragged over an
   * element leaves the element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dragleaveEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragLeaveEvent = const EventStreamProvider<MouseEvent>('dragleave');

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over an element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dragoverEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragOverEvent = const EventStreamProvider<MouseEvent>('dragover');

  /**
   * A stream of `dragstart` events for a dragged element whose drag has begun.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dragstartEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragStartEvent = const EventStreamProvider<MouseEvent>('dragstart');

  /**
   * A stream of `drop` events fired when a dragged object is dropped on an
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dropEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dropEvent = const EventStreamProvider<MouseEvent>('drop');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `focus` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.focusEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> focusEvent = const EventStreamProvider<Event>('focus');

  /**
   * Static factory designed to expose `input` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.inputEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> inputEvent = const EventStreamProvider<Event>('input');

  /**
   * Static factory designed to expose `invalid` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.invalidEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> invalidEvent = const EventStreamProvider<Event>('invalid');

  /**
   * Static factory designed to expose `keydown` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.keydownEvent')
  @DocsEditable()
  static const EventStreamProvider<KeyboardEvent> keyDownEvent = const EventStreamProvider<KeyboardEvent>('keydown');

  /**
   * Static factory designed to expose `keypress` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.keypressEvent')
  @DocsEditable()
  static const EventStreamProvider<KeyboardEvent> keyPressEvent = const EventStreamProvider<KeyboardEvent>('keypress');

  /**
   * Static factory designed to expose `keyup` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.keyupEvent')
  @DocsEditable()
  static const EventStreamProvider<KeyboardEvent> keyUpEvent = const EventStreamProvider<KeyboardEvent>('keyup');

  /**
   * Static factory designed to expose `load` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.loadEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> loadEvent = const EventStreamProvider<Event>('load');

  /**
   * Static factory designed to expose `mousedown` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mousedownEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> mouseDownEvent = const EventStreamProvider<MouseEvent>('mousedown');

  /**
   * Static factory designed to expose `mouseenter` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mouseenterEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseEnterEvent = const EventStreamProvider<MouseEvent>('mouseenter');

  /**
   * Static factory designed to expose `mouseleave` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mouseleaveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseLeaveEvent = const EventStreamProvider<MouseEvent>('mouseleave');

  /**
   * Static factory designed to expose `mousemove` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mousemoveEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> mouseMoveEvent = const EventStreamProvider<MouseEvent>('mousemove');

  /**
   * Static factory designed to expose `mouseout` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mouseoutEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> mouseOutEvent = const EventStreamProvider<MouseEvent>('mouseout');

  /**
   * Static factory designed to expose `mouseover` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mouseoverEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> mouseOverEvent = const EventStreamProvider<MouseEvent>('mouseover');

  /**
   * Static factory designed to expose `mouseup` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mouseupEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> mouseUpEvent = const EventStreamProvider<MouseEvent>('mouseup');

  /**
   * Static factory designed to expose `paste` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.pasteEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> pasteEvent = const EventStreamProvider<Event>('paste');

  /**
   * Static factory designed to expose `reset` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.resetEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> resetEvent = const EventStreamProvider<Event>('reset');

  @DomName('Element.resizeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> resizeEvent = const EventStreamProvider<Event>('resize');

  /**
   * Static factory designed to expose `scroll` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.scrollEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> scrollEvent = const EventStreamProvider<Event>('scroll');

  /**
   * Static factory designed to expose `search` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.searchEvent')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  static const EventStreamProvider<Event> searchEvent = const EventStreamProvider<Event>('search');

  /**
   * Static factory designed to expose `select` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.selectEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> selectEvent = const EventStreamProvider<Event>('select');

  /**
   * Static factory designed to expose `selectstart` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.selectstartEvent')
  @DocsEditable()
  @Experimental() // nonstandard
  static const EventStreamProvider<Event> selectStartEvent = const EventStreamProvider<Event>('selectstart');

  /**
   * Static factory designed to expose `submit` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.submitEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> submitEvent = const EventStreamProvider<Event>('submit');

  /**
   * Static factory designed to expose `touchcancel` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchcancelEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchCancelEvent = const EventStreamProvider<TouchEvent>('touchcancel');

  /**
   * Static factory designed to expose `touchend` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchendEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchEndEvent = const EventStreamProvider<TouchEvent>('touchend');

  /**
   * Static factory designed to expose `touchenter` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchenterEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchEnterEvent = const EventStreamProvider<TouchEvent>('touchenter');

  /**
   * Static factory designed to expose `touchleave` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchleaveEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchLeaveEvent = const EventStreamProvider<TouchEvent>('touchleave');

  /**
   * Static factory designed to expose `touchmove` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchmoveEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchMoveEvent = const EventStreamProvider<TouchEvent>('touchmove');

  /**
   * Static factory designed to expose `touchstart` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchstartEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchStartEvent = const EventStreamProvider<TouchEvent>('touchstart');

  /**
   * Static factory designed to expose `fullscreenchange` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.webkitfullscreenchangeEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  static const EventStreamProvider<Event> fullscreenChangeEvent = const EventStreamProvider<Event>('webkitfullscreenchange');

  /**
   * Static factory designed to expose `fullscreenerror` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.webkitfullscreenerrorEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  static const EventStreamProvider<Event> fullscreenErrorEvent = const EventStreamProvider<Event>('webkitfullscreenerror');

  @DomName('Element.contentEditable')
  @DocsEditable()
  String contentEditable;

  @DomName('Element.dir')
  @DocsEditable()
  String dir;

  /**
   * Indicates whether the element can be dragged and dropped.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.draggable')
  @DocsEditable()
  bool draggable;

  /**
   * Indicates whether the element is not relevant to the page's current state.
   *
   * ## Other resources
   *
   * * [Hidden attribute specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#the-hidden-attribute)
   * from WHATWG.
   */
  @DomName('Element.hidden')
  @DocsEditable()
  bool hidden;

  @DomName('Element.isContentEditable')
  @DocsEditable()
  final bool isContentEditable;

  @DomName('Element.lang')
  @DocsEditable()
  String lang;

  @DomName('Element.spellcheck')
  @DocsEditable()
  // http://blog.whatwg.org/the-road-to-html-5-spellchecking
  @Experimental() // nonstandard
  bool spellcheck;

  @DomName('Element.tabIndex')
  @DocsEditable()
  int tabIndex;

  @DomName('Element.title')
  @DocsEditable()
  String title;

  /**
   * Specifies whether this element's text content changes when the page is
   * localized.
   *
   * ## Other resources
   *
   * * [The translate attribute]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#the-translate-attribute)
   * from WHATWG.
   */
  @DomName('Element.translate')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#the-translate-attribute
  @Experimental()
  bool translate;

  @JSName('webkitdropzone')
  /**
   * A set of space-separated keywords that specify what kind of data this
   * Element accepts on drop and what to do with that data.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.webkitdropzone')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#the-dropzone-attribute
  String dropzone;

  @DomName('Element.click')
  @DocsEditable()
  void click() native;

  @JSName('attributes')
  @DomName('Element.attributes')
  @DocsEditable()
  final _NamedNodeMap _attributes;

  @DomName('Element.className')
  @DocsEditable()
  String className;

  @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()
  int _scrollLeft;

  @JSName('scrollTop')
  @DomName('Element.scrollTop')
  @DocsEditable()
  int _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.animate')
  @DocsEditable()
  @Experimental() // untriaged
  Animation animate(List<Map> keyframes, [timingInput]) {
    if ((timingInput is Map || timingInput == null)) {
      var timingInput_1 = convertDartToNative_Dictionary(timingInput);
      return _animate_1(keyframes, timingInput_1);
    }
    if ((timingInput is num || timingInput == null)) {
      return _animate_2(keyframes, timingInput);
    }
    if (timingInput == null) {
      return _animate_3(keyframes);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  @JSName('animate')
  @DomName('Element.animate')
  @DocsEditable()
  @Experimental() // untriaged
  Animation _animate_1(List<Map> keyframes, timingInput) native;
  @JSName('animate')
  @DomName('Element.animate')
  @DocsEditable()
  @Experimental() // untriaged
  Animation _animate_2(List<Map> keyframes, num timingInput) native;
  @JSName('animate')
  @DomName('Element.animate')
  @DocsEditable()
  @Experimental() // untriaged
  Animation _animate_3(List<Map> keyframes) native;

  @DomName('Element.blur')
  @DocsEditable()
  void blur() native;

  @DomName('Element.focus')
  @DocsEditable()
  void focus() native;

  @DomName('Element.getAttribute')
  @DocsEditable()
  @Experimental() // untriaged
  String getAttribute(String name) native;

  @DomName('Element.getAttributeNS')
  @DocsEditable()
  @Experimental() // untriaged
  String getAttributeNS(String namespaceURI, String localName) native;

  /**
   * Returns the smallest bounding rectangle that encompasses this element's
   * padding, scrollbar, and border.
   *
   * ## Other resources
   *
   * * [Element.getBoundingClientRect]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect)
   * from MDN.
   * * [The getBoundingClientRect() method]
   * (http://www.w3.org/TR/cssom-view/#the-getclientrects-and-getboundingclientrect-methods)
   * from W3C.
   */
  @DomName('Element.getBoundingClientRect')
  @DocsEditable()
  Rectangle getBoundingClientRect() native;

  /**
   * Returns a list of bounding rectangles for each box associated with this
   * element.
   *
   * ## Other resources
   *
   * * [Element.getClientRects]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Element.getClientRects)
   * from MDN.
   * * [The getClientRects() method]
   * (http://www.w3.org/TR/cssom-view/#the-getclientrects-and-getboundingclientrect-methods)
   * from W3C.
   */
  @DomName('Element.getClientRects')
  @DocsEditable()
  @Returns('_ClientRectList')
  @Creates('_ClientRectList')
  List<Rectangle> getClientRects() native;

  /**
   * Returns a list of shadow DOM insertion points to which this element is
   * distributed.
   *
   * ## Other resources
   *
   * * [Shadow DOM specification]
   * (https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html)
   * from W3C.
   */
  @DomName('Element.getDestinationInsertionPoints')
  @DocsEditable()
  @Experimental() // untriaged
  @Returns('NodeList')
  @Creates('NodeList')
  List<Node> getDestinationInsertionPoints() native;

  /**
   * Returns a list of nodes with the given class name inside this element.
   *
   * ## Other resources
   *
   * * [getElementsByClassName]
   * (https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByClassName)
   * from MDN.
   * * [DOM specification]
   * (http://www.w3.org/TR/domcore/) from W3C.
   */
  @DomName('Element.getElementsByClassName')
  @DocsEditable()
  @Creates('NodeList|HtmlCollection')
  @Returns('NodeList|HtmlCollection')
  List<Node> getElementsByClassName(String classNames) native;

  @JSName('getElementsByTagName')
  @DomName('Element.getElementsByTagName')
  @DocsEditable()
  @Creates('NodeList|HtmlCollection')
  @Returns('NodeList|HtmlCollection')
  List<Node> _getElementsByTagName(String name) native;

  @JSName('hasAttribute')
  @DomName('Element.hasAttribute')
  @DocsEditable()
  bool _hasAttribute(String name) native;

  @JSName('hasAttributeNS')
  @DomName('Element.hasAttributeNS')
  @DocsEditable()
  bool _hasAttributeNS(String namespaceURI, String localName) native;

  /**
   * Finds the first descendant element of this element that matches the
   * specified group of selectors.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     // Gets the first descendant with the class 'classname'
   *     var element = element.querySelector('.className');
   *     // Gets the element with id 'id'
   *     var element = element.querySelector('#id');
   *     // Gets the first descendant [ImageElement]
   *     var img = element.querySelector('img');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  @DomName('Element.querySelector')
  @DocsEditable()
  Element querySelector(String selectors) native;

  @JSName('querySelectorAll')
  @DomName('Element.querySelectorAll')
  @DocsEditable()
  @Returns('NodeList')
  @Creates('NodeList')
  List<Node> _querySelectorAll(String selectors) native;

  @JSName('removeAttribute')
  @DomName('Element.removeAttribute')
  @DocsEditable()
  void _removeAttribute(String name) native;

  @JSName('removeAttributeNS')
  @DomName('Element.removeAttributeNS')
  @DocsEditable()
  void _removeAttributeNS(String namespaceURI, String localName) native;

  /**
   * Scrolls the element by a number of lines.
   *
   * ## Other resources
   *
   * * [scrollByLines]
   * (http://docs.webplatform.org/wiki/dom/methods/scrollByLines) from WebPlatform.org.
   */
  @DomName('Element.scrollByLines')
  @DocsEditable()
  void scrollByLines(int lines) native;

  /**
   * Scrolls the element by a number of pages.
   *
   * ## Other resources
   *
   * * [scrollByPages]
   * (http://docs.webplatform.org/wiki/dom/methods/scrollByPages) from WebPlatform.org.
   */
  @DomName('Element.scrollByPages')
  @DocsEditable()
  void scrollByPages(int pages) native;

  @JSName('scrollIntoView')
  @DomName('Element.scrollIntoView')
  @DocsEditable()
  void _scrollIntoView([bool alignWithTop]) native;

  @JSName('scrollIntoViewIfNeeded')
  @DomName('Element.scrollIntoViewIfNeeded')
  @DocsEditable()
  // http://docs.webplatform.org/wiki/dom/methods/scrollIntoViewIfNeeded
  @Experimental() // non-standard
  void _scrollIntoViewIfNeeded([bool centerIfNeeded]) native;

  @DomName('Element.setAttribute')
  @DocsEditable()
  void setAttribute(String name, String value) native;

  @DomName('Element.setAttributeNS')
  @DocsEditable()
  void setAttributeNS(String namespaceURI, String qualifiedName, String value) native;

  @JSName('webkitRequestFullscreen')
  /**
   * Displays this element fullscreen.
   *
   * ## Other resources
   *
   * * [Using the fullscreen API]
   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)
   * tutorial from WebPlatform.org.
   * * [Fullscreen specification]
   * (http://www.w3.org/TR/fullscreen/) from W3C.
   */
  @DomName('Element.webkitRequestFullscreen')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#dom-element-requestfullscreen
  void requestFullscreen() native;

  @JSName('webkitRequestPointerLock')
  /**
   * Locks the mouse pointer to this element.
   *
   * ## Other resources
   *
   * * [Pointer lock and first person shooter controls]
   * (http://www.html5rocks.com/en/tutorials/pointerlock/intro/) tutorial from
   * HTML5Rocks.
   *
   * * [Pointer lock specification]
   * (http://www.w3.org/TR/pointerlock/) from W3C.
   */
  @DomName('Element.webkitRequestPointerLock')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html#widl-Element-requestPointerLock-void
  void requestPointerLock() native;

  // From ChildNode

  @DomName('Element.nextElementSibling')
  @DocsEditable()
  final Element nextElementSibling;

  @DomName('Element.previousElementSibling')
  @DocsEditable()
  final Element previousElementSibling;

  // From ParentNode

  @JSName('childElementCount')
  @DomName('Element.childElementCount')
  @DocsEditable()
  final int _childElementCount;

  @JSName('children')
  @DomName('Element.children')
  @DocsEditable()
  @Returns('HtmlCollection')
  @Creates('HtmlCollection')
  final List<Node> _children;

  @JSName('firstElementChild')
  @DomName('Element.firstElementChild')
  @DocsEditable()
  final Element _firstElementChild;

  @JSName('lastElementChild')
  @DomName('Element.lastElementChild')
  @DocsEditable()
  final Element _lastElementChild;

  /// Stream of `abort` events handled by this [Element].
  @DomName('Element.onabort')
  @DocsEditable()
  ElementStream<Event> get onAbort => abortEvent.forElement(this);

  /// Stream of `beforecopy` events handled by this [Element].
  @DomName('Element.onbeforecopy')
  @DocsEditable()
  ElementStream<Event> get onBeforeCopy => beforeCopyEvent.forElement(this);

  /// Stream of `beforecut` events handled by this [Element].
  @DomName('Element.onbeforecut')
  @DocsEditable()
  ElementStream<Event> get onBeforeCut => beforeCutEvent.forElement(this);

  /// Stream of `beforepaste` events handled by this [Element].
  @DomName('Element.onbeforepaste')
  @DocsEditable()
  ElementStream<Event> get onBeforePaste => beforePasteEvent.forElement(this);

  /// Stream of `blur` events handled by this [Element].
  @DomName('Element.onblur')
  @DocsEditable()
  ElementStream<Event> get onBlur => blurEvent.forElement(this);

  /// Stream of `change` events handled by this [Element].
  @DomName('Element.onchange')
  @DocsEditable()
  ElementStream<Event> get onChange => changeEvent.forElement(this);

  /// Stream of `click` events handled by this [Element].
  @DomName('Element.onclick')
  @DocsEditable()
  ElementStream<MouseEvent> get onClick => clickEvent.forElement(this);

  /// Stream of `contextmenu` events handled by this [Element].
  @DomName('Element.oncontextmenu')
  @DocsEditable()
  ElementStream<MouseEvent> get onContextMenu => contextMenuEvent.forElement(this);

  /// Stream of `copy` events handled by this [Element].
  @DomName('Element.oncopy')
  @DocsEditable()
  ElementStream<Event> get onCopy => copyEvent.forElement(this);

  /// Stream of `cut` events handled by this [Element].
  @DomName('Element.oncut')
  @DocsEditable()
  ElementStream<Event> get onCut => cutEvent.forElement(this);

  /// Stream of `doubleclick` events handled by this [Element].
  @DomName('Element.ondblclick')
  @DocsEditable()
  ElementStream<Event> get onDoubleClick => doubleClickEvent.forElement(this);

  /**
   * A stream of `drag` events fired when this element currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondrag')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrag => dragEvent.forElement(this);

  /**
   * A stream of `dragend` events fired when this element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragend')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnd => dragEndEvent.forElement(this);

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragenter')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnter => dragEnterEvent.forElement(this);

  /**
   * A stream of `dragleave` events fired when an object being dragged over this
   * element leaves this element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragleave')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragLeave => dragLeaveEvent.forElement(this);

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragover')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragOver => dragOverEvent.forElement(this);

  /**
   * A stream of `dragstart` events fired when this element starts being
   * dragged.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragstart')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragStart => dragStartEvent.forElement(this);

  /**
   * A stream of `drop` events fired when a dragged object is dropped on this
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondrop')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrop => dropEvent.forElement(this);

  /// Stream of `error` events handled by this [Element].
  @DomName('Element.onerror')
  @DocsEditable()
  ElementStream<Event> get onError => errorEvent.forElement(this);

  /// Stream of `focus` events handled by this [Element].
  @DomName('Element.onfocus')
  @DocsEditable()
  ElementStream<Event> get onFocus => focusEvent.forElement(this);

  /// Stream of `input` events handled by this [Element].
  @DomName('Element.oninput')
  @DocsEditable()
  ElementStream<Event> get onInput => inputEvent.forElement(this);

  /// Stream of `invalid` events handled by this [Element].
  @DomName('Element.oninvalid')
  @DocsEditable()
  ElementStream<Event> get onInvalid => invalidEvent.forElement(this);

  /// Stream of `keydown` events handled by this [Element].
  @DomName('Element.onkeydown')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyDown => keyDownEvent.forElement(this);

  /// Stream of `keypress` events handled by this [Element].
  @DomName('Element.onkeypress')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyPress => keyPressEvent.forElement(this);

  /// Stream of `keyup` events handled by this [Element].
  @DomName('Element.onkeyup')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyUp => keyUpEvent.forElement(this);

  /// Stream of `load` events handled by this [Element].
  @DomName('Element.onload')
  @DocsEditable()
  ElementStream<Event> get onLoad => loadEvent.forElement(this);

  /// Stream of `mousedown` events handled by this [Element].
  @DomName('Element.onmousedown')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseDown => mouseDownEvent.forElement(this);

  /// Stream of `mouseenter` events handled by this [Element].
  @DomName('Element.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseEnter => mouseEnterEvent.forElement(this);

  /// Stream of `mouseleave` events handled by this [Element].
  @DomName('Element.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseLeave => mouseLeaveEvent.forElement(this);

  /// Stream of `mousemove` events handled by this [Element].
  @DomName('Element.onmousemove')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseMove => mouseMoveEvent.forElement(this);

  /// Stream of `mouseout` events handled by this [Element].
  @DomName('Element.onmouseout')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOut => mouseOutEvent.forElement(this);

  /// Stream of `mouseover` events handled by this [Element].
  @DomName('Element.onmouseover')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOver => mouseOverEvent.forElement(this);

  /// Stream of `mouseup` events handled by this [Element].
  @DomName('Element.onmouseup')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseUp => mouseUpEvent.forElement(this);

  /// Stream of `mousewheel` events handled by this [Element].
  @DomName('Element.onmousewheel')
  @DocsEditable()
  // http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents
  @Experimental() // non-standard
  ElementStream<WheelEvent> get onMouseWheel => mouseWheelEvent.forElement(this);

  /// Stream of `paste` events handled by this [Element].
  @DomName('Element.onpaste')
  @DocsEditable()
  ElementStream<Event> get onPaste => pasteEvent.forElement(this);

  /// Stream of `reset` events handled by this [Element].
  @DomName('Element.onreset')
  @DocsEditable()
  ElementStream<Event> get onReset => resetEvent.forElement(this);

  @DomName('Element.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onResize => resizeEvent.forElement(this);

  /// Stream of `scroll` events handled by this [Element].
  @DomName('Element.onscroll')
  @DocsEditable()
  ElementStream<Event> get onScroll => scrollEvent.forElement(this);

  /// Stream of `search` events handled by this [Element].
  @DomName('Element.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  ElementStream<Event> get onSearch => searchEvent.forElement(this);

  /// Stream of `select` events handled by this [Element].
  @DomName('Element.onselect')
  @DocsEditable()
  ElementStream<Event> get onSelect => selectEvent.forElement(this);

  /// Stream of `selectstart` events handled by this [Element].
  @DomName('Element.onselectstart')
  @DocsEditable()
  @Experimental() // nonstandard
  ElementStream<Event> get onSelectStart => selectStartEvent.forElement(this);

  /// Stream of `submit` events handled by this [Element].
  @DomName('Element.onsubmit')
  @DocsEditable()
  ElementStream<Event> get onSubmit => submitEvent.forElement(this);

  /// Stream of `touchcancel` events handled by this [Element].
  @DomName('Element.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchCancel => touchCancelEvent.forElement(this);

  /// Stream of `touchend` events handled by this [Element].
  @DomName('Element.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnd => touchEndEvent.forElement(this);

  /// Stream of `touchenter` events handled by this [Element].
  @DomName('Element.ontouchenter')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnter => touchEnterEvent.forElement(this);

  /// Stream of `touchleave` events handled by this [Element].
  @DomName('Element.ontouchleave')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchLeave => touchLeaveEvent.forElement(this);

  /// Stream of `touchmove` events handled by this [Element].
  @DomName('Element.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchMove => touchMoveEvent.forElement(this);

  /// Stream of `touchstart` events handled by this [Element].
  @DomName('Element.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchStart => touchStartEvent.forElement(this);

  /// Stream of `transitionend` events handled by this [Element].
  @DomName('Element.ontransitionend')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  ElementStream<TransitionEvent> get onTransitionEnd => transitionEndEvent.forElement(this);

  /// Stream of `fullscreenchange` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenchange')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenChange => fullscreenChangeEvent.forElement(this);

  /// Stream of `fullscreenerror` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenError => fullscreenErrorEvent.forElement(this);

}


class _ElementFactoryProvider {

  @DomName('Document.createElement')
  // Optimization to improve performance until the dart2js compiler inlines this
  // method.
  static dynamic createElement_tag(String tag, String typeExtension) {
    // Firefox may return a JS function for some types (Embed, Object).
    if (typeExtension != null) {
      return JS('Element|=Object', 'document.createElement(#, #)',
          tag, typeExtension);
    }
    // Should be able to eliminate this and just call the two-arg version above
    // with null typeExtension, but Chrome treats the tag as case-sensitive if
    // typeExtension is null.
    // https://code.google.com/p/chromium/issues/detail?id=282467
    return JS('Element|=Object', 'document.createElement(#)', tag);
  }

}


/**
 * Options for Element.scrollIntoView.
 */
class ScrollAlignment {
  final _value;
  const ScrollAlignment._internal(this._value);
  toString() => 'ScrollAlignment.$_value';

  /// Attempt to align the element to the top of the scrollable area.
  static const TOP = const ScrollAlignment._internal('TOP');
  /// Attempt to center the element in the scrollable area.
  static const CENTER = const ScrollAlignment._internal('CENTER');
  /// Attempt to align the element to the bottom of the scrollable area.
  static const BOTTOM = const ScrollAlignment._internal('BOTTOM');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLEmbedElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
class EmbedElement extends HtmlElement native "HTMLEmbedElement" {
  // To suppress missing implicit constructor warnings.
  factory EmbedElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLEmbedElement.HTMLEmbedElement')
  @DocsEditable()
  factory EmbedElement() => document.createElement("embed");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  EmbedElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('embed');

  @DomName('HTMLEmbedElement.height')
  @DocsEditable()
  String height;

  @DomName('HTMLEmbedElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLEmbedElement.src')
  @DocsEditable()
  String src;

  @DomName('HTMLEmbedElement.type')
  @DocsEditable()
  String type;

  @DomName('HTMLEmbedElement.width')
  @DocsEditable()
  String width;

  @DomName('HTMLEmbedElement.__getter__')
  @DocsEditable()
  bool __getter__(index_OR_name) native;

  @DomName('HTMLEmbedElement.__setter__')
  @DocsEditable()
  void __setter__(index_OR_name, Node value) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('EntriesCallback')
// http://www.w3.org/TR/file-system-api/#the-entriescallback-interface
@Experimental()
typedef void _EntriesCallback(List<Entry> entries);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('Entry')
// http://www.w3.org/TR/file-system-api/#the-entry-interface
@Experimental()
class Entry extends Interceptor native "Entry" {
  // To suppress missing implicit constructor warnings.
  factory Entry._() { throw new UnsupportedError("Not supported"); }

  @DomName('Entry.filesystem')
  @DocsEditable()
  final FileSystem filesystem;

  @DomName('Entry.fullPath')
  @DocsEditable()
  final String fullPath;

  @DomName('Entry.isDirectory')
  @DocsEditable()
  final bool isDirectory;

  @DomName('Entry.isFile')
  @DocsEditable()
  final bool isFile;

  @DomName('Entry.name')
  @DocsEditable()
  final String name;

  @JSName('copyTo')
  @DomName('Entry.copyTo')
  @DocsEditable()
  void _copyTo(DirectoryEntry parent, {String name, _EntryCallback successCallback, _ErrorCallback errorCallback}) native;

  @JSName('copyTo')
  @DomName('Entry.copyTo')
  @DocsEditable()
  Future<Entry> copyTo(DirectoryEntry parent, {String name}) {
    var completer = new Completer<Entry>();
    _copyTo(parent, name : name,
        successCallback : (value) { completer.complete(value); },
        errorCallback : (error) { completer.completeError(error); });
    return completer.future;
  }

  @JSName('getMetadata')
  @DomName('Entry.getMetadata')
  @DocsEditable()
  void _getMetadata(MetadataCallback successCallback, [_ErrorCallback errorCallback]) native;

  @JSName('getMetadata')
  @DomName('Entry.getMetadata')
  @DocsEditable()
  Future<Metadata> getMetadata() {
    var completer = new Completer<Metadata>();
    _getMetadata(
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  @JSName('getParent')
  @DomName('Entry.getParent')
  @DocsEditable()
  void _getParent([_EntryCallback successCallback, _ErrorCallback errorCallback]) native;

  @JSName('getParent')
  @DomName('Entry.getParent')
  @DocsEditable()
  Future<Entry> getParent() {
    var completer = new Completer<Entry>();
    _getParent(
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  @JSName('moveTo')
  @DomName('Entry.moveTo')
  @DocsEditable()
  void _moveTo(DirectoryEntry parent, {String name, _EntryCallback successCallback, _ErrorCallback errorCallback}) native;

  @JSName('moveTo')
  @DomName('Entry.moveTo')
  @DocsEditable()
  Future<Entry> moveTo(DirectoryEntry parent, {String name}) {
    var completer = new Completer<Entry>();
    _moveTo(parent, name : name,
        successCallback : (value) { completer.complete(value); },
        errorCallback : (error) { completer.completeError(error); });
    return completer.future;
  }

  @JSName('remove')
  @DomName('Entry.remove')
  @DocsEditable()
  void _remove(VoidCallback successCallback, [_ErrorCallback errorCallback]) native;

  @JSName('remove')
  @DomName('Entry.remove')
  @DocsEditable()
  Future remove() {
    var completer = new Completer();
    _remove(
        () { completer.complete(); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  @JSName('toURL')
  @DomName('Entry.toURL')
  @DocsEditable()
  String toUrl() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('EntryCallback')
// http://www.w3.org/TR/file-system-api/#the-entrycallback-interface
@Experimental()
typedef void _EntryCallback(Entry entry);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('ErrorCallback')
// http://www.w3.org/TR/file-system-api/#the-errorcallback-interface
@Experimental()
typedef void _ErrorCallback(FileError error);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('ErrorEvent')
@Unstable()
class ErrorEvent extends Event native "ErrorEvent" {
  // To suppress missing implicit constructor warnings.
  factory ErrorEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('ErrorEvent.colno')
  @DocsEditable()
  @Experimental() // untriaged
  final int colno;

  @DomName('ErrorEvent.error')
  @DocsEditable()
  @Experimental() // untriaged
  @Creates('Null')
  final Object error;

  @DomName('ErrorEvent.filename')
  @DocsEditable()
  final String filename;

  @DomName('ErrorEvent.lineno')
  @DocsEditable()
  final int lineno;

  @DomName('ErrorEvent.message')
  @DocsEditable()
  final String message;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('Event')
class Event extends Interceptor native "Event,InputEvent" {
  // In JS, canBubble and cancelable are technically required parameters to
  // init*Event. In practice, though, if they aren't provided they simply
  // default to false (since that's Boolean(undefined)).
  //
  // Contrary to JS, we default canBubble and cancelable to true, since that's
  // what people want most of the time anyway.
  factory Event(String type,
      {bool canBubble: true, bool cancelable: true}) {
    return new Event.eventType('Event', type, canBubble: canBubble,
        cancelable: cancelable);
  }

  /**
   * Creates a new Event object of the specified type.
   *
   * This is analogous to document.createEvent.
   * Normally events should be created via their constructors, if available.
   *
   *     var e = new Event.type('MouseEvent', 'mousedown', true, true);
   */
  factory Event.eventType(String type, String name, {bool canBubble: true,
      bool cancelable: true}) {
    final Event e = document._createEvent(type);
    e._initEvent(name, canBubble, cancelable);
    return e;
  }
  
  /** The CSS selector involved with event delegation. */
  String _selector;

  /**
   * A pointer to the element whose CSS selector matched within which an event
   * was fired. If this Event was not associated with any Event delegation,
   * accessing this value will throw an [UnsupportedError].
   */
  Element get matchingTarget {
    if (_selector == null) {
      throw new UnsupportedError('Cannot call matchingTarget if this Event did'
          ' not arise as a result of event delegation.');
    }
    var currentTarget = this.currentTarget;
    var target = this.target;
    var matchedTarget;
    do {
      if (target.matches(_selector)) return target;
      target = target.parent;
    } while (target != null && target != currentTarget.parent);
    throw new StateError('No selector matched for populating matchedTarget.');
  }
  // To suppress missing implicit constructor warnings.
  factory Event._() { throw new UnsupportedError("Not supported"); }

  /**
   * This event is being handled by the event target.
   *
   * ## Other resources
   *
   * * [Target phase] (http://www.w3.org/TR/DOM-Level-3-Events/#target-phase)
   * from W3C.
   */
  @DomName('Event.AT_TARGET')
  @DocsEditable()
  static const int AT_TARGET = 2;

  /**
   * This event is bubbling up through the target's ancestors.
   *
   * ## Other resources
   *
   * * [Bubble phase] (http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
   * from W3C.
   */
  @DomName('Event.BUBBLING_PHASE')
  @DocsEditable()
  static const int BUBBLING_PHASE = 3;

  /**
   * This event is propagating through the target's ancestors, starting from the
   * document.
   *
   * ## Other resources
   *
   * * [Bubble phase] (http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
   * from W3C.
   */
  @DomName('Event.CAPTURING_PHASE')
  @DocsEditable()
  static const int CAPTURING_PHASE = 1;

  @DomName('Event.bubbles')
  @DocsEditable()
  final bool bubbles;

  @DomName('Event.cancelable')
  @DocsEditable()
  final bool cancelable;

  /**
   * Access to the system's clipboard data during copy, cut, and paste events.
   *
   * ## Other resources
   *
   * * [clipboardData specification]
   * (http://www.w3.org/TR/clipboard-apis/#attributes) from W3C.
   */
  @DomName('Event.clipboardData')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // Part of copy/paste
  @Experimental() // nonstandard
  final DataTransfer clipboardData;

  @DomName('Event.currentTarget')
  @DocsEditable()
  EventTarget get currentTarget => _convertNativeToDart_EventTarget(this._get_currentTarget);
  @JSName('currentTarget')
  @DomName('Event.currentTarget')
  @DocsEditable()
  @Creates('Null')
  @Returns('EventTarget|=Object')
  final dynamic _get_currentTarget;

  @DomName('Event.defaultPrevented')
  @DocsEditable()
  final bool defaultPrevented;

  @DomName('Event.eventPhase')
  @DocsEditable()
  final int eventPhase;

  /**
   * This event's path, taking into account shadow DOM.
   *
   * ## Other resources
   *
   * * [Shadow DOM extensions to Event]
   * (http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event) from
   * W3C.
   */
  @DomName('Event.path')
  @DocsEditable()
  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#extensions-to-event
  @Experimental()
  @Returns('NodeList')
  @Creates('NodeList')
  final List<Node> path;

  @DomName('Event.target')
  @DocsEditable()
  EventTarget get target => _convertNativeToDart_EventTarget(this._get_target);
  @JSName('target')
  @DomName('Event.target')
  @DocsEditable()
  @Creates('Node')
  @Returns('EventTarget|=Object')
  final dynamic _get_target;

  @DomName('Event.timeStamp')
  @DocsEditable()
  final int timeStamp;

  @DomName('Event.type')
  @DocsEditable()
  final String type;

  @JSName('initEvent')
  @DomName('Event.initEvent')
  @DocsEditable()
  void _initEvent(String eventTypeArg, bool canBubbleArg, bool cancelableArg) native;

  @DomName('Event.preventDefault')
  @DocsEditable()
  void preventDefault() native;

  @DomName('Event.stopImmediatePropagation')
  @DocsEditable()
  void stopImmediatePropagation() native;

  @DomName('Event.stopPropagation')
  @DocsEditable()
  void stopPropagation() native;

}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('EventSource')
// http://www.w3.org/TR/eventsource/#the-eventsource-interface
@Experimental() // stable
class EventSource extends EventTarget native "EventSource" {
  factory EventSource(String title, {withCredentials: false}) {
    var parsedOptions = {
      'withCredentials': withCredentials,
    };
    return EventSource._factoryEventSource(title, parsedOptions);
  }
  // To suppress missing implicit constructor warnings.
  factory EventSource._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [EventSource].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('EventSource.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [EventSource].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('EventSource.messageEvent')
  @DocsEditable()
  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');

  /**
   * Static factory designed to expose `open` events to event
   * handlers that are not necessarily instances of [EventSource].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('EventSource.openEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> openEvent = const EventStreamProvider<Event>('open');

  @DomName('EventSource.EventSource')
  @DocsEditable()
  static EventSource _factoryEventSource(String url, [Map eventSourceInit]) {
    if (eventSourceInit != null) {
      return EventSource._create_1(url, eventSourceInit);
    }
    return EventSource._create_2(url);
  }
  static EventSource _create_1(url, eventSourceInit) => JS('EventSource', 'new EventSource(#,#)', url, eventSourceInit);
  static EventSource _create_2(url) => JS('EventSource', 'new EventSource(#)', url);

  @DomName('EventSource.CLOSED')
  @DocsEditable()
  static const int CLOSED = 2;

  @DomName('EventSource.CONNECTING')
  @DocsEditable()
  static const int CONNECTING = 0;

  @DomName('EventSource.OPEN')
  @DocsEditable()
  static const int OPEN = 1;

  @DomName('EventSource.readyState')
  @DocsEditable()
  final int readyState;

  @DomName('EventSource.url')
  @DocsEditable()
  final String url;

  @DomName('EventSource.withCredentials')
  @DocsEditable()
  final bool withCredentials;

  @DomName('EventSource.close')
  @DocsEditable()
  void close() native;

  /// Stream of `error` events handled by this [EventSource].
  @DomName('EventSource.onerror')
  @DocsEditable()
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `message` events handled by this [EventSource].
  @DomName('EventSource.onmessage')
  @DocsEditable()
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  /// Stream of `open` events handled by this [EventSource].
  @DomName('EventSource.onopen')
  @DocsEditable()
  Stream<Event> get onOpen => openEvent.forTarget(this);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * Base class that supports listening for and dispatching browser events.
 *
 * Normally events are accessed via the Stream getter:
 *
 *     element.onMouseOver.listen((e) => print('Mouse over!'));
 *
 * To access bubbling events which are declared on one element, but may bubble
 * up to another element type (common for MediaElement events):
 *
 *     MediaElement.pauseEvent.forTarget(document.body).listen(...);
 *
 * To useCapture on events:
 *
 *     Element.keyDownEvent.forTarget(element, useCapture: true).listen(...);
 *
 * Custom events can be declared as:
 *
 *    class DataGenerator {
 *      static EventStreamProvider<Event> dataEvent =
 *          new EventStreamProvider('data');
 *    }
 *
 * Then listeners should access the event with:
 *
 *     DataGenerator.dataEvent.forTarget(element).listen(...);
 *
 * Custom events can also be accessed as:
 *
 *     element.on['some_event'].listen(...);
 *
 * This approach is generally discouraged as it loses the event typing and
 * some DOM events may have multiple platform-dependent event names under the
 * covers. By using the standard Stream getters you will get the platform
 * specific event name automatically.
 */
class Events {
  /* Raw event target. */
  final EventTarget _ptr;

  Events(this._ptr);

  Stream operator [](String type) {
    return new _EventStream(_ptr, type, false);
  }
}

class ElementEvents extends Events {
  /* Raw event target. */
  final Element _ptr;
  static final webkitEvents = {
    'animationend' : 'webkitAnimationEnd', 
    'animationiteration' : 'webkitAnimationIteration', 
    'animationstart' : 'webkitAnimationStart', 
    'fullscreenchange' : 'webkitfullscreenchange', 
    'fullscreenerror' : 'webkitfullscreenerror',
    'keyadded' : 'webkitkeyadded', 
    'keyerror' : 'webkitkeyerror', 
    'keymessage' : 'webkitkeymessage', 
    'needkey' : 'webkitneedkey', 
    'pointerlockchange' : 'webkitpointerlockchange', 
    'pointerlockerror' : 'webkitpointerlockerror', 
    'resourcetimingbufferfull' : 'webkitresourcetimingbufferfull', 
    'transitionend': 'webkitTransitionEnd',
    'speechchange' : 'webkitSpeechChange'
  };

  ElementEvents(Element ptr) : this._ptr = ptr, super(ptr);

  Stream operator [](String type) {
    if (webkitEvents.keys.contains(type.toLowerCase())) {
      if (Device.isWebKit) {
        return new _ElementEventStreamImpl(
            _ptr, webkitEvents[type.toLowerCase()], false);
      }
    }
    return new _ElementEventStreamImpl(_ptr, type, false);
  }
}

/**
 * Base class for all browser objects that support events.
 *
 * Use the [on] property to add, and remove events
 * for compile-time type checks and a more concise API.
 */
@DomName('EventTarget')
class EventTarget extends Interceptor native "EventTarget" {

  // Custom element created callback.
  EventTarget._created();

  /**
   * This is an ease-of-use accessor for event streams which should only be
   * used when an explicit accessor is not available.
   */
  Events get on => new Events(this);
  // To suppress missing implicit constructor warnings.
  factory EventTarget._() { throw new UnsupportedError("Not supported"); }

  @DomName('EventTarget.addEventListener')
  @DocsEditable()
  void addEventListener(String type, EventListener listener, [bool useCapture]) native;

  @DomName('EventTarget.dispatchEvent')
  @DocsEditable()
  bool dispatchEvent(Event event) native;

  @DomName('EventTarget.removeEventListener')
  @DocsEditable()
  void removeEventListener(String type, EventListener listener, [bool useCapture]) native;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLFieldSetElement')
@Unstable()
class FieldSetElement extends HtmlElement native "HTMLFieldSetElement" {
  // To suppress missing implicit constructor warnings.
  factory FieldSetElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLFieldSetElement.HTMLFieldSetElement')
  @DocsEditable()
  factory FieldSetElement() => document.createElement("fieldset");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  FieldSetElement.created() : super.created();

  @DomName('HTMLFieldSetElement.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('HTMLFieldSetElement.elements')
  @DocsEditable()
  @Returns('HtmlCollection')
  @Creates('HtmlCollection')
  final List<Node> elements;

  @DomName('HTMLFieldSetElement.form')
  @DocsEditable()
  final FormElement form;

  @DomName('HTMLFieldSetElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLFieldSetElement.type')
  @DocsEditable()
  final String type;

  @DomName('HTMLFieldSetElement.validationMessage')
  @DocsEditable()
  final String validationMessage;

  @DomName('HTMLFieldSetElement.validity')
  @DocsEditable()
  final ValidityState validity;

  @DomName('HTMLFieldSetElement.willValidate')
  @DocsEditable()
  final bool willValidate;

  @DomName('HTMLFieldSetElement.checkValidity')
  @DocsEditable()
  bool checkValidity() native;

  @DomName('HTMLFieldSetElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('File')
class File extends Blob native "File" {
  // To suppress missing implicit constructor warnings.
  factory File._() { throw new UnsupportedError("Not supported"); }

  @DomName('File.lastModified')
  @DocsEditable()
  @Experimental() // untriaged
  final int lastModified;

  @DomName('File.lastModifiedDate')
  @DocsEditable()
  DateTime get lastModifiedDate => convertNativeToDart_DateTime(this._get_lastModifiedDate);
  @JSName('lastModifiedDate')
  @DomName('File.lastModifiedDate')
  @DocsEditable()
  @Creates('Null')
  final dynamic _get_lastModifiedDate;

  @DomName('File.name')
  @DocsEditable()
  final String name;

  @JSName('webkitRelativePath')
  @DomName('File.webkitRelativePath')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://plus.sandbox.google.com/+AddyOsmani/posts/Dk5UhZ6zfF3
  final String relativePath;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('FileCallback')
// http://www.w3.org/TR/file-system-api/#the-filecallback-interface
@Experimental()
typedef void _FileCallback(File file);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('FileEntry')
// http://www.w3.org/TR/file-system-api/#the-fileentry-interface
@Experimental()
class FileEntry extends Entry native "FileEntry" {
  // To suppress missing implicit constructor warnings.
  factory FileEntry._() { throw new UnsupportedError("Not supported"); }

  @JSName('createWriter')
  @DomName('FileEntry.createWriter')
  @DocsEditable()
  void _createWriter(_FileWriterCallback successCallback, [_ErrorCallback errorCallback]) native;

  @JSName('createWriter')
  @DomName('FileEntry.createWriter')
  @DocsEditable()
  Future<FileWriter> createWriter() {
    var completer = new Completer<FileWriter>();
    _createWriter(
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  @JSName('file')
  @DomName('FileEntry.file')
  @DocsEditable()
  void _file(_FileCallback successCallback, [_ErrorCallback errorCallback]) native;

  @JSName('file')
  @DomName('FileEntry.file')
  @DocsEditable()
  Future<File> file() {
    var completer = new Completer<File>();
    _file(
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); });
    return completer.future;
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('FileError')
// http://dev.w3.org/2009/dap/file-system/pub/FileSystem/
@Experimental()
class FileError extends DomError native "FileError" {
  // To suppress missing implicit constructor warnings.
  factory FileError._() { throw new UnsupportedError("Not supported"); }

  @DomName('FileError.ABORT_ERR')
  @DocsEditable()
  static const int ABORT_ERR = 3;

  @DomName('FileError.ENCODING_ERR')
  @DocsEditable()
  static const int ENCODING_ERR = 5;

  @DomName('FileError.INVALID_MODIFICATION_ERR')
  @DocsEditable()
  static const int INVALID_MODIFICATION_ERR = 9;

  @DomName('FileError.INVALID_STATE_ERR')
  @DocsEditable()
  static const int INVALID_STATE_ERR = 7;

  @DomName('FileError.NOT_FOUND_ERR')
  @DocsEditable()
  static const int NOT_FOUND_ERR = 1;

  @DomName('FileError.NOT_READABLE_ERR')
  @DocsEditable()
  static const int NOT_READABLE_ERR = 4;

  @DomName('FileError.NO_MODIFICATION_ALLOWED_ERR')
  @DocsEditable()
  static const int NO_MODIFICATION_ALLOWED_ERR = 6;

  @DomName('FileError.PATH_EXISTS_ERR')
  @DocsEditable()
  static const int PATH_EXISTS_ERR = 12;

  @DomName('FileError.QUOTA_EXCEEDED_ERR')
  @DocsEditable()
  static const int QUOTA_EXCEEDED_ERR = 10;

  @DomName('FileError.SECURITY_ERR')
  @DocsEditable()
  static const int SECURITY_ERR = 2;

  @DomName('FileError.SYNTAX_ERR')
  @DocsEditable()
  static const int SYNTAX_ERR = 8;

  @DomName('FileError.TYPE_MISMATCH_ERR')
  @DocsEditable()
  static const int TYPE_MISMATCH_ERR = 11;

  @DomName('FileError.code')
  @DocsEditable()
  final int code;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('FileList')
class FileList extends Interceptor with ListMixin<File>, ImmutableListMixin<File> implements JavaScriptIndexingBehavior, List<File> native "FileList" {
  // To suppress missing implicit constructor warnings.
  factory FileList._() { throw new UnsupportedError("Not supported"); }

  @DomName('FileList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  File operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("File", "#[#]", this, index);
  }
  void operator[]=(int index, File value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<File> mixins.
  // File is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  File get first {
    if (this.length > 0) {
      return JS('File', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  File get last {
    int len = this.length;
    if (len > 0) {
      return JS('File', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  File get single {
    int len = this.length;
    if (len == 1) {
      return JS('File', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  File elementAt(int index) => this[index];
  // -- end List<File> mixins.

  @DomName('FileList.item')
  @DocsEditable()
  File item(int index) native;
}
// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('FileReader')
class FileReader extends EventTarget native "FileReader" {

  @DomName('FileReader.result')
  @DocsEditable()
  Object get result {
    var res = JS('Null|String|NativeByteBuffer', '#.result', this);
    if (res is ByteBuffer) {
      return new Uint8List.view(res);
    }
    return res;
  }

  // To suppress missing implicit constructor warnings.
  factory FileReader._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `abort` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileReader.abortEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> abortEvent = const EventStreamProvider<ProgressEvent>('abort');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileReader.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `load` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileReader.loadEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> loadEvent = const EventStreamProvider<ProgressEvent>('load');

  /**
   * Static factory designed to expose `loadend` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileReader.loadendEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> loadEndEvent = const EventStreamProvider<ProgressEvent>('loadend');

  /**
   * Static factory designed to expose `loadstart` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileReader.loadstartEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> loadStartEvent = const EventStreamProvider<ProgressEvent>('loadstart');

  /**
   * Static factory designed to expose `progress` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileReader.progressEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> progressEvent = const EventStreamProvider<ProgressEvent>('progress');

  @DomName('FileReader.FileReader')
  @DocsEditable()
  factory FileReader() {
    return FileReader._create_1();
  }
  static FileReader _create_1() => JS('FileReader', 'new FileReader()');

  @DomName('FileReader.DONE')
  @DocsEditable()
  static const int DONE = 2;

  @DomName('FileReader.EMPTY')
  @DocsEditable()
  static const int EMPTY = 0;

  @DomName('FileReader.LOADING')
  @DocsEditable()
  static const int LOADING = 1;

  @DomName('FileReader.error')
  @DocsEditable()
  final FileError error;

  @DomName('FileReader.readyState')
  @DocsEditable()
  final int readyState;

  @DomName('FileReader.abort')
  @DocsEditable()
  void abort() native;

  @DomName('FileReader.readAsArrayBuffer')
  @DocsEditable()
  void readAsArrayBuffer(Blob blob) native;

  @JSName('readAsDataURL')
  @DomName('FileReader.readAsDataURL')
  @DocsEditable()
  void readAsDataUrl(Blob blob) native;

  @DomName('FileReader.readAsText')
  @DocsEditable()
  void readAsText(Blob blob, [String encoding]) native;

  /// Stream of `abort` events handled by this [FileReader].
  @DomName('FileReader.onabort')
  @DocsEditable()
  Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);

  /// Stream of `error` events handled by this [FileReader].
  @DomName('FileReader.onerror')
  @DocsEditable()
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `load` events handled by this [FileReader].
  @DomName('FileReader.onload')
  @DocsEditable()
  Stream<ProgressEvent> get onLoad => loadEvent.forTarget(this);

  /// Stream of `loadend` events handled by this [FileReader].
  @DomName('FileReader.onloadend')
  @DocsEditable()
  Stream<ProgressEvent> get onLoadEnd => loadEndEvent.forTarget(this);

  /// Stream of `loadstart` events handled by this [FileReader].
  @DomName('FileReader.onloadstart')
  @DocsEditable()
  Stream<ProgressEvent> get onLoadStart => loadStartEvent.forTarget(this);

  /// Stream of `progress` events handled by this [FileReader].
  @DomName('FileReader.onprogress')
  @DocsEditable()
  Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('Stream')
@Experimental() // untriaged
class FileStream extends Interceptor native "Stream" {
  // To suppress missing implicit constructor warnings.
  factory FileStream._() { throw new UnsupportedError("Not supported"); }

  @DomName('Stream.type')
  @DocsEditable()
  @Experimental() // untriaged
  final String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('DOMFileSystem')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://www.w3.org/TR/file-system-api/
class FileSystem extends Interceptor native "DOMFileSystem" {
  // To suppress missing implicit constructor warnings.
  factory FileSystem._() { throw new UnsupportedError("Not supported"); }

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.webkitRequestFileSystem)');

  @DomName('DOMFileSystem.name')
  @DocsEditable()
  final String name;

  @DomName('DOMFileSystem.root')
  @DocsEditable()
  final DirectoryEntry root;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('FileSystemCallback')
// http://www.w3.org/TR/file-system-api/#the-filesystemcallback-interface
@Experimental()
typedef void _FileSystemCallback(FileSystem fileSystem);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('FileWriter')
// http://www.w3.org/TR/file-writer-api/#the-filewriter-interface
@Experimental()
class FileWriter extends EventTarget native "FileWriter" {
  // To suppress missing implicit constructor warnings.
  factory FileWriter._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `abort` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileWriter.abortEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> abortEvent = const EventStreamProvider<ProgressEvent>('abort');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileWriter.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `progress` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileWriter.progressEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> progressEvent = const EventStreamProvider<ProgressEvent>('progress');

  /**
   * Static factory designed to expose `write` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileWriter.writeEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> writeEvent = const EventStreamProvider<ProgressEvent>('write');

  /**
   * Static factory designed to expose `writeend` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileWriter.writeendEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> writeEndEvent = const EventStreamProvider<ProgressEvent>('writeend');

  /**
   * Static factory designed to expose `writestart` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileWriter.writestartEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> writeStartEvent = const EventStreamProvider<ProgressEvent>('writestart');

  @DomName('FileWriter.DONE')
  @DocsEditable()
  static const int DONE = 2;

  @DomName('FileWriter.INIT')
  @DocsEditable()
  static const int INIT = 0;

  @DomName('FileWriter.WRITING')
  @DocsEditable()
  static const int WRITING = 1;

  @DomName('FileWriter.error')
  @DocsEditable()
  final FileError error;

  @DomName('FileWriter.length')
  @DocsEditable()
  final int length;

  @DomName('FileWriter.position')
  @DocsEditable()
  final int position;

  @DomName('FileWriter.readyState')
  @DocsEditable()
  final int readyState;

  @DomName('FileWriter.abort')
  @DocsEditable()
  void abort() native;

  @DomName('FileWriter.seek')
  @DocsEditable()
  void seek(int position) native;

  @DomName('FileWriter.truncate')
  @DocsEditable()
  void truncate(int size) native;

  @DomName('FileWriter.write')
  @DocsEditable()
  void write(Blob data) native;

  /// Stream of `abort` events handled by this [FileWriter].
  @DomName('FileWriter.onabort')
  @DocsEditable()
  Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);

  /// Stream of `error` events handled by this [FileWriter].
  @DomName('FileWriter.onerror')
  @DocsEditable()
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `progress` events handled by this [FileWriter].
  @DomName('FileWriter.onprogress')
  @DocsEditable()
  Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);

  /// Stream of `write` events handled by this [FileWriter].
  @DomName('FileWriter.onwrite')
  @DocsEditable()
  Stream<ProgressEvent> get onWrite => writeEvent.forTarget(this);

  /// Stream of `writeend` events handled by this [FileWriter].
  @DomName('FileWriter.onwriteend')
  @DocsEditable()
  Stream<ProgressEvent> get onWriteEnd => writeEndEvent.forTarget(this);

  /// Stream of `writestart` events handled by this [FileWriter].
  @DomName('FileWriter.onwritestart')
  @DocsEditable()
  Stream<ProgressEvent> get onWriteStart => writeStartEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('FileWriterCallback')
// http://www.w3.org/TR/file-writer-api/#idl-def-FileWriter
@Experimental()
typedef void _FileWriterCallback(FileWriter fileWriter);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('FocusEvent')
class FocusEvent extends UIEvent native "FocusEvent" {
  // To suppress missing implicit constructor warnings.
  factory FocusEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('FocusEvent.relatedTarget')
  @DocsEditable()
  EventTarget get relatedTarget => _convertNativeToDart_EventTarget(this._get_relatedTarget);
  @JSName('relatedTarget')
  @DomName('FocusEvent.relatedTarget')
  @DocsEditable()
  @Creates('Null')
  final dynamic _get_relatedTarget;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('FontFace')
@Experimental() // untriaged
class FontFace extends Interceptor native "FontFace" {
  // To suppress missing implicit constructor warnings.
  factory FontFace._() { throw new UnsupportedError("Not supported"); }

  @DomName('FontFace.FontFace')
  @DocsEditable()
  factory FontFace(String family, String source, Map descriptors) {
    return FontFace._create_1(family, source, descriptors);
  }
  static FontFace _create_1(family, source, descriptors) => JS('FontFace', 'new FontFace(#,#,#)', family, source, descriptors);

  @DomName('FontFace.family')
  @DocsEditable()
  @Experimental() // untriaged
  String family;

  @DomName('FontFace.featureSettings')
  @DocsEditable()
  @Experimental() // untriaged
  String featureSettings;

  @DomName('FontFace.status')
  @DocsEditable()
  @Experimental() // untriaged
  final String status;

  @DomName('FontFace.stretch')
  @DocsEditable()
  @Experimental() // untriaged
  String stretch;

  @DomName('FontFace.style')
  @DocsEditable()
  @Experimental() // untriaged
  String style;

  @DomName('FontFace.unicodeRange')
  @DocsEditable()
  @Experimental() // untriaged
  String unicodeRange;

  @DomName('FontFace.variant')
  @DocsEditable()
  @Experimental() // untriaged
  String variant;

  @DomName('FontFace.weight')
  @DocsEditable()
  @Experimental() // untriaged
  String weight;

  @DomName('FontFace.load')
  @DocsEditable()
  @Experimental() // untriaged
  void load() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('FontFaceSet')
@Experimental() // untriaged
class FontFaceSet extends EventTarget native "FontFaceSet" {
  // To suppress missing implicit constructor warnings.
  factory FontFaceSet._() { throw new UnsupportedError("Not supported"); }

  @DomName('FontFaceSet.size')
  @DocsEditable()
  @Experimental() // untriaged
  final int size;

  @DomName('FontFaceSet.status')
  @DocsEditable()
  @Experimental() // untriaged
  final String status;

  @DomName('FontFaceSet.add')
  @DocsEditable()
  @Experimental() // untriaged
  void add(FontFace fontFace) native;

  @DomName('FontFaceSet.check')
  @DocsEditable()
  @Experimental() // untriaged
  bool check(String font, String text) native;

  @DomName('FontFaceSet.clear')
  @DocsEditable()
  @Experimental() // untriaged
  void clear() native;

  @DomName('FontFaceSet.delete')
  @DocsEditable()
  @Experimental() // untriaged
  bool delete(FontFace fontFace) native;

  @DomName('FontFaceSet.forEach')
  @DocsEditable()
  @Experimental() // untriaged
  void forEach(FontFaceSetForEachCallback callback, [Object thisArg]) native;

  @DomName('FontFaceSet.has')
  @DocsEditable()
  @Experimental() // untriaged
  bool has(FontFace fontFace) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('FontFaceSetForEachCallback')
@Experimental() // untriaged
typedef void FontFaceSetForEachCallback(FontFace fontFace, FontFace fontFaceAgain, FontFaceSet set);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('FormData')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
class FormData extends Interceptor native "FormData" {
  // To suppress missing implicit constructor warnings.
  factory FormData._() { throw new UnsupportedError("Not supported"); }

  @DomName('FormData.FormData')
  @DocsEditable()
  factory FormData([FormElement form]) {
    if (form != null) {
      return FormData._create_1(form);
    }
    return FormData._create_2();
  }
  static FormData _create_1(form) => JS('FormData', 'new FormData(#)', form);
  static FormData _create_2() => JS('FormData', 'new FormData()');

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.FormData)');

  @DomName('FormData.append')
  @DocsEditable()
  void append(String name, String value) native;

  @JSName('append')
  @DomName('FormData.append')
  @DocsEditable()
  void appendBlob(String name, Blob value, [String filename]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLFormElement')
class FormElement extends HtmlElement native "HTMLFormElement" {
  // To suppress missing implicit constructor warnings.
  factory FormElement._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `autocomplete` events to event
   * handlers that are not necessarily instances of [FormElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLFormElement.autocompleteEvent')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#autofilling-form-controls:-the-autocomplete-attribute
  @Experimental()
  static const EventStreamProvider<Event> autocompleteEvent = const EventStreamProvider<Event>('autocomplete');

  /**
   * Static factory designed to expose `autocompleteerror` events to event
   * handlers that are not necessarily instances of [FormElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLFormElement.autocompleteerrorEvent')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#autofilling-form-controls:-the-autocomplete-attribute
  @Experimental()
  static const EventStreamProvider<AutocompleteErrorEvent> autocompleteErrorEvent = const EventStreamProvider<AutocompleteErrorEvent>('autocompleteerror');

  @DomName('HTMLFormElement.HTMLFormElement')
  @DocsEditable()
  factory FormElement() => document.createElement("form");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  FormElement.created() : super.created();

  @DomName('HTMLFormElement.acceptCharset')
  @DocsEditable()
  String acceptCharset;

  @DomName('HTMLFormElement.action')
  @DocsEditable()
  String action;

  @DomName('HTMLFormElement.autocomplete')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#autofilling-form-controls:-the-autocomplete-attribute
  @Experimental()
  String autocomplete;

  @DomName('HTMLFormElement.encoding')
  @DocsEditable()
  String encoding;

  @DomName('HTMLFormElement.enctype')
  @DocsEditable()
  String enctype;

  @DomName('HTMLFormElement.length')
  @DocsEditable()
  final int length;

  @DomName('HTMLFormElement.method')
  @DocsEditable()
  String method;

  @DomName('HTMLFormElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLFormElement.noValidate')
  @DocsEditable()
  bool noValidate;

  @DomName('HTMLFormElement.target')
  @DocsEditable()
  String target;

  @DomName('HTMLFormElement.__getter__')
  @DocsEditable()
  Element __getter__(int index) native;

  @DomName('HTMLFormElement.checkValidity')
  @DocsEditable()
  bool checkValidity() native;

  @DomName('HTMLFormElement.requestAutocomplete')
  @DocsEditable()
  // http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2012-October/037711.html
  @Experimental()
  void requestAutocomplete(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;

  /// Stream of `autocomplete` events handled by this [FormElement].
  @DomName('HTMLFormElement.onautocomplete')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#autofilling-form-controls:-the-autocomplete-attribute
  @Experimental()
  ElementStream<Event> get onAutocomplete => autocompleteEvent.forElement(this);

  /// Stream of `autocompleteerror` events handled by this [FormElement].
  @DomName('HTMLFormElement.onautocompleteerror')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#autofilling-form-controls:-the-autocomplete-attribute
  @Experimental()
  ElementStream<AutocompleteErrorEvent> get onAutocompleteError => autocompleteErrorEvent.forElement(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('Gamepad')
// https://dvcs.w3.org/hg/gamepad/raw-file/default/gamepad.html#gamepad-interface
@Experimental()
class Gamepad extends Interceptor native "Gamepad" {
  // To suppress missing implicit constructor warnings.
  factory Gamepad._() { throw new UnsupportedError("Not supported"); }

  @DomName('Gamepad.axes')
  @DocsEditable()
  final List<num> axes;

  @DomName('Gamepad.buttons')
  @DocsEditable()
  final List<num> buttons;

  @DomName('Gamepad.id')
  @DocsEditable()
  final String id;

  @DomName('Gamepad.index')
  @DocsEditable()
  final int index;

  @DomName('Gamepad.timestamp')
  @DocsEditable()
  final int timestamp;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('Geolocation')
@Unstable()
class Geolocation extends Interceptor native "Geolocation" {

  @DomName('Geolocation.getCurrentPosition')
  Future<Geoposition> getCurrentPosition({bool enableHighAccuracy,
      Duration timeout, Duration maximumAge}) {
    var options = {};
    if (enableHighAccuracy != null) {
      options['enableHighAccuracy'] = enableHighAccuracy;
    }
    if (timeout != null) {
      options['timeout'] = timeout.inMilliseconds;
    }
    if (maximumAge != null) {
      options['maximumAge'] = maximumAge.inMilliseconds;
    }
    var completer = new Completer<Geoposition>();
    try {
      _getCurrentPosition(
          (position) {
            completer.complete(_ensurePosition(position));
          },
          (error) {
            completer.completeError(error);
          },
          options);
    } catch (e, stacktrace) {
      completer.completeError(e, stacktrace);
    }
    return completer.future;
  }

  @DomName('Geolocation.watchPosition')
  Stream<Geoposition> watchPosition({bool enableHighAccuracy,
      Duration timeout, Duration maximumAge}) {

    var options = {};
    if (enableHighAccuracy != null) {
      options['enableHighAccuracy'] = enableHighAccuracy;
    }
    if (timeout != null) {
      options['timeout'] = timeout.inMilliseconds;
    }
    if (maximumAge != null) {
      options['maximumAge'] = maximumAge.inMilliseconds;
    }

    int watchId;
    var controller;
    controller = new StreamController<Geoposition>(sync: true,
      onListen: () {
        assert(watchId == null);
        watchId = _watchPosition(
            (position) {
              controller.add(_ensurePosition(position));
            },
            (error) {
              controller.addError(error);
            },
            options);
      },
      onCancel: () {
        assert(watchId != null);
        _clearWatch(watchId);
      });

    return controller.stream;
  }

  Geoposition _ensurePosition(domPosition) {
    try {
      // Firefox may throw on this.
      if (domPosition is Geoposition) {
        return domPosition;
      }
    } catch(e) {}
    return new _GeopositionWrapper(domPosition);
  }

  // To suppress missing implicit constructor warnings.
  factory Geolocation._() { throw new UnsupportedError("Not supported"); }

  @JSName('clearWatch')
  @DomName('Geolocation.clearWatch')
  @DocsEditable()
  void _clearWatch(int watchID) native;

  @JSName('getCurrentPosition')
  @DomName('Geolocation.getCurrentPosition')
  @DocsEditable()
  void _getCurrentPosition(_PositionCallback successCallback, [_PositionErrorCallback errorCallback, Object options]) native;

  @JSName('watchPosition')
  @DomName('Geolocation.watchPosition')
  @DocsEditable()
  int _watchPosition(_PositionCallback successCallback, [_PositionErrorCallback errorCallback, Object options]) native;
}

/**
 * Wrapper for Firefox- it returns an object which we cannot map correctly.
 * Basically Firefox was returning a [xpconnect wrapped nsIDOMGeoPosition] but
 * which has further oddities.
 */
class _GeopositionWrapper implements Geoposition {
  var _ptr;
  _GeopositionWrapper(this._ptr);

  Coordinates get coords => JS('Coordinates', '#.coords', _ptr);
  int get timestamp => JS('int', '#.timestamp', _ptr);
}


// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('Geoposition')
@Unstable()
class Geoposition extends Interceptor native "Geoposition" {
  // To suppress missing implicit constructor warnings.
  factory Geoposition._() { throw new UnsupportedError("Not supported"); }

  @DomName('Geoposition.coords')
  @DocsEditable()
  final Coordinates coords;

  @DomName('Geoposition.timestamp')
  @DocsEditable()
  final int timestamp;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('GlobalEventHandlers')
@Experimental() // untriaged
abstract class GlobalEventHandlers extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory GlobalEventHandlers._() { throw new UnsupportedError("Not supported"); }

  @DomName('GlobalEventHandlers.abortEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> abortEvent = const EventStreamProvider<Event>('abort');

  @DomName('GlobalEventHandlers.blurEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> blurEvent = const EventStreamProvider<Event>('blur');

  @DomName('GlobalEventHandlers.changeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> changeEvent = const EventStreamProvider<Event>('change');

  @DomName('GlobalEventHandlers.clickEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> clickEvent = const EventStreamProvider<MouseEvent>('click');

  @DomName('GlobalEventHandlers.contextmenuEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> contextMenuEvent = const EventStreamProvider<MouseEvent>('contextmenu');

  @DomName('GlobalEventHandlers.dblclickEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> doubleClickEvent = const EventStreamProvider<Event>('dblclick');

  @DomName('GlobalEventHandlers.dragEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragEvent = const EventStreamProvider<MouseEvent>('drag');

  @DomName('GlobalEventHandlers.dragendEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragEndEvent = const EventStreamProvider<MouseEvent>('dragend');

  @DomName('GlobalEventHandlers.dragenterEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragEnterEvent = const EventStreamProvider<MouseEvent>('dragenter');

  @DomName('GlobalEventHandlers.dragleaveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragLeaveEvent = const EventStreamProvider<MouseEvent>('dragleave');

  @DomName('GlobalEventHandlers.dragoverEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragOverEvent = const EventStreamProvider<MouseEvent>('dragover');

  @DomName('GlobalEventHandlers.dragstartEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragStartEvent = const EventStreamProvider<MouseEvent>('dragstart');

  @DomName('GlobalEventHandlers.dropEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dropEvent = const EventStreamProvider<MouseEvent>('drop');

  @DomName('GlobalEventHandlers.errorEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  @DomName('GlobalEventHandlers.focusEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> focusEvent = const EventStreamProvider<Event>('focus');

  @DomName('GlobalEventHandlers.inputEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> inputEvent = const EventStreamProvider<Event>('input');

  @DomName('GlobalEventHandlers.invalidEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> invalidEvent = const EventStreamProvider<Event>('invalid');

  @DomName('GlobalEventHandlers.keydownEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<KeyboardEvent> keyDownEvent = const EventStreamProvider<KeyboardEvent>('keydown');

  @DomName('GlobalEventHandlers.keypressEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<KeyboardEvent> keyPressEvent = const EventStreamProvider<KeyboardEvent>('keypress');

  @DomName('GlobalEventHandlers.keyupEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<KeyboardEvent> keyUpEvent = const EventStreamProvider<KeyboardEvent>('keyup');

  @DomName('GlobalEventHandlers.loadEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadEvent = const EventStreamProvider<Event>('load');

  @DomName('GlobalEventHandlers.mousedownEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseDownEvent = const EventStreamProvider<MouseEvent>('mousedown');

  @DomName('GlobalEventHandlers.mouseenterEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseEnterEvent = const EventStreamProvider<MouseEvent>('mouseenter');

  @DomName('GlobalEventHandlers.mouseleaveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseLeaveEvent = const EventStreamProvider<MouseEvent>('mouseleave');

  @DomName('GlobalEventHandlers.mousemoveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseMoveEvent = const EventStreamProvider<MouseEvent>('mousemove');

  @DomName('GlobalEventHandlers.mouseoutEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseOutEvent = const EventStreamProvider<MouseEvent>('mouseout');

  @DomName('GlobalEventHandlers.mouseoverEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseOverEvent = const EventStreamProvider<MouseEvent>('mouseover');

  @DomName('GlobalEventHandlers.mouseupEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseUpEvent = const EventStreamProvider<MouseEvent>('mouseup');

  @DomName('GlobalEventHandlers.mousewheelEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<WheelEvent> mouseWheelEvent = const EventStreamProvider<WheelEvent>('mousewheel');

  @DomName('GlobalEventHandlers.resetEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> resetEvent = const EventStreamProvider<Event>('reset');

  @DomName('GlobalEventHandlers.resizeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> resizeEvent = const EventStreamProvider<Event>('resize');

  @DomName('GlobalEventHandlers.scrollEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> scrollEvent = const EventStreamProvider<Event>('scroll');

  @DomName('GlobalEventHandlers.selectEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> selectEvent = const EventStreamProvider<Event>('select');

  @DomName('GlobalEventHandlers.submitEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> submitEvent = const EventStreamProvider<Event>('submit');

  @DomName('GlobalEventHandlers.onabort')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onAbort => abortEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onblur')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onBlur => blurEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onChange => changeEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onclick')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onClick => clickEvent.forTarget(this);

  @DomName('GlobalEventHandlers.oncontextmenu')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onContextMenu => contextMenuEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondblclick')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onDoubleClick => doubleClickEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondrag')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDrag => dragEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondragend')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDragEnd => dragEndEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondragenter')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDragEnter => dragEnterEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondragleave')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDragLeave => dragLeaveEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondragover')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDragOver => dragOverEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondragstart')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDragStart => dragStartEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondrop')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDrop => dropEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onerror')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onError => errorEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onfocus')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onFocus => focusEvent.forTarget(this);

  @DomName('GlobalEventHandlers.oninput')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onInput => inputEvent.forTarget(this);

  @DomName('GlobalEventHandlers.oninvalid')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onInvalid => invalidEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onkeydown')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<KeyboardEvent> get onKeyDown => keyDownEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onkeypress')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<KeyboardEvent> get onKeyPress => keyPressEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onkeyup')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<KeyboardEvent> get onKeyUp => keyUpEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onload')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onLoad => loadEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmousedown')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseDown => mouseDownEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseEnter => mouseEnterEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseLeave => mouseLeaveEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmousemove')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseMove => mouseMoveEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmouseout')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseOut => mouseOutEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmouseover')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseOver => mouseOverEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmouseup')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseUp => mouseUpEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmousewheel')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<WheelEvent> get onMouseWheel => mouseWheelEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onreset')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onReset => resetEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onResize => resizeEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onscroll')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onScroll => scrollEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onselect')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSelect => selectEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onsubmit')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSubmit => submitEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
/**
 * An `<hr>` tag.
 */
@DomName('HTMLHRElement')
class HRElement extends HtmlElement native "HTMLHRElement" {
  // To suppress missing implicit constructor warnings.
  factory HRElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLHRElement.HTMLHRElement')
  @DocsEditable()
  factory HRElement() => document.createElement("hr");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  HRElement.created() : super.created();

  @DomName('HTMLHRElement.color')
  @DocsEditable()
  @Experimental() // untriaged
  String color;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('HashChangeEvent')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
class HashChangeEvent extends Event native "HashChangeEvent" {
  factory HashChangeEvent(String type,
      {bool canBubble: true, bool cancelable: true, String oldUrl,
      String newUrl}) {
    var event = document._createEvent("HashChangeEvent");
    event._initHashChangeEvent(type, canBubble, cancelable, oldUrl, newUrl);
    return event;
  }
  // To suppress missing implicit constructor warnings.
  factory HashChangeEvent._() { throw new UnsupportedError("Not supported"); }

  /// Checks if this type is supported on the current platform.
  static bool get supported => Device.isEventTypeSupported('HashChangeEvent');

  @JSName('newURL')
  @DomName('HashChangeEvent.newURL')
  @DocsEditable()
  final String newUrl;

  @JSName('oldURL')
  @DomName('HashChangeEvent.oldURL')
  @DocsEditable()
  final String oldUrl;

  @JSName('initHashChangeEvent')
  @DomName('HashChangeEvent.initHashChangeEvent')
  @DocsEditable()
  void _initHashChangeEvent(String type, bool canBubble, bool cancelable, String oldURL, String newURL) native;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLHeadElement')
class HeadElement extends HtmlElement native "HTMLHeadElement" {
  // To suppress missing implicit constructor warnings.
  factory HeadElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLHeadElement.HTMLHeadElement')
  @DocsEditable()
  factory HeadElement() => document.createElement("head");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  HeadElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLHeadingElement')
class HeadingElement extends HtmlElement native "HTMLHeadingElement" {
  // To suppress missing implicit constructor warnings.
  factory HeadingElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h1() => document.createElement("h1");

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h2() => document.createElement("h2");

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h3() => document.createElement("h3");

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h4() => document.createElement("h4");

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h5() => document.createElement("h5");

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h6() => document.createElement("h6");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  HeadingElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('History')
class History extends Interceptor implements HistoryBase native "History" {

  /**
   * Checks if the State APIs are supported on the current platform.
   *
   * See also:
   *
   * * [pushState]
   * * [replaceState]
   * * [state]
   */
  static bool get supportsState => JS('bool', '!!window.history.pushState');
  // To suppress missing implicit constructor warnings.
  factory History._() { throw new UnsupportedError("Not supported"); }

  @DomName('History.length')
  @DocsEditable()
  final int length;

  @DomName('History.state')
  @DocsEditable()
  dynamic get state => convertNativeToDart_SerializedScriptValue(this._get_state);
  @JSName('state')
  @DomName('History.state')
  @DocsEditable()
  @annotation_Creates_SerializedScriptValue
  @annotation_Returns_SerializedScriptValue
  final dynamic _get_state;

  @DomName('History.back')
  @DocsEditable()
  void back() native;

  @DomName('History.forward')
  @DocsEditable()
  void forward() native;

  @DomName('History.go')
  @DocsEditable()
  void go(int distance) native;

  @DomName('History.pushState')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void pushState(Object data, String title, [String url]) native;

  @DomName('History.replaceState')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void replaceState(Object data, String title, [String url]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLCollection')
class HtmlCollection extends Interceptor with ListMixin<Node>, ImmutableListMixin<Node> implements JavaScriptIndexingBehavior, List<Node> native "HTMLCollection" {
  // To suppress missing implicit constructor warnings.
  factory HtmlCollection._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLCollection.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  Node operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("Node", "#[#]", this, index);
  }
  void operator[]=(int index, Node value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Node> mixins.
  // Node is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Node get first {
    if (this.length > 0) {
      return JS('Node', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Node get last {
    int len = this.length;
    if (len > 0) {
      return JS('Node', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Node get single {
    int len = this.length;
    if (len == 1) {
      return JS('Node', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Node elementAt(int index) => this[index];
  // -- end List<Node> mixins.

  @DomName('HTMLCollection.item')
  @DocsEditable()
  Element item(int index) native;

  @DomName('HTMLCollection.namedItem')
  @DocsEditable()
  Element namedItem(String name) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('HTMLDocument')
class HtmlDocument extends Document native "HTMLDocument" {
  // To suppress missing implicit constructor warnings.
  factory HtmlDocument._() { throw new UnsupportedError("Not supported"); }


  @DomName('Document.body')
  BodyElement body;

  @DomName('Document.caretRangeFromPoint')
  Range caretRangeFromPoint(int x, int y) {
    return _caretRangeFromPoint(x, y);
  }

  @DomName('Document.elementFromPoint')
  Element elementFromPoint(int x, int y) {
    return _elementFromPoint(x, y);
  }

  /**
   * Checks if the getCssCanvasContext API is supported on the current platform.
   *
   * See also:
   *
   * * [getCssCanvasContext]
   */
  static bool get supportsCssCanvasContext =>
      JS('bool', '!!(document.getCSSCanvasContext)');


  /**
   * Gets a CanvasRenderingContext which can be used as the CSS background of an
   * element.
   *
   * CSS:
   *
   *     background: -webkit-canvas(backgroundCanvas)
   *
   * Generate the canvas:
   *
   *     var context = document.getCssCanvasContext('2d', 'backgroundCanvas',
   *         100, 100);
   *     context.fillStyle = 'red';
   *     context.fillRect(0, 0, 100, 100);
   *
   * See also:
   *
   * * [supportsCssCanvasContext]
   * * [CanvasElement.getContext]
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @DomName('Document.getCSSCanvasContext')
  CanvasRenderingContext getCssCanvasContext(String contextId, String name,
      int width, int height) {
    return _getCssCanvasContext(contextId, name, width, height);
  }

  @DomName('Document.head')
  HeadElement get head => _head;

  @DomName('Document.lastModified')
  String get lastModified => _lastModified;

  @DomName('Document.preferredStylesheetSet')
  String get preferredStylesheetSet => _preferredStylesheetSet;

  @DomName('Document.referrer')
  String get referrer => _referrer;

  @DomName('Document.selectedStylesheetSet')
  String get selectedStylesheetSet => _selectedStylesheetSet;
  void set selectedStylesheetSet(String value) {
    _selectedStylesheetSet = value;
  }

  @DomName('Document.styleSheets')
  List<StyleSheet> get styleSheets => _styleSheets;

  @DomName('Document.title')
  String get title => _title;

  @DomName('Document.title')
  void set title(String value) {
    _title = value;
  }

  /**
   * Returns page to standard layout.
   *
   * Has no effect if the page is not in fullscreen mode.
   *
   * ## Other resources
   *
   * * [Using the fullscreen API]
   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api) from
   * WebPlatform.org.
   * * [Fullscreen specification]
   * (http://www.w3.org/TR/fullscreen/) from W3C.
   */
  @DomName('Document.webkitExitFullscreen')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  void exitFullscreen() {
    _webkitExitFullscreen();
  }

  @DomName('Document.webkitExitPointerLock')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  void exitPointerLock() {
    _webkitExitPointerLock();
  }

  /**
   * Returns the element, if any, that is currently displayed in fullscreen.
   *
   * Returns null if there is currently no fullscreen element. You can use
   * this to determine if the page is in fullscreen mode.
   *
   *     myVideo = new VideoElement();
   *     if (document.fullscreenElement == null) {
   *       myVideo.requestFullscreen();
   *       print(document.fullscreenElement == myVideo); // true
   *     }
   *
   * ## Other resources
   *
   * * [Using the fullscreen API]
   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api) from
   * WebPlatform.org.
   * * [Fullscreen specification]
   * (http://www.w3.org/TR/fullscreen/) from W3C.
   */
  @DomName('Document.webkitFullscreenElement')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  Element get fullscreenElement => _webkitFullscreenElement;

  /**
   * Returns true if this document can display elements in fullscreen mode.
   *
   * ## Other resources
   *
   * * [Using the fullscreen API]
   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api) from
   * WebPlatform.org.
   * * [Fullscreen specification]
   * (http://www.w3.org/TR/fullscreen/) from W3C.
   */
  @DomName('Document.webkitFullscreenEnabled')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  bool get fullscreenEnabled => _webkitFullscreenEnabled;

  @DomName('Document.webkitHidden')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  bool get hidden => _webkitHidden;

  @DomName('Document.webkitPointerLockElement')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  Element get pointerLockElement =>
      _webkitPointerLockElement;

  @DomName('Document.visibilityState')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @Experimental()
  String get visibilityState => JS('String',
    '(#.visibilityState || #.mozVisibilityState || #.msVisibilityState ||'
      '#.webkitVisibilityState)', this, this, this, this);

  @Experimental()
  /**
   * Register a custom subclass of Element to be instantiatable by the DOM.
   *
   * This is necessary to allow the construction of any custom elements.
   *
   * The class being registered must either subclass HtmlElement or SvgElement.
   * If they subclass these directly then they can be used as:
   *
   *     class FooElement extends HtmlElement{
   *        void created() {
   *          print('FooElement created!');
   *        }
   *     }
   *
   *     main() {
   *       document.registerElement('x-foo', FooElement);
   *       var myFoo = new Element.tag('x-foo');
   *       // prints 'FooElement created!' to the console.
   *     }
   *
   * The custom element can also be instantiated via HTML using the syntax
   * `<x-foo></x-foo>`
   *
   * Other elements can be subclassed as well:
   *
   *     class BarElement extends InputElement{
   *        void created() {
   *          print('BarElement created!');
   *        }
   *     }
   *
   *     main() {
   *       document.registerElement('x-bar', BarElement);
   *       var myBar = new Element.tag('input', 'x-bar');
   *       // prints 'BarElement created!' to the console.
   *     }
   *
   * This custom element can also be instantiated via HTML using the syntax
   * `<input is="x-bar"></input>`
   *
   */
  void registerElement(String tag, Type customElementClass,
      {String extendsTag}) {
    _registerCustomElement(JS('', 'window'), this, tag, customElementClass,
        extendsTag);
  }

  /** *Deprecated*: use [registerElement] instead. */
  @deprecated
  @Experimental()
  void register(String tag, Type customElementClass, {String extendsTag}) {
    return registerElement(tag, customElementClass, extendsTag: extendsTag);
  }

  /**
   * Static factory designed to expose `visibilitychange` events to event
   * handlers that are not necessarily instances of [Document].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Document.visibilityChange')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @Experimental()
  static const EventStreamProvider<Event> visibilityChangeEvent =
      const _CustomEventStreamProvider<Event>(
        _determineVisibilityChangeEventType);

  static String _determineVisibilityChangeEventType(EventTarget e) {
    if (JS('bool', '(typeof #.hidden !== "undefined")', e)) {
      // Opera 12.10 and Firefox 18 and later support
      return 'visibilitychange';
    } else if (JS('bool', '(typeof #.mozHidden !== "undefined")', e)) {
      return 'mozvisibilitychange';
    } else if (JS('bool', '(typeof #.msHidden !== "undefined")', e)) {
      return 'msvisibilitychange';
    } else if (JS('bool', '(typeof #.webkitHidden !== "undefined")', e)) {
      return 'webkitvisibilitychange';
    }
    return 'visibilitychange';
  }

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @Experimental()
  Stream<Event> get onVisibilityChange =>
      visibilityChangeEvent.forTarget(this);

  /// Creates an element upgrader which can be used to change the Dart wrapper
  /// type for elements.
  ///
  /// The type specified must be a subclass of HtmlElement, when an element is
  /// upgraded then the created constructor will be invoked on that element.
  ///
  /// If the type is not a direct subclass of HtmlElement then the extendsTag
  /// parameter must be provided.
  @Experimental()
  ElementUpgrader createElementUpgrader(Type type, {String extendsTag}) {
    return new _JSElementUpgrader(this, type, extendsTag);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLFormControlsCollection')
class HtmlFormControlsCollection extends HtmlCollection native "HTMLFormControlsCollection" {
  // To suppress missing implicit constructor warnings.
  factory HtmlFormControlsCollection._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLHtmlElement')
class HtmlHtmlElement extends HtmlElement native "HTMLHtmlElement" {
  // To suppress missing implicit constructor warnings.
  factory HtmlHtmlElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLHtmlElement.HTMLHtmlElement')
  @DocsEditable()
  factory HtmlHtmlElement() => document.createElement("html");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  HtmlHtmlElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLOptionsCollection')
class HtmlOptionsCollection extends HtmlCollection native "HTMLOptionsCollection" {
  // To suppress missing implicit constructor warnings.
  factory HtmlOptionsCollection._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


 /**
  * A client-side XHR request for getting data from a URL,
  * formally known as XMLHttpRequest.
  *
  * HttpRequest can be used to obtain data from HTTP and FTP protocols,
  * and is useful for AJAX-style page updates.
  *
  * The simplest way to get the contents of a text file, such as a
  * JSON-formatted file, is with [getString].
  * For example, the following code gets the contents of a JSON file
  * and prints its length:
  *
  *     var path = 'myData.json';
  *     HttpRequest.getString(path)
  *         .then((String fileContents) {
  *           print(fileContents.length);
  *         })
  *         .catchError((Error error) {
  *           print(error.toString());
  *         });
  *
  * ## Fetching data from other servers
  *
  * For security reasons, browsers impose restrictions on requests
  * made by embedded apps.
  * With the default behavior of this class,
  * the code making the request must be served from the same origin
  * (domain name, port, and application layer protocol)
  * as the requested resource.
  * In the example above, the myData.json file must be co-located with the
  * app that uses it.
  * You might be able to
  * [get around this restriction](http://www.dartlang.org/articles/json-web-service/#a-note-on-cors-and-httprequest)
  * by using CORS headers or JSONP.
  *
  * ## Other resources
  *
  * * [Fetch Data Dynamically](https://www.dartlang.org/docs/tutorials/fetchdata/),
  * a tutorial from _A Game of Darts_,
  * shows two different ways to use HttpRequest to get a JSON file.
  * * [Get Input from a Form](https://www.dartlang.org/docs/tutorials/forms/),
  * another tutorial from _A Game of Darts_,
  * shows using HttpRequest with a custom server.
  * * [Dart article on using HttpRequests](http://www.dartlang.org/articles/json-web-service/#getting-data)
  * * [JS XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest)
  * * [Using XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest)
 */
@DomName('XMLHttpRequest')
class HttpRequest extends HttpRequestEventTarget native "XMLHttpRequest" {

  /**
   * Creates a GET request for the specified [url].
   *
   * The server response must be a `text/` mime type for this request to
   * succeed.
   *
   * This is similar to [request] but specialized for HTTP GET requests which
   * return text content.
   *
   * To add query parameters, append them to the [url] following a `?`,
   * joining each key to its value with `=` and separating key-value pairs with
   * `&`.
   *
   *     var name = Uri.encodeQueryComponent('John');
   *     var id = Uri.encodeQueryComponent('42');
   *     HttpRequest.getString('users.json?name=$name&id=$id')
   *       .then((HttpRequest resp) {
   *         // Do something with the response.
   *     });
   *
   * See also:
   *
   * * [request]
   */
  static Future<String> getString(String url,
      {bool withCredentials, void onProgress(ProgressEvent e)}) {
    return request(url, withCredentials: withCredentials,
        onProgress: onProgress).then((xhr) => xhr.responseText);
  }

  /**
   * Makes a server POST request with the specified data encoded as form data.
   *
   * This is roughly the POST equivalent of getString. This method is similar
   * to sending a FormData object with broader browser support but limited to
   * String values.
   *
   * If [data] is supplied, the key/value pairs are URI encoded with
   * [Uri.encodeQueryComponent] and converted into an HTTP query string.
   *
   * Unless otherwise specified, this method appends the following header:
   *
   *     Content-Type: application/x-www-form-urlencoded; charset=UTF-8
   *
   * Here's an example of using this method:
   *
   *     var data = { 'firstName' : 'John', 'lastName' : 'Doe' };
   *     HttpRequest.postFormData('/send', data).then((HttpRequest resp) {
   *       // Do something with the response.
   *     });
   *
   * See also:
   *
   * * [request]
   */
  static Future<HttpRequest> postFormData(String url, Map<String, String> data,
      {bool withCredentials, String responseType,
      Map<String, String> requestHeaders,
      void onProgress(ProgressEvent e)}) {

    var parts = [];
    data.forEach((key, value) {
      parts.add('${Uri.encodeQueryComponent(key)}='
          '${Uri.encodeQueryComponent(value)}');
    });
    var formData = parts.join('&');

    if (requestHeaders == null) {
      requestHeaders = <String, String>{};
    }
    requestHeaders.putIfAbsent('Content-Type',
        () => 'application/x-www-form-urlencoded; charset=UTF-8');

    return request(url, method: 'POST', withCredentials: withCredentials,
        responseType: responseType,
        requestHeaders: requestHeaders, sendData: formData,
        onProgress: onProgress);
  }

  /**
   * Creates and sends a URL request for the specified [url].
   *
   * By default `request` will perform an HTTP GET request, but a different
   * method (`POST`, `PUT`, `DELETE`, etc) can be used by specifying the
   * [method] parameter. (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) {
      // Note: file:// URIs have status of 0.
      if ((xhr.status >= 200 && xhr.status < 300) ||
          xhr.status == 0 || xhr.status == 304) {
        completer.complete(xhr);
      } else {
        completer.completeError(e);
      }
    });

    xhr.onError.listen(completer.completeError);

    if (sendData != null) {
      xhr.send(sendData);
    } else {
      xhr.send();
    }

    return completer.future;
  }

  /**
   * Checks to see if the Progress event is supported on the current platform.
   */
  static bool get supportsProgressEvent {
    var xhr = new HttpRequest();
    return JS('bool', '("onprogress" in #)', xhr);
  }

  /**
   * Checks to see if the current platform supports making cross origin
   * requests.
   *
   * Note that even if cross origin requests are supported, they still may fail
   * if the destination server does not support CORS requests.
   */
  static bool get supportsCrossOrigin {
    var xhr = new HttpRequest();
    return JS('bool', '("withCredentials" in #)', xhr);
  }

  /**
   * Checks to see if the LoadEnd event is supported on the current platform.
   */
  static bool get supportsLoadEndEvent {
    var xhr = new HttpRequest();
    return JS('bool', '("onloadend" in #)', xhr);
  }

  /**
   * Checks to see if the overrideMimeType method is supported on the current
   * platform.
   */
  static bool get supportsOverrideMimeType {
    var xhr = new HttpRequest();
    return JS('bool', '("overrideMimeType" in #)', xhr);
  }

  /**
   * Makes a cross-origin request to the specified URL.
   *
   * This API provides a subset of [request] which works on IE9. If IE9
   * cross-origin support is not required then [request] should be used instead.
   */
  @Experimental()
  static Future<String> requestCrossOrigin(String url,
      {String method, String sendData}) {
    if (supportsCrossOrigin) {
      return request(url, method: method, sendData: sendData).then((xhr) {
        return xhr.responseText;
      });
    }
    var completer = new Completer<String>();
    if (method == null) {
      method = 'GET';
    }
    var xhr = JS('var', 'new XDomainRequest()');
    JS('', '#.open(#, #)', xhr, method, url);
    JS('', '#.onload = #', xhr, convertDartClosureToJS((e) {
      var response = JS('String', '#.responseText', xhr);
      completer.complete(response);
    }, 1));
    JS('', '#.onerror = #', xhr, convertDartClosureToJS((e) {
      completer.completeError(e);
    }, 1));

    // IE9 RTM - XDomainRequest issued requests may abort if all event handlers
    // not specified
    // http://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified
    JS('', '#.onprogress = {}', xhr);
    JS('', '#.ontimeout = {}', xhr);
    JS('', '#.timeout = Number.MAX_VALUE', xhr);

    if (sendData != null) {
      JS('', '#.send(#)', xhr, sendData);
    } else {
      JS('', '#.send()', xhr);
    }

    return completer.future;
  }

  /**
   * Returns all response headers as a key-value map.
   *
   * Multiple values for the same header key can be combined into one,
   * separated by a comma and a space.
   *
   * See: http://www.w3.org/TR/XMLHttpRequest/#the-getresponseheader()-method
   */
  Map<String, String> get responseHeaders {
    // from Closure's goog.net.Xhrio.getResponseHeaders.
    var headers = <String, String>{};
    var headersString = this.getAllResponseHeaders();
    if (headersString == null) {
      return headers;
    }
    var headersList = headersString.split('\r\n');
    for (var header in headersList) {
      if (header.isEmpty) {
        continue;
      }

      var splitIdx = header.indexOf(': ');
      if (splitIdx == -1) {
        continue;
      }
      var key = header.substring(0, splitIdx).toLowerCase();
      var value = header.substring(splitIdx + 2);
      if (headers.containsKey(key)) {
        headers[key] = '${headers[key]}, $value';
      } else {
        headers[key] = value;
      }
    }
    return headers;
  }

  // To suppress missing implicit constructor warnings.
  factory HttpRequest._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `readystatechange` events to event
   * handlers that are not necessarily instances of [HttpRequest].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequest.readystatechangeEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> readyStateChangeEvent = const EventStreamProvider<ProgressEvent>('readystatechange');

  /**
   * General constructor for any type of request (GET, POST, etc).
   *
   * This call is used in conjunction with [open]:
   *
   *     var request = new HttpRequest();
   *     request.open('GET', 'http://dartlang.org');
   *     request.onLoad.listen((event) => print(
   *         'Request complete ${event.target.reponseText}'));
   *     request.send();
   *
   * is the (more verbose) equivalent of
   *
   *     HttpRequest.getString('http://dartlang.org').then(
   *         (result) => print('Request complete: $result'));
   */
  @DomName('XMLHttpRequest.XMLHttpRequest')
  @DocsEditable()
  factory HttpRequest() {
    return HttpRequest._create_1();
  }
  static HttpRequest _create_1() => JS('HttpRequest', 'new XMLHttpRequest()');

  @DomName('XMLHttpRequest.DONE')
  @DocsEditable()
  static const int DONE = 4;

  @DomName('XMLHttpRequest.HEADERS_RECEIVED')
  @DocsEditable()
  static const int HEADERS_RECEIVED = 2;

  @DomName('XMLHttpRequest.LOADING')
  @DocsEditable()
  static const int LOADING = 3;

  @DomName('XMLHttpRequest.OPENED')
  @DocsEditable()
  static const int OPENED = 1;

  @DomName('XMLHttpRequest.UNSENT')
  @DocsEditable()
  static const int UNSENT = 0;

  /**
   * Indicator of the current state of the request:
   *
   * <table>
   *   <tr>
   *     <td>Value</td>
   *     <td>State</td>
   *     <td>Meaning</td>
   *   </tr>
   *   <tr>
   *     <td>0</td>
   *     <td>unsent</td>
   *     <td><code>open()</code> has not yet been called</td>
   *   </tr>
   *   <tr>
   *     <td>1</td>
   *     <td>opened</td>
   *     <td><code>send()</code> has not yet been called</td>
   *   </tr>
   *   <tr>
   *     <td>2</td>
   *     <td>headers received</td>
   *     <td><code>sent()</code> has been called; response headers and <code>status</code> are available</td>
   *   </tr>
   *   <tr>
   *     <td>3</td> <td>loading</td> <td><code>responseText</code> holds some data</td>
   *   </tr>
   *   <tr>
   *     <td>4</td> <td>done</td> <td>request is complete</td>
   *   </tr>
   * </table>
   */
  @DomName('XMLHttpRequest.readyState')
  @DocsEditable()
  final int readyState;

  /**
   * The data received as a reponse from the request.
   *
   * The data could be in the
   * form of a [String], [ByteBuffer], [Document], [Blob], or json (also a
   * [String]). `null` indicates request failure.
   */
  @DomName('XMLHttpRequest.response')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  dynamic get response => _convertNativeToDart_XHR_Response(this._get_response);
  @JSName('response')
  /**
   * The data received as a reponse from the request.
   *
   * The data could be in the
   * form of a [String], [ByteBuffer], [Document], [Blob], or json (also a
   * [String]). `null` indicates request failure.
   */
  @DomName('XMLHttpRequest.response')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Creates('NativeByteBuffer|Blob|Document|=Object|JSExtendableArray|String|num')
  final dynamic _get_response;

  /**
   * The response in String form or empty String on failure.
   */
  @DomName('XMLHttpRequest.responseText')
  @DocsEditable()
  final String responseText;

  /**
   * [String] telling the server the desired response format.
   *
   * Default is `String`.
   * Other options are one of 'arraybuffer', 'blob', 'document', 'json',
   * 'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if
   * `responseType` is set while performing a synchronous request.
   *
   * See also: [MDN responseType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType)
   */
  @DomName('XMLHttpRequest.responseType')
  @DocsEditable()
  String responseType;

  @JSName('responseXML')
  /**
   * The request response, or null on failure.
   *
   * The response is processed as
   * `text/xml` stream, unless responseType = 'document' and the request is
   * synchronous.
   */
  @DomName('XMLHttpRequest.responseXML')
  @DocsEditable()
  final Document responseXml;

  /**
   * The http result code from the request (200, 404, etc).
   * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
   */
  @DomName('XMLHttpRequest.status')
  @DocsEditable()
  final int status;

  /**
   * The request response string (such as \"200 OK\").
   * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
   */
  @DomName('XMLHttpRequest.statusText')
  @DocsEditable()
  final String statusText;

  /**
   * Length of time before a request is automatically terminated.
   *
   * When the time has passed, a [TimeoutEvent] is dispatched.
   *
   * If [timeout] is set to 0, then the request will not time out.
   *
   * ## Other resources
   *
   * * [XMLHttpRequest.timeout]
   * (https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#timeout)
   * from MDN.
   * * [The timeout attribute]
   * (http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute)
   * from W3C.
   */
  @DomName('XMLHttpRequest.timeout')
  @DocsEditable()
  @Experimental() // untriaged
  int timeout;

  /**
   * [EventTarget] that can hold listeners to track the progress of the request.
   * The events fired will be members of [HttpRequestUploadEvents].
   */
  @DomName('XMLHttpRequest.upload')
  @DocsEditable()
  @Unstable()
  final HttpRequestUpload upload;

  /**
   * True if cross-site requests should use credentials such as cookies
   * or authorization headers; false otherwise.
   *
   * This value is ignored for same-site requests.
   */
  @DomName('XMLHttpRequest.withCredentials')
  @DocsEditable()
  bool withCredentials;

  /**
   * Stop the current request.
   *
   * The request can only be stopped if readyState is `HEADERS_RECIEVED` or
   * `LOADING`. If this method is not in the process of being sent, the method
   * has no effect.
   */
  @DomName('XMLHttpRequest.abort')
  @DocsEditable()
  void abort() native;

  /**
   * Retrieve all the response headers from a request.
   *
   * `null` if no headers have been received. For multipart requests,
   * `getAllResponseHeaders` will return the response headers for the current
   * part of the request.
   *
   * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)
   * for a list of common response headers.
   */
  @DomName('XMLHttpRequest.getAllResponseHeaders')
  @DocsEditable()
  @Unstable()
  String getAllResponseHeaders() native;

  /**
   * Return the response header named `header`, or null if not found.
   *
   * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)
   * for a list of common response headers.
   */
  @DomName('XMLHttpRequest.getResponseHeader')
  @DocsEditable()
  @Unstable()
  String getResponseHeader(String header) native;

  /**
   * Specify the desired `url`, and `method` to use in making the request.
   *
   * By default the request is done asyncronously, with no user or password
   * authentication information. If `async` is false, the request will be send
   * synchronously.
   *
   * Calling `open` again on a currently active request is equivalent to
   * calling `abort`.
   *
   * Note: Most simple HTTP requests can be accomplished using the [getString],
   * [request], [requestCrossOrigin], or [postFormData] methods. Use of this
   * `open` method is intended only for more complext HTTP requests where
   * finer-grained control is needed.
   */
  @DomName('XMLHttpRequest.open')
  @DocsEditable()
  void open(String method, String url, {bool async, String user, String password}) native;

  /**
   * Specify a particular MIME type (such as `text/xml`) desired for the
   * response.
   *
   * This value must be set before the request has been sent. See also the list
   * of [common MIME types](http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types)
   */
  @DomName('XMLHttpRequest.overrideMimeType')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void overrideMimeType(String override) native;

  /**
   * Send the request with any given `data`.
   *
   * Note: Most simple HTTP requests can be accomplished using the [getString],
   * [request], [requestCrossOrigin], or [postFormData] methods. Use of this
   * `send` method is intended only for more complext HTTP requests where
   * finer-grained control is needed.
   *
   * ## Other resources
   *
   * * [XMLHttpRequest.send]
   * (https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
   * from MDN.
   */
  @DomName('XMLHttpRequest.send')
  @DocsEditable()
  void send([data]) native;

  /**
   * Sets the value of an HTTP requst header.
   *
   * This method should be called after the request is opened, but before
   * the request is sent.
   *
   * Multiple calls with the same header will combine all their values into a
   * single header.
   *
   * ## Other resources
   *
   * * [XMLHttpRequest.setRequestHeader]
   * (https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
   * from MDN.
   * * [The setRequestHeader() method]
   * (http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method) from
   * W3C.
   */
  @DomName('XMLHttpRequest.setRequestHeader')
  @DocsEditable()
  void setRequestHeader(String header, String value) native;

  /// Stream of `readystatechange` events handled by this [HttpRequest].
/**
   * Event listeners to be notified every time the [HttpRequest]
   * object's `readyState` changes values.
   */
  @DomName('XMLHttpRequest.onreadystatechange')
  @DocsEditable()
  Stream<ProgressEvent> get onReadyStateChange => readyStateChangeEvent.forTarget(this);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('XMLHttpRequestEventTarget')
@Experimental() // untriaged
class HttpRequestEventTarget extends EventTarget native "XMLHttpRequestEventTarget" {
  // To suppress missing implicit constructor warnings.
  factory HttpRequestEventTarget._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `abort` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequestEventTarget.abortEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<ProgressEvent> abortEvent = const EventStreamProvider<ProgressEvent>('abort');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequestEventTarget.errorEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<ProgressEvent> errorEvent = const EventStreamProvider<ProgressEvent>('error');

  /**
   * Static factory designed to expose `load` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequestEventTarget.loadEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<ProgressEvent> loadEvent = const EventStreamProvider<ProgressEvent>('load');

  /**
   * Static factory designed to expose `loadend` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequestEventTarget.loadendEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<ProgressEvent> loadEndEvent = const EventStreamProvider<ProgressEvent>('loadend');

  /**
   * Static factory designed to expose `loadstart` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequestEventTarget.loadstartEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<ProgressEvent> loadStartEvent = const EventStreamProvider<ProgressEvent>('loadstart');

  /**
   * Static factory designed to expose `progress` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequestEventTarget.progressEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<ProgressEvent> progressEvent = const EventStreamProvider<ProgressEvent>('progress');

  /**
   * Static factory designed to expose `timeout` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequestEventTarget.timeoutEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<ProgressEvent> timeoutEvent = const EventStreamProvider<ProgressEvent>('timeout');

  /// Stream of `abort` events handled by this [HttpRequestEventTarget].
  @DomName('XMLHttpRequestEventTarget.onabort')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);

  /// Stream of `error` events handled by this [HttpRequestEventTarget].
  @DomName('XMLHttpRequestEventTarget.onerror')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<ProgressEvent> get onError => errorEvent.forTarget(this);

  /// Stream of `load` events handled by this [HttpRequestEventTarget].
  @DomName('XMLHttpRequestEventTarget.onload')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<ProgressEvent> get onLoad => loadEvent.forTarget(this);

  /// Stream of `loadend` events handled by this [HttpRequestEventTarget].
  @DomName('XMLHttpRequestEventTarget.onloadend')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental() // untriaged
  Stream<ProgressEvent> get onLoadEnd => loadEndEvent.forTarget(this);

  /// Stream of `loadstart` events handled by this [HttpRequestEventTarget].
  @DomName('XMLHttpRequestEventTarget.onloadstart')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<ProgressEvent> get onLoadStart => loadStartEvent.forTarget(this);

  /// Stream of `progress` events handled by this [HttpRequestEventTarget].
  @DomName('XMLHttpRequestEventTarget.onprogress')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental() // untriaged
  Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);

  /// Stream of `timeout` events handled by this [HttpRequestEventTarget].
  @DomName('XMLHttpRequestEventTarget.ontimeout')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<ProgressEvent> get onTimeout => timeoutEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('XMLHttpRequestUpload')
// http://xhr.spec.whatwg.org/#xmlhttprequestupload
@Experimental()
class HttpRequestUpload extends HttpRequestEventTarget native "XMLHttpRequestUpload" {
  // To suppress missing implicit constructor warnings.
  factory HttpRequestUpload._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLIFrameElement')
class IFrameElement extends HtmlElement native "HTMLIFrameElement" {
  // To suppress missing implicit constructor warnings.
  factory IFrameElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLIFrameElement.HTMLIFrameElement')
  @DocsEditable()
  factory IFrameElement() => document.createElement("iframe");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  IFrameElement.created() : super.created();

  @DomName('HTMLIFrameElement.contentWindow')
  @DocsEditable()
  WindowBase get contentWindow => _convertNativeToDart_Window(this._get_contentWindow);
  @JSName('contentWindow')
  @DomName('HTMLIFrameElement.contentWindow')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_contentWindow;

  @DomName('HTMLIFrameElement.height')
  @DocsEditable()
  String height;

  @DomName('HTMLIFrameElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLIFrameElement.sandbox')
  @DocsEditable()
  String sandbox;

  @DomName('HTMLIFrameElement.src')
  @DocsEditable()
  String src;

  @DomName('HTMLIFrameElement.srcdoc')
  @DocsEditable()
  String srcdoc;

  @DomName('HTMLIFrameElement.width')
  @DocsEditable()
  String width;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('ImageBitmap')
@Experimental() // untriaged
class ImageBitmap extends Interceptor native "ImageBitmap" {
  // To suppress missing implicit constructor warnings.
  factory ImageBitmap._() { throw new UnsupportedError("Not supported"); }

  @DomName('ImageBitmap.height')
  @DocsEditable()
  @Experimental() // untriaged
  final int height;

  @DomName('ImageBitmap.width')
  @DocsEditable()
  @Experimental() // untriaged
  final int width;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DomName('ImageData')
class ImageData extends Interceptor native "ImageData" {

  // To suppress missing implicit constructor warnings.
  factory ImageData._() { throw new UnsupportedError("Not supported"); }

  @DomName('ImageData.data')
  @DocsEditable()
  @Creates('NativeUint8ClampedList')
  @Returns('NativeUint8ClampedList')
  final List<int> data;

  @DomName('ImageData.height')
  @DocsEditable()
  final int height;

  @DomName('ImageData.width')
  @DocsEditable()
  final int width;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('HTMLImageElement')
class ImageElement extends HtmlElement implements CanvasImageSource native "HTMLImageElement" {
  // To suppress missing implicit constructor warnings.
  factory ImageElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLImageElement.HTMLImageElement')
  @DocsEditable()
  factory ImageElement({String src, int width, int height}) {
    var e = document.createElement("img");
    if (src != null) e.src = src;
    if (width != null) e.width = width;
    if (height != null) e.height = height;
    return e;
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ImageElement.created() : super.created();

  @DomName('HTMLImageElement.alt')
  @DocsEditable()
  String alt;

  @DomName('HTMLImageElement.complete')
  @DocsEditable()
  final bool complete;

  @DomName('HTMLImageElement.crossOrigin')
  @DocsEditable()
  String crossOrigin;

  @DomName('HTMLImageElement.height')
  @DocsEditable()
  int height;

  @DomName('HTMLImageElement.isMap')
  @DocsEditable()
  bool isMap;

  @DomName('HTMLImageElement.naturalHeight')
  @DocsEditable()
  final int naturalHeight;

  @DomName('HTMLImageElement.naturalWidth')
  @DocsEditable()
  final int naturalWidth;

  @DomName('HTMLImageElement.src')
  @DocsEditable()
  String src;

  @DomName('HTMLImageElement.srcset')
  @DocsEditable()
  @Experimental() // untriaged
  String srcset;

  @DomName('HTMLImageElement.useMap')
  @DocsEditable()
  String useMap;

  @DomName('HTMLImageElement.width')
  @DocsEditable()
  int width;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('InjectedScriptHost')
@Experimental() // untriaged
class InjectedScriptHost extends Interceptor native "InjectedScriptHost" {
  // 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')
class InputElement extends HtmlElement implements
    HiddenInputElement,
    SearchInputElement,
    TextInputElement,
    UrlInputElement,
    TelephoneInputElement,
    EmailInputElement,
    PasswordInputElement,
    DateInputElement,
    MonthInputElement,
    WeekInputElement,
    TimeInputElement,
    LocalDateTimeInputElement,
    NumberInputElement,
    RangeInputElement,
    CheckboxInputElement,
    RadioButtonInputElement,
    FileUploadInputElement,
    SubmitButtonInputElement,
    ImageButtonInputElement,
    ResetButtonInputElement,
    ButtonInputElement
     native "HTMLInputElement" {

  factory InputElement({String type}) {
    var e = document.createElement("input");
    if (type != null) {
      try {
        // IE throws an exception for unknown types.
        e.type = type;
      } catch(_) {}
    }
    return e;
  }

  // To suppress missing implicit constructor warnings.
  factory InputElement._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `speechchange` events to event
   * handlers that are not necessarily instances of [InputElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLInputElement.webkitSpeechChangeEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://lists.w3.org/Archives/Public/public-xg-htmlspeech/2011Feb/att-0020/api-draft.html#extending_html_elements
  static const EventStreamProvider<Event> speechChangeEvent = const EventStreamProvider<Event>('webkitSpeechChange');
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  InputElement.created() : super.created();

  @DomName('HTMLInputElement.accept')
  @DocsEditable()
  String accept;

  @DomName('HTMLInputElement.alt')
  @DocsEditable()
  String alt;

  @DomName('HTMLInputElement.autocomplete')
  @DocsEditable()
  String autocomplete;

  @DomName('HTMLInputElement.autofocus')
  @DocsEditable()
  bool autofocus;

  @DomName('HTMLInputElement.checked')
  @DocsEditable()
  bool checked;

  @DomName('HTMLInputElement.defaultChecked')
  @DocsEditable()
  bool defaultChecked;

  @DomName('HTMLInputElement.defaultValue')
  @DocsEditable()
  String defaultValue;

  @DomName('HTMLInputElement.dirName')
  @DocsEditable()
  String dirName;

  @DomName('HTMLInputElement.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('HTMLInputElement.files')
  @DocsEditable()
  @Returns('FileList')
  @Creates('FileList')
  List<File> files;

  @DomName('HTMLInputElement.form')
  @DocsEditable()
  final FormElement form;

  @DomName('HTMLInputElement.formAction')
  @DocsEditable()
  String formAction;

  @DomName('HTMLInputElement.formEnctype')
  @DocsEditable()
  String formEnctype;

  @DomName('HTMLInputElement.formMethod')
  @DocsEditable()
  String formMethod;

  @DomName('HTMLInputElement.formNoValidate')
  @DocsEditable()
  bool formNoValidate;

  @DomName('HTMLInputElement.formTarget')
  @DocsEditable()
  String formTarget;

  @DomName('HTMLInputElement.height')
  @DocsEditable()
  int height;

  @DomName('HTMLInputElement.incremental')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  bool incremental;

  @DomName('HTMLInputElement.indeterminate')
  @DocsEditable()
  bool indeterminate;

  @DomName('HTMLInputElement.inputMode')
  @DocsEditable()
  @Experimental() // untriaged
  String inputMode;

  @DomName('HTMLInputElement.labels')
  @DocsEditable()
  @Returns('NodeList')
  @Creates('NodeList')
  final List<Node> labels;

  @DomName('HTMLInputElement.list')
  @DocsEditable()
  final HtmlElement list;

  @DomName('HTMLInputElement.max')
  @DocsEditable()
  String max;

  @DomName('HTMLInputElement.maxLength')
  @DocsEditable()
  int maxLength;

  @DomName('HTMLInputElement.min')
  @DocsEditable()
  String min;

  @DomName('HTMLInputElement.multiple')
  @DocsEditable()
  bool multiple;

  @DomName('HTMLInputElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLInputElement.pattern')
  @DocsEditable()
  String pattern;

  @DomName('HTMLInputElement.placeholder')
  @DocsEditable()
  String placeholder;

  @DomName('HTMLInputElement.readOnly')
  @DocsEditable()
  bool readOnly;

  @DomName('HTMLInputElement.required')
  @DocsEditable()
  bool required;

  @DomName('HTMLInputElement.selectionDirection')
  @DocsEditable()
  String selectionDirection;

  @DomName('HTMLInputElement.selectionEnd')
  @DocsEditable()
  int selectionEnd;

  @DomName('HTMLInputElement.selectionStart')
  @DocsEditable()
  int selectionStart;

  @DomName('HTMLInputElement.size')
  @DocsEditable()
  int size;

  @DomName('HTMLInputElement.src')
  @DocsEditable()
  String src;

  @DomName('HTMLInputElement.step')
  @DocsEditable()
  String step;

  @DomName('HTMLInputElement.type')
  @DocsEditable()
  String type;

  @DomName('HTMLInputElement.validationMessage')
  @DocsEditable()
  final String validationMessage;

  @DomName('HTMLInputElement.validity')
  @DocsEditable()
  final ValidityState validity;

  @DomName('HTMLInputElement.value')
  @DocsEditable()
  String value;

  @DomName('HTMLInputElement.valueAsDate')
  @DocsEditable()
  DateTime get valueAsDate => convertNativeToDart_DateTime(this._get_valueAsDate);
  @JSName('valueAsDate')
  @DomName('HTMLInputElement.valueAsDate')
  @DocsEditable()
  @Creates('Null')
  final dynamic _get_valueAsDate;

  void set valueAsDate(DateTime value) {
    this._set_valueAsDate = convertDartToNative_DateTime(value);
  }
  void set _set_valueAsDate(/*dynamic*/ value) {
    JS("void", "#.valueAsDate = #", this, value);
  }

  @DomName('HTMLInputElement.valueAsNumber')
  @DocsEditable()
  num valueAsNumber;

  @JSName('webkitEntries')
  @DomName('HTMLInputElement.webkitEntries')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#concept-input-type-file-selected
  final List<Entry> entries;

  @JSName('webkitdirectory')
  @DomName('HTMLInputElement.webkitdirectory')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://plus.sandbox.google.com/+AddyOsmani/posts/Dk5UhZ6zfF3
  bool directory;

  @DomName('HTMLInputElement.width')
  @DocsEditable()
  int width;

  @DomName('HTMLInputElement.willValidate')
  @DocsEditable()
  final bool willValidate;

  @DomName('HTMLInputElement.checkValidity')
  @DocsEditable()
  bool checkValidity() native;

  @DomName('HTMLInputElement.select')
  @DocsEditable()
  void select() native;

  @DomName('HTMLInputElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) native;

  @DomName('HTMLInputElement.setRangeText')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#dom-textarea/input-setrangetext
  @Experimental() // experimental
  void setRangeText(String replacement, {int start, int end, String selectionMode}) native;

  @DomName('HTMLInputElement.setSelectionRange')
  @DocsEditable()
  void setSelectionRange(int start, int end, [String direction]) native;

  @DomName('HTMLInputElement.stepDown')
  @DocsEditable()
  void stepDown([int n]) native;

  @DomName('HTMLInputElement.stepUp')
  @DocsEditable()
  void stepUp([int n]) native;

  /// Stream of `speechchange` events handled by this [InputElement].
  @DomName('HTMLInputElement.onwebkitSpeechChange')
  @DocsEditable()
  // http://lists.w3.org/Archives/Public/public-xg-htmlspeech/2011Feb/att-0020/api-draft.html#extending_html_elements
  @Experimental()
  ElementStream<Event> get onSpeechChange => speechChangeEvent.forElement(this);

}


// Interfaces representing the InputElement APIs which are supported
// for the various types of InputElement. From:
// http://www.w3.org/html/wg/drafts/html/master/forms.html#the-input-element.

/**
 * Exposes the functionality common between all InputElement types.
 */
abstract class InputElementBase implements Element {
  @DomName('HTMLInputElement.autofocus')
  bool autofocus;

  @DomName('HTMLInputElement.disabled')
  bool disabled;

  @DomName('HTMLInputElement.incremental')
  bool incremental;

  @DomName('HTMLInputElement.indeterminate')
  bool indeterminate;

  @DomName('HTMLInputElement.labels')
  List<Node> get labels;

  @DomName('HTMLInputElement.name')
  String name;

  @DomName('HTMLInputElement.validationMessage')
  String get validationMessage;

  @DomName('HTMLInputElement.validity')
  ValidityState get validity;

  @DomName('HTMLInputElement.value')
  String value;

  @DomName('HTMLInputElement.willValidate')
  bool get willValidate;

  @DomName('HTMLInputElement.checkValidity')
  bool checkValidity();

  @DomName('HTMLInputElement.setCustomValidity')
  void setCustomValidity(String error);
}

/**
 * Hidden input which is not intended to be seen or edited by the user.
 */
abstract class HiddenInputElement implements InputElementBase {
  factory HiddenInputElement() => new InputElement(type: 'hidden');
}


/**
 * Base interface for all inputs which involve text editing.
 */
abstract class TextInputElementBase implements InputElementBase {
  @DomName('HTMLInputElement.autocomplete')
  String autocomplete;

  @DomName('HTMLInputElement.maxLength')
  int maxLength;

  @DomName('HTMLInputElement.pattern')
  String pattern;

  @DomName('HTMLInputElement.placeholder')
  String placeholder;

  @DomName('HTMLInputElement.readOnly')
  bool readOnly;

  @DomName('HTMLInputElement.required')
  bool required;

  @DomName('HTMLInputElement.size')
  int size;

  @DomName('HTMLInputElement.select')
  void select();

  @DomName('HTMLInputElement.selectionDirection')
  String selectionDirection;

  @DomName('HTMLInputElement.selectionEnd')
  int selectionEnd;

  @DomName('HTMLInputElement.selectionStart')
  int selectionStart;

  @DomName('HTMLInputElement.setSelectionRange')
  void setSelectionRange(int start, int end, [String direction]);
}

/**
 * Similar to [TextInputElement], but on platforms where search is styled
 * differently this will get the search style.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
abstract class SearchInputElement implements TextInputElementBase {
  factory SearchInputElement() => new InputElement(type: 'search');

  @DomName('HTMLInputElement.dirName')
  String dirName;

  @DomName('HTMLInputElement.list')
  Element get list;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'search')).type == 'search';
  }
}

/**
 * A basic text input editor control.
 */
abstract class TextInputElement implements TextInputElementBase {
  factory TextInputElement() => new InputElement(type: 'text');

  @DomName('HTMLInputElement.dirName')
  String dirName;

  @DomName('HTMLInputElement.list')
  Element get list;
}

/**
 * A control for editing an absolute URL.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
abstract class UrlInputElement implements TextInputElementBase {
  factory UrlInputElement() => new InputElement(type: 'url');

  @DomName('HTMLInputElement.list')
  Element get list;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'url')).type == 'url';
  }
}

/**
 * Represents a control for editing a telephone number.
 *
 * This provides a single line of text with minimal formatting help since
 * there is a wide variety of telephone numbers.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
abstract class TelephoneInputElement implements TextInputElementBase {
  factory TelephoneInputElement() => new InputElement(type: 'tel');

  @DomName('HTMLInputElement.list')
  Element get list;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'tel')).type == 'tel';
  }
}

/**
 * An e-mail address or list of e-mail addresses.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
abstract class EmailInputElement implements TextInputElementBase {
  factory EmailInputElement() => new InputElement(type: 'email');

  @DomName('HTMLInputElement.autocomplete')
  String autocomplete;

  @DomName('HTMLInputElement.autofocus')
  bool autofocus;

  @DomName('HTMLInputElement.list')
  Element get list;

  @DomName('HTMLInputElement.maxLength')
  int maxLength;

  @DomName('HTMLInputElement.multiple')
  bool multiple;

  @DomName('HTMLInputElement.pattern')
  String pattern;

  @DomName('HTMLInputElement.placeholder')
  String placeholder;

  @DomName('HTMLInputElement.readOnly')
  bool readOnly;

  @DomName('HTMLInputElement.required')
  bool required;

  @DomName('HTMLInputElement.size')
  int size;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'email')).type == 'email';
  }
}

/**
 * Text with no line breaks (sensitive information).
 */
abstract class PasswordInputElement implements TextInputElementBase {
  factory PasswordInputElement() => new InputElement(type: 'password');
}

/**
 * Base interface for all input element types which involve ranges.
 */
abstract class RangeInputElementBase implements InputElementBase {

  @DomName('HTMLInputElement.list')
  Element get list;

  @DomName('HTMLInputElement.max')
  String max;

  @DomName('HTMLInputElement.min')
  String min;

  @DomName('HTMLInputElement.step')
  String step;

  @DomName('HTMLInputElement.valueAsNumber')
  num valueAsNumber;

  @DomName('HTMLInputElement.stepDown')
  void stepDown([int n]);

  @DomName('HTMLInputElement.stepUp')
  void stepUp([int n]);
}

/**
 * A date (year, month, day) with no time zone.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
abstract class DateInputElement implements RangeInputElementBase {
  factory DateInputElement() => new InputElement(type: 'date');

  @DomName('HTMLInputElement.valueAsDate')
  DateTime valueAsDate;

  @DomName('HTMLInputElement.readOnly')
  bool readOnly;

  @DomName('HTMLInputElement.required')
  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'date')).type == 'date';
  }
}

/**
 * A date consisting of a year and a month with no time zone.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
abstract class MonthInputElement implements RangeInputElementBase {
  factory MonthInputElement() => new InputElement(type: 'month');

  @DomName('HTMLInputElement.valueAsDate')
  DateTime valueAsDate;

  @DomName('HTMLInputElement.readOnly')
  bool readOnly;

  @DomName('HTMLInputElement.required')
  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'month')).type == 'month';
  }
}

/**
 * A date consisting of a week-year number and a week number with no time zone.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
abstract class WeekInputElement implements RangeInputElementBase {
  factory WeekInputElement() => new InputElement(type: 'week');

  @DomName('HTMLInputElement.valueAsDate')
  DateTime valueAsDate;

  @DomName('HTMLInputElement.readOnly')
  bool readOnly;

  @DomName('HTMLInputElement.required')
  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'week')).type == 'week';
  }
}

/**
 * A time (hour, minute, seconds, fractional seconds) with no time zone.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
abstract class TimeInputElement implements RangeInputElementBase {
  factory TimeInputElement() => new InputElement(type: 'time');

  @DomName('HTMLInputElement.valueAsDate')
  DateTime valueAsDate;

  @DomName('HTMLInputElement.readOnly')
  bool readOnly;

  @DomName('HTMLInputElement.required')
  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'time')).type == 'time';
  }
}

/**
 * A date and time (year, month, day, hour, minute, second, fraction of a
 * second) with no time zone.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
abstract class LocalDateTimeInputElement implements RangeInputElementBase {
  factory LocalDateTimeInputElement() =>
      new InputElement(type: 'datetime-local');

  @DomName('HTMLInputElement.readOnly')
  bool readOnly;

  @DomName('HTMLInputElement.required')
  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'datetime-local')).type == 'datetime-local';
  }
}

/**
 * A numeric editor control.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
abstract class NumberInputElement implements RangeInputElementBase {
  factory NumberInputElement() => new InputElement(type: 'number');

  @DomName('HTMLInputElement.placeholder')
  String placeholder;

  @DomName('HTMLInputElement.readOnly')
  bool readOnly;

  @DomName('HTMLInputElement.required')
  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'number')).type == 'number';
  }
}

/**
 * Similar to [NumberInputElement] but the browser may provide more optimal
 * styling (such as a slider control).
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE, '10')
@Experimental()
abstract class RangeInputElement implements RangeInputElementBase {
  factory RangeInputElement() => new InputElement(type: 'range');

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'range')).type == 'range';
  }
}

/**
 * A boolean editor control.
 *
 * Note that if [indeterminate] is set then this control is in a third
 * indeterminate state.
 */
abstract class CheckboxInputElement implements InputElementBase {
  factory CheckboxInputElement() => new InputElement(type: 'checkbox');

  @DomName('HTMLInputElement.checked')
  bool checked;

  @DomName('HTMLInputElement.required')
  bool required;
}


/**
 * A control that when used with other [ReadioButtonInputElement] controls
 * forms a radio button group in which only one control can be checked at a
 * time.
 *
 * Radio buttons are considered to be in the same radio button group if:
 *
 * * They are all of type 'radio'.
 * * They all have either the same [FormElement] owner, or no owner.
 * * Their name attributes contain the same name.
 */
abstract class RadioButtonInputElement implements InputElementBase {
  factory RadioButtonInputElement() => new InputElement(type: 'radio');

  @DomName('HTMLInputElement.checked')
  bool checked;

  @DomName('HTMLInputElement.required')
  bool required;
}

/**
 * A control for picking files from the user's computer.
 */
abstract class FileUploadInputElement implements InputElementBase {
  factory FileUploadInputElement() => new InputElement(type: 'file');

  @DomName('HTMLInputElement.accept')
  String accept;

  @DomName('HTMLInputElement.multiple')
  bool multiple;

  @DomName('HTMLInputElement.required')
  bool required;

  @DomName('HTMLInputElement.files')
  List<File> files;
}

/**
 * A button, which when clicked, submits the form.
 */
abstract class SubmitButtonInputElement implements InputElementBase {
  factory SubmitButtonInputElement() => new InputElement(type: 'submit');

  @DomName('HTMLInputElement.formAction')
  String formAction;

  @DomName('HTMLInputElement.formEnctype')
  String formEnctype;

  @DomName('HTMLInputElement.formMethod')
  String formMethod;

  @DomName('HTMLInputElement.formNoValidate')
  bool formNoValidate;

  @DomName('HTMLInputElement.formTarget')
  String formTarget;
}

/**
 * Either an image which the user can select a coordinate to or a form
 * submit button.
 */
abstract class ImageButtonInputElement implements InputElementBase {
  factory ImageButtonInputElement() => new InputElement(type: 'image');

  @DomName('HTMLInputElement.alt')
  String alt;

  @DomName('HTMLInputElement.formAction')
  String formAction;

  @DomName('HTMLInputElement.formEnctype')
  String formEnctype;

  @DomName('HTMLInputElement.formMethod')
  String formMethod;

  @DomName('HTMLInputElement.formNoValidate')
  bool formNoValidate;

  @DomName('HTMLInputElement.formTarget')
  String formTarget;

  @DomName('HTMLInputElement.height')
  int height;

  @DomName('HTMLInputElement.src')
  String src;

  @DomName('HTMLInputElement.width')
  int width;
}

/**
 * A button, which when clicked, resets the form.
 */
abstract class ResetButtonInputElement implements InputElementBase {
  factory ResetButtonInputElement() => new InputElement(type: 'reset');
}

/**
 * A button, with no default behavior.
 */
abstract class ButtonInputElement implements InputElementBase {
  factory ButtonInputElement() => new InputElement(type: 'button');
}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('InputMethodContext')
// http://www.w3.org/TR/ime-api/#idl-def-InputMethodContext
@Experimental()
class InputMethodContext extends EventTarget native "InputMethodContext" {
  // To suppress missing implicit constructor warnings.
  factory InputMethodContext._() { throw new UnsupportedError("Not supported"); }

  @DomName('InputMethodContext.compositionEndOffset')
  @DocsEditable()
  @Experimental() // untriaged
  final int compositionEndOffset;

  @DomName('InputMethodContext.compositionStartOffset')
  @DocsEditable()
  @Experimental() // untriaged
  final int compositionStartOffset;

  @DomName('InputMethodContext.locale')
  @DocsEditable()
  final String locale;

  @DomName('InputMethodContext.target')
  @DocsEditable()
  @Experimental() // untriaged
  final HtmlElement target;

  @DomName('InputMethodContext.confirmComposition')
  @DocsEditable()
  void confirmComposition() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('InstallEvent')
@Experimental() // untriaged
class InstallEvent extends InstallPhaseEvent native "InstallEvent" {
  // To suppress missing implicit constructor warnings.
  factory InstallEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('InstallEvent.replace')
  @DocsEditable()
  @Experimental() // untriaged
  void replace() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('InstallPhaseEvent')
@Experimental() // untriaged
class InstallPhaseEvent extends Event native "InstallPhaseEvent" {
  // To suppress missing implicit constructor warnings.
  factory InstallPhaseEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('InstallPhaseEvent.waitUntil')
  @DocsEditable()
  @Experimental() // untriaged
  void waitUntil(Object value) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('KeyPair')
@Experimental() // untriaged
class KeyPair extends Interceptor native "KeyPair" {
  // To suppress missing implicit constructor warnings.
  factory KeyPair._() { throw new UnsupportedError("Not supported"); }

  @DomName('KeyPair.privateKey')
  @DocsEditable()
  @Experimental() // untriaged
  final CryptoKey privateKey;

  @DomName('KeyPair.publicKey')
  @DocsEditable()
  @Experimental() // untriaged
  final CryptoKey publicKey;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * An event that describes user interaction with the keyboard.
 *
 * The [type] of the event identifies what kind of interaction occurred.
 *
 * See also:
 *
 * * [KeyboardEvent](https://developer.mozilla.org/en/DOM/KeyboardEvent) at MDN.
 */
@DomName('KeyboardEvent')
class KeyboardEvent extends UIEvent native "KeyboardEvent" {

  /** 
   * Programmatically create a KeyboardEvent. 
   *
   * Due to browser differences, keyCode, charCode, or keyIdentifier values
   * cannot be specified in this base level constructor. This constructor
   * enables the user to programmatically create and dispatch a [KeyboardEvent],
   * but it will not contain any particular key content. For programmatically
   * creating keyboard events with specific key value contents, see the custom
   * Event [KeyEvent]. 
   */
  factory KeyboardEvent(String type,
      {Window view, bool canBubble: true, bool cancelable: true,
      int keyLocation: 1, bool ctrlKey: false,
      bool altKey: false, bool shiftKey: false, bool metaKey: false,
      bool altGraphKey: false}) {
    if (view == null) {
      view = window;
    }
    final e = document._createEvent("KeyboardEvent");
    e._initKeyboardEvent(type, canBubble, cancelable, view, "",
        keyLocation, ctrlKey, altKey, shiftKey, metaKey, altGraphKey);
    return e;
  }

  @DomName('KeyboardEvent.initKeyboardEvent')
  void _initKeyboardEvent(String type, bool canBubble, bool cancelable,
      Window view, String keyIdentifier, int keyLocation, bool ctrlKey,
      bool altKey, bool shiftKey, bool metaKey, bool altGraphKey) {
    if (JS('bool', 'typeof(#.initKeyEvent) == "function"', this)) {
      // initKeyEvent is only in Firefox (instead of initKeyboardEvent). It has
      // a slightly different signature, and allows you to specify keyCode and
      // charCode as the last two arguments, but we just set them as the default
      // since they can't be specified in other browsers.
      JS('void', '#.initKeyEvent(#, #, #, #, #, #, #, #, 0, 0)', this,
          type, canBubble, cancelable, view,
          ctrlKey, altKey, shiftKey, metaKey);
    } else {
      // initKeyboardEvent is for all other browsers.
      JS('void', '#.initKeyboardEvent(#, #, #, #, #, #, #, #, #, #, #)', this,
          type, canBubble, cancelable, view, keyIdentifier, keyLocation,
          ctrlKey, altKey, shiftKey, metaKey, altGraphKey);
    }
  }

  @DomName('KeyboardEvent.keyCode')
  int get keyCode => _keyCode;

  @DomName('KeyboardEvent.charCode')
  int get charCode => _charCode;
  // To suppress missing implicit constructor warnings.
  factory KeyboardEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('KeyboardEvent.DOM_KEY_LOCATION_LEFT')
  @DocsEditable()
  @Experimental() // untriaged
  static const int DOM_KEY_LOCATION_LEFT = 0x01;

  @DomName('KeyboardEvent.DOM_KEY_LOCATION_NUMPAD')
  @DocsEditable()
  @Experimental() // untriaged
  static const int DOM_KEY_LOCATION_NUMPAD = 0x03;

  @DomName('KeyboardEvent.DOM_KEY_LOCATION_RIGHT')
  @DocsEditable()
  @Experimental() // untriaged
  static const int DOM_KEY_LOCATION_RIGHT = 0x02;

  @DomName('KeyboardEvent.DOM_KEY_LOCATION_STANDARD')
  @DocsEditable()
  @Experimental() // untriaged
  static const int DOM_KEY_LOCATION_STANDARD = 0x00;

  @DomName('KeyboardEvent.altGraphKey')
  @DocsEditable()
  @Experimental() // nonstandard
  final bool altGraphKey;

  @DomName('KeyboardEvent.altKey')
  @DocsEditable()
  final bool altKey;

  @DomName('KeyboardEvent.ctrlKey')
  @DocsEditable()
  final bool ctrlKey;

  @JSName('keyIdentifier')
  @DomName('KeyboardEvent.keyIdentifier')
  @DocsEditable()
  @Experimental() // nonstandard
  final String _keyIdentifier;

  @DomName('KeyboardEvent.keyLocation')
  @DocsEditable()
  @Experimental() // nonstandard
  final int keyLocation;

  @DomName('KeyboardEvent.location')
  @DocsEditable()
  @Experimental() // untriaged
  final int location;

  @DomName('KeyboardEvent.metaKey')
  @DocsEditable()
  final bool metaKey;

  @DomName('KeyboardEvent.repeat')
  @DocsEditable()
  @Experimental() // untriaged
  final bool repeat;

  @DomName('KeyboardEvent.shiftKey')
  @DocsEditable()
  final bool shiftKey;

  @DomName('KeyboardEvent.getModifierState')
  @DocsEditable()
  @Experimental() // untriaged
  bool getModifierState(String keyArgument) native;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLKeygenElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#the-keygen-element
class KeygenElement extends HtmlElement native "HTMLKeygenElement" {
  // To suppress missing implicit constructor warnings.
  factory KeygenElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLKeygenElement.HTMLKeygenElement')
  @DocsEditable()
  factory KeygenElement() => document.createElement("keygen");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  KeygenElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('keygen') && (new Element.tag('keygen') is KeygenElement);

  @DomName('HTMLKeygenElement.autofocus')
  @DocsEditable()
  bool autofocus;

  @DomName('HTMLKeygenElement.challenge')
  @DocsEditable()
  String challenge;

  @DomName('HTMLKeygenElement.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('HTMLKeygenElement.form')
  @DocsEditable()
  final FormElement form;

  @DomName('HTMLKeygenElement.keytype')
  @DocsEditable()
  String keytype;

  @DomName('HTMLKeygenElement.labels')
  @DocsEditable()
  @Unstable()
  @Returns('NodeList')
  @Creates('NodeList')
  final List<Node> labels;

  @DomName('HTMLKeygenElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLKeygenElement.type')
  @DocsEditable()
  final String type;

  @DomName('HTMLKeygenElement.validationMessage')
  @DocsEditable()
  final String validationMessage;

  @DomName('HTMLKeygenElement.validity')
  @DocsEditable()
  final ValidityState validity;

  @DomName('HTMLKeygenElement.willValidate')
  @DocsEditable()
  final bool willValidate;

  @DomName('HTMLKeygenElement.checkValidity')
  @DocsEditable()
  bool checkValidity() native;

  @DomName('HTMLKeygenElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLLIElement')
class LIElement extends HtmlElement native "HTMLLIElement" {
  // To suppress missing implicit constructor warnings.
  factory LIElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLLIElement.HTMLLIElement')
  @DocsEditable()
  factory LIElement() => document.createElement("li");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  LIElement.created() : super.created();

  @DomName('HTMLLIElement.value')
  @DocsEditable()
  int value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLLabelElement')
class LabelElement extends HtmlElement native "HTMLLabelElement" {
  // To suppress missing implicit constructor warnings.
  factory LabelElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLLabelElement.HTMLLabelElement')
  @DocsEditable()
  factory LabelElement() => document.createElement("label");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  LabelElement.created() : super.created();

  @DomName('HTMLLabelElement.control')
  @DocsEditable()
  final HtmlElement control;

  @DomName('HTMLLabelElement.form')
  @DocsEditable()
  final FormElement form;

  @DomName('HTMLLabelElement.htmlFor')
  @DocsEditable()
  String htmlFor;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLLegendElement')
class LegendElement extends HtmlElement native "HTMLLegendElement" {
  // To suppress missing implicit constructor warnings.
  factory LegendElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLLegendElement.HTMLLegendElement')
  @DocsEditable()
  factory LegendElement() => document.createElement("legend");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  LegendElement.created() : super.created();

  @DomName('HTMLLegendElement.form')
  @DocsEditable()
  final FormElement form;
}
// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLLinkElement')
class LinkElement extends HtmlElement native "HTMLLinkElement" {
  // To suppress missing implicit constructor warnings.
  factory LinkElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLLinkElement.HTMLLinkElement')
  @DocsEditable()
  factory LinkElement() => document.createElement("link");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  LinkElement.created() : super.created();

  @DomName('HTMLLinkElement.crossOrigin')
  @DocsEditable()
  @Experimental() // untriaged
  String crossOrigin;

  @DomName('HTMLLinkElement.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('HTMLLinkElement.href')
  @DocsEditable()
  String href;

  @DomName('HTMLLinkElement.hreflang')
  @DocsEditable()
  String hreflang;

  @DomName('HTMLLinkElement.import')
  @DocsEditable()
  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/imports/index.html#interface-import
  @Experimental()
  final Document import;

  @DomName('HTMLLinkElement.media')
  @DocsEditable()
  String media;

  @DomName('HTMLLinkElement.rel')
  @DocsEditable()
  String rel;

  @DomName('HTMLLinkElement.sheet')
  @DocsEditable()
  final StyleSheet sheet;

  @DomName('HTMLLinkElement.sizes')
  @DocsEditable()
  final DomSettableTokenList sizes;

  @DomName('HTMLLinkElement.type')
  @DocsEditable()
  String type;


    /// Checks if HTML imports are supported on the current platform.
  bool get supportsImport {
    return JS('bool', '("import" in #)', this);
  }
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('Location')
class Location extends Interceptor implements LocationBase native "Location" {
  // To suppress missing implicit constructor warnings.
  factory Location._() { throw new UnsupportedError("Not supported"); }

  @DomName('Location.ancestorOrigins')
  @DocsEditable()
  @Experimental() // nonstandard
  @Returns('DomStringList')
  @Creates('DomStringList')
  final List<String> ancestorOrigins;

  @DomName('Location.hash')
  @DocsEditable()
  String hash;

  @DomName('Location.host')
  @DocsEditable()
  String host;

  @DomName('Location.hostname')
  @DocsEditable()
  String hostname;

  @DomName('Location.href')
  @DocsEditable()
  String href;

  @DomName('Location.pathname')
  @DocsEditable()
  String pathname;

  @DomName('Location.port')
  @DocsEditable()
  String port;

  @DomName('Location.protocol')
  @DocsEditable()
  String protocol;

  @DomName('Location.search')
  @DocsEditable()
  String search;

  @DomName('Location.assign')
  @DocsEditable()
  void assign(String url) native;

  @DomName('Location.reload')
  @DocsEditable()
  void reload() native;

  @DomName('Location.replace')
  @DocsEditable()
  void replace(String url) native;

  @DomName('Location.toString')
  @DocsEditable()
  String toString() native;


  @DomName('Location.origin')
  String get origin {
    if (JS('bool', '("origin" in #)', this)) {
      return JS('String', '#.origin', this);
    }
    return '${this.protocol}//${this.host}';
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('MIDIErrorCallback')
// http://webaudio.github.io/web-midi-api/#midierrorcallback
@Experimental()
typedef void MidiErrorCallback(DomError error);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('MIDISuccessCallback')
@Experimental() // untriaged
typedef void MidiSuccessCallback(MidiAccess access, bool sysex);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLMapElement')
class MapElement extends HtmlElement native "HTMLMapElement" {
  // To suppress missing implicit constructor warnings.
  factory MapElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLMapElement.HTMLMapElement')
  @DocsEditable()
  factory MapElement() => document.createElement("map");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  MapElement.created() : super.created();

  @DomName('HTMLMapElement.areas')
  @DocsEditable()
  @Returns('HtmlCollection')
  @Creates('HtmlCollection')
  final List<Node> areas;

  @DomName('HTMLMapElement.name')
  @DocsEditable()
  String name;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MediaController')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#mediacontroller
@Experimental()
class MediaController extends EventTarget native "MediaController" {
  // To suppress missing implicit constructor warnings.
  factory MediaController._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaController.MediaController')
  @DocsEditable()
  factory MediaController() {
    return MediaController._create_1();
  }
  static MediaController _create_1() => JS('MediaController', 'new MediaController()');

  @DomName('MediaController.buffered')
  @DocsEditable()
  final TimeRanges buffered;

  @DomName('MediaController.currentTime')
  @DocsEditable()
  num currentTime;

  @DomName('MediaController.defaultPlaybackRate')
  @DocsEditable()
  num defaultPlaybackRate;

  @DomName('MediaController.duration')
  @DocsEditable()
  final double duration;

  @DomName('MediaController.muted')
  @DocsEditable()
  bool muted;

  @DomName('MediaController.paused')
  @DocsEditable()
  final bool paused;

  @DomName('MediaController.playbackRate')
  @DocsEditable()
  num playbackRate;

  @DomName('MediaController.playbackState')
  @DocsEditable()
  final String playbackState;

  @DomName('MediaController.played')
  @DocsEditable()
  final TimeRanges played;

  @DomName('MediaController.seekable')
  @DocsEditable()
  final TimeRanges seekable;

  @DomName('MediaController.volume')
  @DocsEditable()
  num volume;

  @DomName('MediaController.pause')
  @DocsEditable()
  void pause() native;

  @DomName('MediaController.play')
  @DocsEditable()
  void play() native;

  @DomName('MediaController.unpause')
  @DocsEditable()
  void unpause() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLMediaElement')
@Unstable()
class MediaElement extends HtmlElement native "HTMLMediaElement" {
  // To suppress missing implicit constructor warnings.
  factory MediaElement._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `canplay` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.canplayEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> canPlayEvent = const EventStreamProvider<Event>('canplay');

  /**
   * Static factory designed to expose `canplaythrough` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.canplaythroughEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> canPlayThroughEvent = const EventStreamProvider<Event>('canplaythrough');

  /**
   * Static factory designed to expose `durationchange` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.durationchangeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> durationChangeEvent = const EventStreamProvider<Event>('durationchange');

  /**
   * Static factory designed to expose `emptied` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.emptiedEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> emptiedEvent = const EventStreamProvider<Event>('emptied');

  /**
   * Static factory designed to expose `ended` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.endedEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');

  /**
   * Static factory designed to expose `loadeddata` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.loadeddataEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> loadedDataEvent = const EventStreamProvider<Event>('loadeddata');

  /**
   * Static factory designed to expose `loadedmetadata` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.loadedmetadataEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> loadedMetadataEvent = const EventStreamProvider<Event>('loadedmetadata');

  /**
   * Static factory designed to expose `loadstart` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.loadstartEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> loadStartEvent = const EventStreamProvider<Event>('loadstart');

  /**
   * Static factory designed to expose `pause` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.pauseEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> pauseEvent = const EventStreamProvider<Event>('pause');

  /**
   * Static factory designed to expose `play` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.playEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> playEvent = const EventStreamProvider<Event>('play');

  /**
   * Static factory designed to expose `playing` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.playingEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> playingEvent = const EventStreamProvider<Event>('playing');

  /**
   * Static factory designed to expose `progress` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.progressEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> progressEvent = const EventStreamProvider<Event>('progress');

  /**
   * Static factory designed to expose `ratechange` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.ratechangeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> rateChangeEvent = const EventStreamProvider<Event>('ratechange');

  /**
   * Static factory designed to expose `seeked` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.seekedEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> seekedEvent = const EventStreamProvider<Event>('seeked');

  /**
   * Static factory designed to expose `seeking` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.seekingEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> seekingEvent = const EventStreamProvider<Event>('seeking');

  /**
   * Static factory designed to expose `show` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.showEvent')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#event-media-loadstart
  @Experimental()
  static const EventStreamProvider<Event> showEvent = const EventStreamProvider<Event>('show');

  /**
   * Static factory designed to expose `stalled` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.stalledEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> stalledEvent = const EventStreamProvider<Event>('stalled');

  /**
   * Static factory designed to expose `suspend` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.suspendEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> suspendEvent = const EventStreamProvider<Event>('suspend');

  /**
   * Static factory designed to expose `timeupdate` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.timeupdateEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> timeUpdateEvent = const EventStreamProvider<Event>('timeupdate');

  /**
   * Static factory designed to expose `volumechange` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.volumechangeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> volumeChangeEvent = const EventStreamProvider<Event>('volumechange');

  /**
   * Static factory designed to expose `waiting` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.waitingEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> waitingEvent = const EventStreamProvider<Event>('waiting');

  /**
   * Static factory designed to expose `keyadded` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.webkitkeyaddedEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  static const EventStreamProvider<MediaKeyEvent> keyAddedEvent = const EventStreamProvider<MediaKeyEvent>('webkitkeyadded');

  /**
   * Static factory designed to expose `keyerror` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.webkitkeyerrorEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  static const EventStreamProvider<MediaKeyEvent> keyErrorEvent = const EventStreamProvider<MediaKeyEvent>('webkitkeyerror');

  /**
   * Static factory designed to expose `keymessage` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.webkitkeymessageEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  static const EventStreamProvider<MediaKeyEvent> keyMessageEvent = const EventStreamProvider<MediaKeyEvent>('webkitkeymessage');

  /**
   * Static factory designed to expose `needkey` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.webkitneedkeyEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  static const EventStreamProvider<MediaKeyEvent> needKeyEvent = const EventStreamProvider<MediaKeyEvent>('webkitneedkey');
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  MediaElement.created() : super.created();

  @DomName('HTMLMediaElement.HAVE_CURRENT_DATA')
  @DocsEditable()
  static const int HAVE_CURRENT_DATA = 2;

  @DomName('HTMLMediaElement.HAVE_ENOUGH_DATA')
  @DocsEditable()
  static const int HAVE_ENOUGH_DATA = 4;

  @DomName('HTMLMediaElement.HAVE_FUTURE_DATA')
  @DocsEditable()
  static const int HAVE_FUTURE_DATA = 3;

  @DomName('HTMLMediaElement.HAVE_METADATA')
  @DocsEditable()
  static const int HAVE_METADATA = 1;

  @DomName('HTMLMediaElement.HAVE_NOTHING')
  @DocsEditable()
  static const int HAVE_NOTHING = 0;

  @DomName('HTMLMediaElement.NETWORK_EMPTY')
  @DocsEditable()
  static const int NETWORK_EMPTY = 0;

  @DomName('HTMLMediaElement.NETWORK_IDLE')
  @DocsEditable()
  static const int NETWORK_IDLE = 1;

  @DomName('HTMLMediaElement.NETWORK_LOADING')
  @DocsEditable()
  static const int NETWORK_LOADING = 2;

  @DomName('HTMLMediaElement.NETWORK_NO_SOURCE')
  @DocsEditable()
  static const int NETWORK_NO_SOURCE = 3;

  @DomName('HTMLMediaElement.autoplay')
  @DocsEditable()
  bool autoplay;

  @DomName('HTMLMediaElement.buffered')
  @DocsEditable()
  final TimeRanges buffered;

  @DomName('HTMLMediaElement.controller')
  @DocsEditable()
  MediaController controller;

  @DomName('HTMLMediaElement.controls')
  @DocsEditable()
  bool controls;

  @DomName('HTMLMediaElement.crossOrigin')
  @DocsEditable()
  @Experimental() // untriaged
  String crossOrigin;

  @DomName('HTMLMediaElement.currentSrc')
  @DocsEditable()
  final String currentSrc;

  @DomName('HTMLMediaElement.currentTime')
  @DocsEditable()
  num currentTime;

  @DomName('HTMLMediaElement.defaultMuted')
  @DocsEditable()
  bool defaultMuted;

  @DomName('HTMLMediaElement.defaultPlaybackRate')
  @DocsEditable()
  num defaultPlaybackRate;

  @DomName('HTMLMediaElement.duration')
  @DocsEditable()
  final double duration;

  @DomName('HTMLMediaElement.ended')
  @DocsEditable()
  final bool ended;

  @DomName('HTMLMediaElement.error')
  @DocsEditable()
  final MediaError error;

  @DomName('HTMLMediaElement.loop')
  @DocsEditable()
  bool loop;

  @DomName('HTMLMediaElement.mediaGroup')
  @DocsEditable()
  String mediaGroup;

  @DomName('HTMLMediaElement.mediaKeys')
  @DocsEditable()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html
  @Experimental()
  final MediaKeys mediaKeys;

  @DomName('HTMLMediaElement.muted')
  @DocsEditable()
  bool muted;

  @DomName('HTMLMediaElement.networkState')
  @DocsEditable()
  final int networkState;

  @DomName('HTMLMediaElement.paused')
  @DocsEditable()
  final bool paused;

  @DomName('HTMLMediaElement.playbackRate')
  @DocsEditable()
  num playbackRate;

  @DomName('HTMLMediaElement.played')
  @DocsEditable()
  final TimeRanges played;

  @DomName('HTMLMediaElement.preload')
  @DocsEditable()
  String preload;

  @DomName('HTMLMediaElement.readyState')
  @DocsEditable()
  final int readyState;

  @DomName('HTMLMediaElement.seekable')
  @DocsEditable()
  final TimeRanges seekable;

  @DomName('HTMLMediaElement.seeking')
  @DocsEditable()
  final bool seeking;

  @DomName('HTMLMediaElement.src')
  @DocsEditable()
  String src;

  @DomName('HTMLMediaElement.textTracks')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-media-texttracks
  @Experimental()
  final TextTrackList textTracks;

  @DomName('HTMLMediaElement.volume')
  @DocsEditable()
  num volume;

  @JSName('webkitAudioDecodedByteCount')
  @DomName('HTMLMediaElement.webkitAudioDecodedByteCount')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // nonstandard
  final int audioDecodedByteCount;

  @JSName('webkitVideoDecodedByteCount')
  @DomName('HTMLMediaElement.webkitVideoDecodedByteCount')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // nonstandard
  final int videoDecodedByteCount;

  @DomName('HTMLMediaElement.addTextTrack')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-media-addtexttrack
  @Experimental()
  TextTrack addTextTrack(String kind, [String label, String language]) native;

  @DomName('HTMLMediaElement.canPlayType')
  @DocsEditable()
  @Unstable()
  String canPlayType(String type, [String keySystem]) native;

  @DomName('HTMLMediaElement.load')
  @DocsEditable()
  void load() native;

  @DomName('HTMLMediaElement.pause')
  @DocsEditable()
  void pause() native;

  @DomName('HTMLMediaElement.play')
  @DocsEditable()
  void play() native;

  @DomName('HTMLMediaElement.setMediaKeys')
  @DocsEditable()
  @Experimental() // untriaged
  void setMediaKeys(MediaKeys mediaKeys) native;

  @JSName('webkitAddKey')
  @DomName('HTMLMediaElement.webkitAddKey')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#extensions
  void addKey(String keySystem, Uint8List key, [Uint8List initData, String sessionId]) native;

  @JSName('webkitCancelKeyRequest')
  @DomName('HTMLMediaElement.webkitCancelKeyRequest')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#extensions
  void cancelKeyRequest(String keySystem, String sessionId) native;

  @JSName('webkitGenerateKeyRequest')
  @DomName('HTMLMediaElement.webkitGenerateKeyRequest')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#extensions
  void generateKeyRequest(String keySystem, [Uint8List initData]) native;

  /// Stream of `canplay` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.oncanplay')
  @DocsEditable()
  ElementStream<Event> get onCanPlay => canPlayEvent.forElement(this);

  /// Stream of `canplaythrough` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.oncanplaythrough')
  @DocsEditable()
  ElementStream<Event> get onCanPlayThrough => canPlayThroughEvent.forElement(this);

  /// Stream of `durationchange` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.ondurationchange')
  @DocsEditable()
  ElementStream<Event> get onDurationChange => durationChangeEvent.forElement(this);

  /// Stream of `emptied` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onemptied')
  @DocsEditable()
  ElementStream<Event> get onEmptied => emptiedEvent.forElement(this);

  /// Stream of `ended` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onended')
  @DocsEditable()
  ElementStream<Event> get onEnded => endedEvent.forElement(this);

  /// Stream of `loadeddata` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onloadeddata')
  @DocsEditable()
  ElementStream<Event> get onLoadedData => loadedDataEvent.forElement(this);

  /// Stream of `loadedmetadata` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onloadedmetadata')
  @DocsEditable()
  ElementStream<Event> get onLoadedMetadata => loadedMetadataEvent.forElement(this);

  /// Stream of `loadstart` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onloadstart')
  @DocsEditable()
  ElementStream<Event> get onLoadStart => loadStartEvent.forElement(this);

  /// Stream of `pause` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onpause')
  @DocsEditable()
  ElementStream<Event> get onPause => pauseEvent.forElement(this);

  /// Stream of `play` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onplay')
  @DocsEditable()
  ElementStream<Event> get onPlay => playEvent.forElement(this);

  /// Stream of `playing` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onplaying')
  @DocsEditable()
  ElementStream<Event> get onPlaying => playingEvent.forElement(this);

  /// Stream of `progress` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onprogress')
  @DocsEditable()
  ElementStream<Event> get onProgress => progressEvent.forElement(this);

  /// Stream of `ratechange` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onratechange')
  @DocsEditable()
  ElementStream<Event> get onRateChange => rateChangeEvent.forElement(this);

  /// Stream of `seeked` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onseeked')
  @DocsEditable()
  ElementStream<Event> get onSeeked => seekedEvent.forElement(this);

  /// Stream of `seeking` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onseeking')
  @DocsEditable()
  ElementStream<Event> get onSeeking => seekingEvent.forElement(this);

  /// Stream of `show` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onshow')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#event-media-loadstart
  @Experimental()
  ElementStream<Event> get onShow => showEvent.forElement(this);

  /// Stream of `stalled` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onstalled')
  @DocsEditable()
  ElementStream<Event> get onStalled => stalledEvent.forElement(this);

  /// Stream of `suspend` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onsuspend')
  @DocsEditable()
  ElementStream<Event> get onSuspend => suspendEvent.forElement(this);

  /// Stream of `timeupdate` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.ontimeupdate')
  @DocsEditable()
  ElementStream<Event> get onTimeUpdate => timeUpdateEvent.forElement(this);

  /// Stream of `volumechange` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onvolumechange')
  @DocsEditable()
  ElementStream<Event> get onVolumeChange => volumeChangeEvent.forElement(this);

  /// Stream of `waiting` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onwaiting')
  @DocsEditable()
  ElementStream<Event> get onWaiting => waitingEvent.forElement(this);

  /// Stream of `keyadded` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onwebkitkeyadded')
  @DocsEditable()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  @Experimental()
  ElementStream<MediaKeyEvent> get onKeyAdded => keyAddedEvent.forElement(this);

  /// Stream of `keyerror` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onwebkitkeyerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  @Experimental()
  ElementStream<MediaKeyEvent> get onKeyError => keyErrorEvent.forElement(this);

  /// Stream of `keymessage` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onwebkitkeymessage')
  @DocsEditable()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  @Experimental()
  ElementStream<MediaKeyEvent> get onKeyMessage => keyMessageEvent.forElement(this);

  /// Stream of `needkey` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onwebkitneedkey')
  @DocsEditable()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  @Experimental()
  ElementStream<MediaKeyEvent> get onNeedKey => needKeyEvent.forElement(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MediaError')
@Unstable()
class MediaError extends Interceptor native "MediaError" {
  // To suppress missing implicit constructor warnings.
  factory MediaError._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaError.MEDIA_ERR_ABORTED')
  @DocsEditable()
  static const int MEDIA_ERR_ABORTED = 1;

  @DomName('MediaError.MEDIA_ERR_DECODE')
  @DocsEditable()
  static const int MEDIA_ERR_DECODE = 3;

  @DomName('MediaError.MEDIA_ERR_ENCRYPTED')
  @DocsEditable()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#error-codes
  @Experimental()
  static const int MEDIA_ERR_ENCRYPTED = 5;

  @DomName('MediaError.MEDIA_ERR_NETWORK')
  @DocsEditable()
  static const int MEDIA_ERR_NETWORK = 2;

  @DomName('MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED')
  @DocsEditable()
  static const int MEDIA_ERR_SRC_NOT_SUPPORTED = 4;

  @DomName('MediaError.code')
  @DocsEditable()
  final int code;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MediaKeyError')
// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#error-codes
@Experimental()
class MediaKeyError extends Interceptor native "MediaKeyError" {
  // To suppress missing implicit constructor warnings.
  factory MediaKeyError._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaKeyError.MEDIA_KEYERR_CLIENT')
  @DocsEditable()
  static const int MEDIA_KEYERR_CLIENT = 2;

  @DomName('MediaKeyError.MEDIA_KEYERR_DOMAIN')
  @DocsEditable()
  static const int MEDIA_KEYERR_DOMAIN = 6;

  @DomName('MediaKeyError.MEDIA_KEYERR_HARDWARECHANGE')
  @DocsEditable()
  static const int MEDIA_KEYERR_HARDWARECHANGE = 5;

  @DomName('MediaKeyError.MEDIA_KEYERR_OUTPUT')
  @DocsEditable()
  static const int MEDIA_KEYERR_OUTPUT = 4;

  @DomName('MediaKeyError.MEDIA_KEYERR_SERVICE')
  @DocsEditable()
  static const int MEDIA_KEYERR_SERVICE = 3;

  @DomName('MediaKeyError.MEDIA_KEYERR_UNKNOWN')
  @DocsEditable()
  static const int MEDIA_KEYERR_UNKNOWN = 1;

  @DomName('MediaKeyError.code')
  @DocsEditable()
  final int code;

  @DomName('MediaKeyError.systemCode')
  @DocsEditable()
  @Experimental() // non-standard
  final int systemCode;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MediaKeyEvent')
// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#event-definitions
@Experimental()
class MediaKeyEvent extends Event native "MediaKeyEvent" {
  // To suppress missing implicit constructor warnings.
  factory MediaKeyEvent._() { throw new UnsupportedError("Not supported"); }

  @JSName('defaultURL')
  @DomName('MediaKeyEvent.defaultURL')
  @DocsEditable()
  final String defaultUrl;

  @DomName('MediaKeyEvent.errorCode')
  @DocsEditable()
  final MediaKeyError errorCode;

  @DomName('MediaKeyEvent.initData')
  @DocsEditable()
  final Uint8List initData;

  @DomName('MediaKeyEvent.keySystem')
  @DocsEditable()
  final String keySystem;

  @DomName('MediaKeyEvent.message')
  @DocsEditable()
  final Uint8List message;

  @DomName('MediaKeyEvent.sessionId')
  @DocsEditable()
  final String sessionId;

  @DomName('MediaKeyEvent.systemCode')
  @DocsEditable()
  final int systemCode;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MediaKeyMessageEvent')
// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-mediakeymessageevent
@Experimental()
class MediaKeyMessageEvent extends Event native "MediaKeyMessageEvent" {
  // To suppress missing implicit constructor warnings.
  factory MediaKeyMessageEvent._() { throw new UnsupportedError("Not supported"); }

  @JSName('destinationURL')
  @DomName('MediaKeyMessageEvent.destinationURL')
  @DocsEditable()
  final String destinationUrl;

  @DomName('MediaKeyMessageEvent.message')
  @DocsEditable()
  final Uint8List message;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MediaKeyNeededEvent')
// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-mediakeyneededevent
@Experimental()
class MediaKeyNeededEvent extends Event native "MediaKeyNeededEvent" {
  // To suppress missing implicit constructor warnings.
  factory MediaKeyNeededEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaKeyNeededEvent.contentType')
  @DocsEditable()
  @Experimental() // untriaged
  final String contentType;

  @DomName('MediaKeyNeededEvent.initData')
  @DocsEditable()
  final Uint8List initData;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MediaKeySession')
// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-mediakeysession
@Experimental()
class MediaKeySession extends EventTarget native "MediaKeySession" {
  // To suppress missing implicit constructor warnings.
  factory MediaKeySession._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaKeySession.error')
  @DocsEditable()
  final MediaKeyError error;

  @DomName('MediaKeySession.keySystem')
  @DocsEditable()
  final String keySystem;

  @DomName('MediaKeySession.sessionId')
  @DocsEditable()
  final String sessionId;

  @DomName('MediaKeySession.release')
  @DocsEditable()
  @Experimental() // untriaged
  void release() native;

  @DomName('MediaKeySession.update')
  @DocsEditable()
  void update(Uint8List response) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MediaKeys')
// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html
@Experimental()
class MediaKeys extends Interceptor native "MediaKeys" {
  // To suppress missing implicit constructor warnings.
  factory MediaKeys._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaKeys.MediaKeys')
  @DocsEditable()
  factory MediaKeys(String keySystem) {
    return MediaKeys._create_1(keySystem);
  }
  static MediaKeys _create_1(keySystem) => JS('MediaKeys', 'new MediaKeys(#)', keySystem);

  @DomName('MediaKeys.keySystem')
  @DocsEditable()
  final String keySystem;

  @DomName('MediaKeys.createSession')
  @DocsEditable()
  MediaKeySession createSession(String type, Uint8List initData) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MediaList')
@Unstable()
class MediaList extends Interceptor native "MediaList" {
  // To suppress missing implicit constructor warnings.
  factory MediaList._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaList.length')
  @DocsEditable()
  final int length;

  @DomName('MediaList.mediaText')
  @DocsEditable()
  String mediaText;

  @DomName('MediaList.appendMedium')
  @DocsEditable()
  void appendMedium(String newMedium) native;

  @DomName('MediaList.deleteMedium')
  @DocsEditable()
  void deleteMedium(String oldMedium) native;

  @DomName('MediaList.item')
  @DocsEditable()
  String item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MediaQueryList')
@Unstable()
class MediaQueryList extends Interceptor native "MediaQueryList" {
  // To suppress missing implicit constructor warnings.
  factory MediaQueryList._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaQueryList.matches')
  @DocsEditable()
  final bool matches;

  @DomName('MediaQueryList.media')
  @DocsEditable()
  final String media;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MediaSource')
// https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#mediasource
@Experimental()
class MediaSource extends EventTarget native "MediaSource" {
  // To suppress missing implicit constructor warnings.
  factory MediaSource._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaSource.MediaSource')
  @DocsEditable()
  factory MediaSource() {
    return MediaSource._create_1();
  }
  static MediaSource _create_1() => JS('MediaSource', 'new MediaSource()');

  @DomName('MediaSource.activeSourceBuffers')
  @DocsEditable()
  final SourceBufferList activeSourceBuffers;

  @DomName('MediaSource.duration')
  @DocsEditable()
  num duration;

  @DomName('MediaSource.readyState')
  @DocsEditable()
  final String readyState;

  @DomName('MediaSource.sourceBuffers')
  @DocsEditable()
  final SourceBufferList sourceBuffers;

  @DomName('MediaSource.addSourceBuffer')
  @DocsEditable()
  SourceBuffer addSourceBuffer(String type) native;

  @DomName('MediaSource.endOfStream')
  @DocsEditable()
  void endOfStream([String error]) native;

  @DomName('MediaSource.isTypeSupported')
  @DocsEditable()
  static bool isTypeSupported(String type) native;

  @DomName('MediaSource.removeSourceBuffer')
  @DocsEditable()
  void removeSourceBuffer(SourceBuffer buffer) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('MediaStream')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html#mediastream
class MediaStream extends EventTarget native "MediaStream" {
  // To suppress missing implicit constructor warnings.
  factory MediaStream._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `addtrack` events to event
   * handlers that are not necessarily instances of [MediaStream].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MediaStream.addtrackEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> addTrackEvent = const EventStreamProvider<Event>('addtrack');

  /**
   * Static factory designed to expose `ended` events to event
   * handlers that are not necessarily instances of [MediaStream].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MediaStream.endedEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');

  /**
   * Static factory designed to expose `removetrack` events to event
   * handlers that are not necessarily instances of [MediaStream].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MediaStream.removetrackEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> removeTrackEvent = const EventStreamProvider<Event>('removetrack');

  @DomName('MediaStream.MediaStream')
  @DocsEditable()
  factory MediaStream([stream_OR_tracks]) {
    if (stream_OR_tracks == null) {
      return MediaStream._create_1();
    }
    if ((stream_OR_tracks is MediaStream || stream_OR_tracks == null)) {
      return MediaStream._create_2(stream_OR_tracks);
    }
    if ((stream_OR_tracks is List<MediaStreamTrack> || stream_OR_tracks == null)) {
      return MediaStream._create_3(stream_OR_tracks);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static MediaStream _create_1() => JS('MediaStream', 'new MediaStream()');
  static MediaStream _create_2(stream_OR_tracks) => JS('MediaStream', 'new MediaStream(#)', stream_OR_tracks);
  static MediaStream _create_3(stream_OR_tracks) => JS('MediaStream', 'new MediaStream(#)', stream_OR_tracks);

  @DomName('MediaStream.ended')
  @DocsEditable()
  final bool ended;

  @DomName('MediaStream.id')
  @DocsEditable()
  final String id;

  @DomName('MediaStream.label')
  @DocsEditable()
  @Experimental() // non-standard
  final String label;

  @DomName('MediaStream.addTrack')
  @DocsEditable()
  void addTrack(MediaStreamTrack track) native;

  @DomName('MediaStream.getAudioTracks')
  @DocsEditable()
  @Creates('JSExtendableArray')
  @Returns('JSExtendableArray')
  List<MediaStreamTrack> getAudioTracks() native;

  @DomName('MediaStream.getTrackById')
  @DocsEditable()
  MediaStreamTrack getTrackById(String trackId) native;

  @DomName('MediaStream.getVideoTracks')
  @DocsEditable()
  @Creates('JSExtendableArray')
  @Returns('JSExtendableArray')
  List<MediaStreamTrack> getVideoTracks() native;

  @DomName('MediaStream.removeTrack')
  @DocsEditable()
  void removeTrack(MediaStreamTrack track) native;

  @DomName('MediaStream.stop')
  @DocsEditable()
  void stop() native;

  /// Stream of `addtrack` events handled by this [MediaStream].
  @DomName('MediaStream.onaddtrack')
  @DocsEditable()
  Stream<Event> get onAddTrack => addTrackEvent.forTarget(this);

  /// Stream of `ended` events handled by this [MediaStream].
  @DomName('MediaStream.onended')
  @DocsEditable()
  Stream<Event> get onEnded => endedEvent.forTarget(this);

  /// Stream of `removetrack` events handled by this [MediaStream].
  @DomName('MediaStream.onremovetrack')
  @DocsEditable()
  Stream<Event> get onRemoveTrack => removeTrackEvent.forTarget(this);


  /**
   * Checks if the MediaStream APIs are supported on the current platform.
   *
   * See also:
   *
   * * [Navigator.getUserMedia]
   */
  static bool get supported =>
    JS('bool', '''!!(#.getUserMedia || #.webkitGetUserMedia ||
        #.mozGetUserMedia || #.msGetUserMedia)''',
        window.navigator,
        window.navigator,
        window.navigator,
        window.navigator);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MediaStreamEvent')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html
class MediaStreamEvent extends Event native "MediaStreamEvent" {
  // To suppress missing implicit constructor warnings.
  factory MediaStreamEvent._() { throw new UnsupportedError("Not supported"); }

  /// Checks if this type is supported on the current platform.
  static bool get supported => Device.isEventTypeSupported('MediaStreamEvent');

  @DomName('MediaStreamEvent.stream')
  @DocsEditable()
  final MediaStream stream;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MediaStreamTrack')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html#mediastreamtrack
class MediaStreamTrack extends EventTarget native "MediaStreamTrack" {
  // To suppress missing implicit constructor warnings.
  factory MediaStreamTrack._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `ended` events to event
   * handlers that are not necessarily instances of [MediaStreamTrack].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MediaStreamTrack.endedEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');

  /**
   * Static factory designed to expose `mute` events to event
   * handlers that are not necessarily instances of [MediaStreamTrack].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MediaStreamTrack.muteEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> muteEvent = const EventStreamProvider<Event>('mute');

  /**
   * Static factory designed to expose `unmute` events to event
   * handlers that are not necessarily instances of [MediaStreamTrack].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MediaStreamTrack.unmuteEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> unmuteEvent = const EventStreamProvider<Event>('unmute');

  @DomName('MediaStreamTrack.enabled')
  @DocsEditable()
  bool enabled;

  @DomName('MediaStreamTrack.id')
  @DocsEditable()
  final String id;

  @DomName('MediaStreamTrack.kind')
  @DocsEditable()
  final String kind;

  @DomName('MediaStreamTrack.label')
  @DocsEditable()
  final String label;

  @DomName('MediaStreamTrack.readyState')
  @DocsEditable()
  final String readyState;

  @JSName('getSources')
  @DomName('MediaStreamTrack.getSources')
  @DocsEditable()
  @Experimental() // untriaged
  static void _getSources(MediaStreamTrackSourcesCallback callback) native;

  @JSName('getSources')
  @DomName('MediaStreamTrack.getSources')
  @DocsEditable()
  @Experimental() // untriaged
  static Future<List<SourceInfo>> getSources() {
    var completer = new Completer<List<SourceInfo>>();
    _getSources(
        (value) { completer.complete(value); });
    return completer.future;
  }

  @DomName('MediaStreamTrack.stop')
  @DocsEditable()
  @Experimental() // untriaged
  void stop() native;

  /// Stream of `ended` events handled by this [MediaStreamTrack].
  @DomName('MediaStreamTrack.onended')
  @DocsEditable()
  Stream<Event> get onEnded => endedEvent.forTarget(this);

  /// Stream of `mute` events handled by this [MediaStreamTrack].
  @DomName('MediaStreamTrack.onmute')
  @DocsEditable()
  Stream<Event> get onMute => muteEvent.forTarget(this);

  /// Stream of `unmute` events handled by this [MediaStreamTrack].
  @DomName('MediaStreamTrack.onunmute')
  @DocsEditable()
  Stream<Event> get onUnmute => unmuteEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MediaStreamTrackEvent')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html
class MediaStreamTrackEvent extends Event native "MediaStreamTrackEvent" {
  // To suppress missing implicit constructor warnings.
  factory MediaStreamTrackEvent._() { throw new UnsupportedError("Not supported"); }

  /// Checks if this type is supported on the current platform.
  static bool get supported => Device.isEventTypeSupported('MediaStreamTrackEvent');

  @DomName('MediaStreamTrackEvent.track')
  @DocsEditable()
  final MediaStreamTrack track;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('MediaStreamTrackSourcesCallback')
@Experimental() // untriaged
typedef void MediaStreamTrackSourcesCallback(List<SourceInfo> sources);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MemoryInfo')
@Experimental() // nonstandard
class MemoryInfo extends Interceptor native "MemoryInfo" {
  // To suppress missing implicit constructor warnings.
  factory MemoryInfo._() { throw new UnsupportedError("Not supported"); }

  @DomName('MemoryInfo.jsHeapSizeLimit')
  @DocsEditable()
  final int jsHeapSizeLimit;

  @DomName('MemoryInfo.totalJSHeapSize')
  @DocsEditable()
  final int totalJSHeapSize;

  @DomName('MemoryInfo.usedJSHeapSize')
  @DocsEditable()
  final int usedJSHeapSize;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
/**
 * An HTML <menu> element.
 *
 * A <menu> element represents an unordered list of menu commands.
 *
 * See also:
 *
 *  * [Menu Element](https://developer.mozilla.org/en-US/docs/HTML/Element/menu) from MDN.
 *  * [Menu Element](http://www.w3.org/TR/html5/the-menu-element.html#the-menu-element) from the W3C.
 */
@DomName('HTMLMenuElement')
class MenuElement extends HtmlElement native "HTMLMenuElement" {
  // To suppress missing implicit constructor warnings.
  factory MenuElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLMenuElement.HTMLMenuElement')
  @DocsEditable()
  factory MenuElement() => document.createElement("menu");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  MenuElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MessageChannel')
@Unstable()
class MessageChannel extends Interceptor native "MessageChannel" {
  // To suppress missing implicit constructor warnings.
  factory MessageChannel._() { throw new UnsupportedError("Not supported"); }

  @DomName('MessageChannel.port1')
  @DocsEditable()
  final MessagePort port1;

  @DomName('MessageChannel.port2')
  @DocsEditable()
  final MessagePort port2;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('MessageEvent')
class MessageEvent extends Event native "MessageEvent" {
  factory MessageEvent(String type,
      {bool canBubble: false, bool cancelable: false, Object data,
      String origin, String lastEventId,
      Window source, List messagePorts}) {
    if (source == null) {
      source = window;
    }
    var event = document._createEvent("MessageEvent");
    event._initMessageEvent(type, canBubble, cancelable, data, origin,
        lastEventId, source, messagePorts);
    return event;
  }
  // To suppress missing implicit constructor warnings.
  factory MessageEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('MessageEvent.data')
  @DocsEditable()
  dynamic get data => convertNativeToDart_SerializedScriptValue(this._get_data);
  @JSName('data')
  @DomName('MessageEvent.data')
  @DocsEditable()
  @annotation_Creates_SerializedScriptValue
  @annotation_Returns_SerializedScriptValue
  final dynamic _get_data;

  @DomName('MessageEvent.lastEventId')
  @DocsEditable()
  @Unstable()
  final String lastEventId;

  @DomName('MessageEvent.origin')
  @DocsEditable()
  final String origin;

  @DomName('MessageEvent.source')
  @DocsEditable()
  EventTarget get source => _convertNativeToDart_EventTarget(this._get_source);
  @JSName('source')
  @DomName('MessageEvent.source')
  @DocsEditable()
  @Creates('Null')
  @Returns('EventTarget|=Object')
  final dynamic _get_source;

  @JSName('initMessageEvent')
  @DomName('MessageEvent.initMessageEvent')
  @DocsEditable()
  void _initMessageEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Object dataArg, String originArg, String lastEventIdArg, Window sourceArg, List<MessagePort> messagePorts) native;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MessagePort')
@Unstable()
class MessagePort extends EventTarget native "MessagePort" {
  // To suppress missing implicit constructor warnings.
  factory MessagePort._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [MessagePort].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MessagePort.messageEvent')
  @DocsEditable()
  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');

  @DomName('MessagePort.close')
  @DocsEditable()
  void close() native;

  @DomName('MessagePort.postMessage')
  @DocsEditable()
  void postMessage(/*any*/ message, [List<MessagePort> messagePorts]) {
    if (messagePorts != null) {
      var message_1 = convertDartToNative_SerializedScriptValue(message);
      _postMessage_1(message_1, messagePorts);
      return;
    }
    var message_2 = convertDartToNative_SerializedScriptValue(message);
    _postMessage_2(message_2);
    return;
  }
  @JSName('postMessage')
  @DomName('MessagePort.postMessage')
  @DocsEditable()
  void _postMessage_1(message, List<MessagePort> messagePorts) native;
  @JSName('postMessage')
  @DomName('MessagePort.postMessage')
  @DocsEditable()
  void _postMessage_2(message) native;

  @DomName('MessagePort.start')
  @DocsEditable()
  void start() native;

  /// Stream of `message` events handled by this [MessagePort].
  @DomName('MessagePort.onmessage')
  @DocsEditable()
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLMetaElement')
class MetaElement extends HtmlElement native "HTMLMetaElement" {
  // To suppress missing implicit constructor warnings.
  factory MetaElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLMetaElement.HTMLMetaElement')
  @DocsEditable()
  factory MetaElement() => document.createElement("meta");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  MetaElement.created() : super.created();

  @DomName('HTMLMetaElement.content')
  @DocsEditable()
  String content;

  @DomName('HTMLMetaElement.httpEquiv')
  @DocsEditable()
  String httpEquiv;

  @DomName('HTMLMetaElement.name')
  @DocsEditable()
  String name;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('Metadata')
// http://www.w3.org/TR/file-system-api/#the-metadata-interface
@Experimental()
class Metadata extends Interceptor native "Metadata" {
  // To suppress missing implicit constructor warnings.
  factory Metadata._() { throw new UnsupportedError("Not supported"); }

  @DomName('Metadata.modificationTime')
  @DocsEditable()
  DateTime get modificationTime => convertNativeToDart_DateTime(this._get_modificationTime);
  @JSName('modificationTime')
  @DomName('Metadata.modificationTime')
  @DocsEditable()
  @Creates('Null')
  final dynamic _get_modificationTime;

  @DomName('Metadata.size')
  @DocsEditable()
  final int size;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('MetadataCallback')
// http://www.w3.org/TR/file-system-api/#idl-def-MetadataCallback
@Experimental()
typedef void MetadataCallback(Metadata metadata);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLMeterElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
class MeterElement extends HtmlElement native "HTMLMeterElement" {
  // To suppress missing implicit constructor warnings.
  factory MeterElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLMeterElement.HTMLMeterElement')
  @DocsEditable()
  factory MeterElement() => document.createElement("meter");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  MeterElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('meter');

  @DomName('HTMLMeterElement.high')
  @DocsEditable()
  num high;

  @DomName('HTMLMeterElement.labels')
  @DocsEditable()
  @Unstable()
  @Returns('NodeList')
  @Creates('NodeList')
  final List<Node> labels;

  @DomName('HTMLMeterElement.low')
  @DocsEditable()
  num low;

  @DomName('HTMLMeterElement.max')
  @DocsEditable()
  num max;

  @DomName('HTMLMeterElement.min')
  @DocsEditable()
  num min;

  @DomName('HTMLMeterElement.optimum')
  @DocsEditable()
  num optimum;

  @DomName('HTMLMeterElement.value')
  @DocsEditable()
  num value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MIDIAccess')
// http://webaudio.github.io/web-midi-api/#midiaccess-interface
@Experimental()
class MidiAccess extends EventTarget native "MIDIAccess" {
  // To suppress missing implicit constructor warnings.
  factory MidiAccess._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `connect` events to event
   * handlers that are not necessarily instances of [MidiAccess].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MIDIAccess.connectEvent')
  @DocsEditable()
  static const EventStreamProvider<MidiConnectionEvent> connectEvent = const EventStreamProvider<MidiConnectionEvent>('connect');

  /**
   * Static factory designed to expose `disconnect` events to event
   * handlers that are not necessarily instances of [MidiAccess].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MIDIAccess.disconnectEvent')
  @DocsEditable()
  static const EventStreamProvider<MidiConnectionEvent> disconnectEvent = const EventStreamProvider<MidiConnectionEvent>('disconnect');

  @DomName('MIDIAccess.inputs')
  @DocsEditable()
  List<MidiInput> inputs() native;

  @DomName('MIDIAccess.outputs')
  @DocsEditable()
  List<MidiOutput> outputs() native;

  /// Stream of `connect` events handled by this [MidiAccess].
  @DomName('MIDIAccess.onconnect')
  @DocsEditable()
  Stream<MidiConnectionEvent> get onConnect => connectEvent.forTarget(this);

  /// Stream of `disconnect` events handled by this [MidiAccess].
  @DomName('MIDIAccess.ondisconnect')
  @DocsEditable()
  Stream<MidiConnectionEvent> get onDisconnect => disconnectEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MIDIAccessPromise')
@Experimental() // untriaged
class MidiAccessPromise extends Interceptor native "MIDIAccessPromise" {
  // To suppress missing implicit constructor warnings.
  factory MidiAccessPromise._() { throw new UnsupportedError("Not supported"); }

  @DomName('MIDIAccessPromise.then')
  @DocsEditable()
  @Experimental() // untriaged
  void then(MidiSuccessCallback successCallback, MidiErrorCallback errorCallback) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MIDIConnectionEvent')
// http://webaudio.github.io/web-midi-api/#midiconnectionevent-interface
@Experimental()
class MidiConnectionEvent extends Event native "MIDIConnectionEvent" {
  // To suppress missing implicit constructor warnings.
  factory MidiConnectionEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('MIDIConnectionEvent.port')
  @DocsEditable()
  final MidiPort port;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MIDIInput')
// http://webaudio.github.io/web-midi-api/#idl-def-MIDIInput
@Experimental()
class MidiInput extends MidiPort native "MIDIInput" {
  // To suppress missing implicit constructor warnings.
  factory MidiInput._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `midimessage` events to event
   * handlers that are not necessarily instances of [MidiInput].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MIDIInput.midimessageEvent')
  @DocsEditable()
  static const EventStreamProvider<MidiMessageEvent> midiMessageEvent = const EventStreamProvider<MidiMessageEvent>('midimessage');

  /// Stream of `midimessage` events handled by this [MidiInput].
  @DomName('MIDIInput.onmidimessage')
  @DocsEditable()
  Stream<MidiMessageEvent> get onMidiMessage => midiMessageEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MIDIMessageEvent')
// http://webaudio.github.io/web-midi-api/#midimessageevent-interface
@Experimental()
class MidiMessageEvent extends Event native "MIDIMessageEvent" {
  // To suppress missing implicit constructor warnings.
  factory MidiMessageEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('MIDIMessageEvent.data')
  @DocsEditable()
  final Uint8List data;

  @DomName('MIDIMessageEvent.receivedTime')
  @DocsEditable()
  final double receivedTime;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MIDIOutput')
// http://webaudio.github.io/web-midi-api/#midioutput-interface
@Experimental()
class MidiOutput extends MidiPort native "MIDIOutput" {
  // To suppress missing implicit constructor warnings.
  factory MidiOutput._() { throw new UnsupportedError("Not supported"); }

  @DomName('MIDIOutput.send')
  @DocsEditable()
  void send(Uint8List data, [num timestamp]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MIDIPort')
// http://webaudio.github.io/web-midi-api/#idl-def-MIDIPort
@Experimental()
class MidiPort extends EventTarget native "MIDIPort" {
  // To suppress missing implicit constructor warnings.
  factory MidiPort._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `disconnect` events to event
   * handlers that are not necessarily instances of [MidiPort].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MIDIPort.disconnectEvent')
  @DocsEditable()
  static const EventStreamProvider<MidiConnectionEvent> disconnectEvent = const EventStreamProvider<MidiConnectionEvent>('disconnect');

  @DomName('MIDIPort.id')
  @DocsEditable()
  final String id;

  @DomName('MIDIPort.manufacturer')
  @DocsEditable()
  final String manufacturer;

  @DomName('MIDIPort.name')
  @DocsEditable()
  final String name;

  @DomName('MIDIPort.type')
  @DocsEditable()
  final String type;

  @DomName('MIDIPort.version')
  @DocsEditable()
  final String version;

  /// Stream of `disconnect` events handled by this [MidiPort].
  @DomName('MIDIPort.ondisconnect')
  @DocsEditable()
  Stream<MidiConnectionEvent> get onDisconnect => disconnectEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MimeType')
@Experimental() // non-standard
class MimeType extends Interceptor native "MimeType" {
  // To suppress missing implicit constructor warnings.
  factory MimeType._() { throw new UnsupportedError("Not supported"); }

  @DomName('MimeType.description')
  @DocsEditable()
  final String description;

  @DomName('MimeType.enabledPlugin')
  @DocsEditable()
  final Plugin enabledPlugin;

  @DomName('MimeType.suffixes')
  @DocsEditable()
  final String suffixes;

  @DomName('MimeType.type')
  @DocsEditable()
  final String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MimeTypeArray')
@Experimental() // non-standard
class MimeTypeArray extends Interceptor with ListMixin<MimeType>, ImmutableListMixin<MimeType> implements JavaScriptIndexingBehavior, List<MimeType> native "MimeTypeArray" {
  // To suppress missing implicit constructor warnings.
  factory MimeTypeArray._() { throw new UnsupportedError("Not supported"); }

  @DomName('MimeTypeArray.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  MimeType operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("MimeType", "#[#]", this, index);
  }
  void operator[]=(int index, MimeType value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<MimeType> mixins.
  // MimeType is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  MimeType get first {
    if (this.length > 0) {
      return JS('MimeType', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  MimeType get last {
    int len = this.length;
    if (len > 0) {
      return JS('MimeType', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  MimeType get single {
    int len = this.length;
    if (len == 1) {
      return JS('MimeType', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  MimeType elementAt(int index) => this[index];
  // -- end List<MimeType> mixins.

  @DomName('MimeTypeArray.__getter__')
  @DocsEditable()
  MimeType __getter__(String name) native;

  @DomName('MimeTypeArray.item')
  @DocsEditable()
  MimeType item(int index) native;

  @DomName('MimeTypeArray.namedItem')
  @DocsEditable()
  MimeType namedItem(String name) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLModElement')
@Unstable()
class ModElement extends HtmlElement native "HTMLModElement" {
  // To suppress missing implicit constructor warnings.
  factory ModElement._() { throw new UnsupportedError("Not supported"); }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ModElement.created() : super.created();

  @DomName('HTMLModElement.cite')
  @DocsEditable()
  String cite;

  @DomName('HTMLModElement.dateTime')
  @DocsEditable()
  String dateTime;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('MouseEvent')
class MouseEvent extends UIEvent native "MouseEvent,DragEvent,PointerEvent,MSPointerEvent" {
  factory MouseEvent(String type,
      {Window view, int detail: 0, int screenX: 0, int screenY: 0,
      int clientX: 0, int clientY: 0, int button: 0, bool canBubble: true,
      bool cancelable: true, bool ctrlKey: false, bool altKey: false,
      bool shiftKey: false, bool metaKey: false, EventTarget relatedTarget}) {

    if (view == null) {
      view = window;
    }
    var event = document._createEvent('MouseEvent');
    event._initMouseEvent(type, canBubble, cancelable, view, detail,
        screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey,
        button, relatedTarget);
    return event;
  }
  // To suppress missing implicit constructor warnings.
  factory MouseEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('MouseEvent.altKey')
  @DocsEditable()
  final bool altKey;

  @DomName('MouseEvent.button')
  @DocsEditable()
  final int button;

  @JSName('clientX')
  @DomName('MouseEvent.clientX')
  @DocsEditable()
  final int _clientX;

  @JSName('clientY')
  @DomName('MouseEvent.clientY')
  @DocsEditable()
  final int _clientY;

  @DomName('MouseEvent.ctrlKey')
  @DocsEditable()
  final bool ctrlKey;

  @DomName('MouseEvent.dataTransfer')
  @DocsEditable()
  @Unstable()
  final DataTransfer dataTransfer;

  @DomName('MouseEvent.fromElement')
  @DocsEditable()
  @Experimental() // nonstandard
  final Node fromElement;

  @DomName('MouseEvent.metaKey')
  @DocsEditable()
  final bool metaKey;

  @DomName('MouseEvent.relatedTarget')
  @DocsEditable()
  EventTarget get relatedTarget => _convertNativeToDart_EventTarget(this._get_relatedTarget);
  @JSName('relatedTarget')
  @DomName('MouseEvent.relatedTarget')
  @DocsEditable()
  @Creates('Node')
  @Returns('EventTarget|=Object')
  final dynamic _get_relatedTarget;

  @JSName('screenX')
  @DomName('MouseEvent.screenX')
  @DocsEditable()
  final int _screenX;

  @JSName('screenY')
  @DomName('MouseEvent.screenY')
  @DocsEditable()
  final int _screenY;

  @DomName('MouseEvent.shiftKey')
  @DocsEditable()
  final bool shiftKey;

  @DomName('MouseEvent.toElement')
  @DocsEditable()
  @Experimental() // nonstandard
  final Node toElement;

  @JSName('webkitMovementX')
  @DomName('MouseEvent.webkitMovementX')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  final int _webkitMovementX;

  @JSName('webkitMovementY')
  @DomName('MouseEvent.webkitMovementY')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  final int _webkitMovementY;

  @DomName('MouseEvent.initMouseEvent')
  @DocsEditable()
  void _initMouseEvent(String type, bool canBubble, bool cancelable, Window view, int detail, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, int button, EventTarget relatedTarget) {
    var relatedTarget_1 = _convertDartToNative_EventTarget(relatedTarget);
    _initMouseEvent_1(type, canBubble, cancelable, view, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget_1);
    return;
  }
  @JSName('initMouseEvent')
  @DomName('MouseEvent.initMouseEvent')
  @DocsEditable()
  void _initMouseEvent_1(type, canBubble, cancelable, Window view, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget) native;


  @DomName('MouseEvent.clientX')
  @DomName('MouseEvent.clientY')
  Point get client => new Point(_clientX, _clientY);

  @DomName('MouseEvent.movementX')
  @DomName('MouseEvent.movementY')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  Point get movement => new Point(_webkitMovementX, _webkitMovementY);

  /**
   * The coordinates of the mouse pointer in target node coordinates.
   *
   * This value may vary between platforms if the target node moves
   * after the event has fired or if the element has CSS transforms affecting
   * it.
   */
  Point get offset {
    if (JS('bool', '!!#.offsetX', this)) {
      var x = JS('int', '#.offsetX', this);
      var y = JS('int', '#.offsetY', this);
      return new Point(x, y);
    } else {
      // Firefox does not support offsetX.
      if (!(this.target is Element)) {
        throw new UnsupportedError(
            'offsetX is only supported on elements');
      }
      Element target = this.target;
      var point = (this.client - target.getBoundingClientRect().topLeft);
      return new Point(point.x.toInt(), point.y.toInt());
    }
  }

  @DomName('MouseEvent.screenX')
  @DomName('MouseEvent.screenY')
  Point get screen => new Point(_screenX, _screenY);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('MutationCallback')
typedef void MutationCallback(List<MutationRecord> mutations, MutationObserver observer);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('MutationObserver')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
class MutationObserver extends Interceptor native "MutationObserver,WebKitMutationObserver" {

  @DomName('MutationObserver.disconnect')
  @DocsEditable()
  void disconnect() native;

  @DomName('MutationObserver.observe')
  @DocsEditable()
  void _observe(Node target, Map options) {
    var options_1 = convertDartToNative_Dictionary(options);
    _observe_1(target, options_1);
    return;
  }
  @JSName('observe')
  @DomName('MutationObserver.observe')
  @DocsEditable()
  void _observe_1(Node target, options) native;

  @DomName('MutationObserver.takeRecords')
  @DocsEditable()
  List<MutationRecord> takeRecords() native;

  /**
   * Checks to see if the mutation observer API is supported on the current
   * platform.
   */
  static bool get supported {
    return JS('bool',
        '!!(window.MutationObserver || window.WebKitMutationObserver)');
  }

  /**
   * Observes the target for the specified changes.
   *
   * Some requirements for the optional parameters:
   *
   * * Either childList, attributes or characterData must be true.
   * * If attributeOldValue is true then attributes must also be true.
   * * If attributeFilter is specified then attributes must be true.
   * * If characterDataOldValue is true then characterData must be true.
   */
  void observe(Node target,
               {bool childList,
                bool attributes,
                bool characterData,
                bool subtree,
                bool attributeOldValue,
                bool characterDataOldValue,
                List<String> attributeFilter}) {

    // Parse options into map of known type.
    var parsedOptions = _createDict();

    // Override options passed in the map with named optional arguments.
    override(key, value) {
      if (value != null) _add(parsedOptions, key, value);
    }

    override('childList', childList);
    override('attributes', attributes);
    override('characterData', characterData);
    override('subtree', subtree);
    override('attributeOldValue', attributeOldValue);
    override('characterDataOldValue', characterDataOldValue);
    if (attributeFilter != null) {
      override('attributeFilter', _fixupList(attributeFilter));
    }

    _call(target, parsedOptions);
  }

   // TODO: Change to a set when const Sets are available.
  static final _boolKeys =
    const {'childList': true,
           'attributes': true,
           'characterData': true,
           'subtree': true,
           'attributeOldValue': true,
           'characterDataOldValue': true };


  static _createDict() => JS('var', '{}');
  static _add(m, String key, value) { JS('void', '#[#] = #', m, key, value); }
  static _fixupList(list) => list;  // TODO: Ensure is a JavaScript Array.

  // Call native function with no conversions.
  @JSName('observe')
  void _call(target, options) native;

  factory MutationObserver(MutationCallback callback) {
    // Dummy statement to mark types as instantiated.
    JS('MutationObserver|MutationRecord', '0');

    return JS('MutationObserver',
        'new(window.MutationObserver||window.WebKitMutationObserver||'
        'window.MozMutationObserver)(#)',
        convertDartClosureToJS(_wrapBinaryZone(callback), 2));
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('MutationRecord')
class MutationRecord extends Interceptor native "MutationRecord" {
  // To suppress missing implicit constructor warnings.
  factory MutationRecord._() { throw new UnsupportedError("Not supported"); }

  @DomName('MutationRecord.addedNodes')
  @DocsEditable()
  @Returns('NodeList')
  @Creates('NodeList')
  final List<Node> addedNodes;

  @DomName('MutationRecord.attributeName')
  @DocsEditable()
  final String attributeName;

  @DomName('MutationRecord.attributeNamespace')
  @DocsEditable()
  final String attributeNamespace;

  @DomName('MutationRecord.nextSibling')
  @DocsEditable()
  final Node nextSibling;

  @DomName('MutationRecord.oldValue')
  @DocsEditable()
  final String oldValue;

  @DomName('MutationRecord.previousSibling')
  @DocsEditable()
  final Node previousSibling;

  @DomName('MutationRecord.removedNodes')
  @DocsEditable()
  @Returns('NodeList')
  @Creates('NodeList')
  final List<Node> removedNodes;

  @DomName('MutationRecord.target')
  @DocsEditable()
  final Node target;

  @DomName('MutationRecord.type')
  @DocsEditable()
  final String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('Navigator')
class Navigator extends Interceptor implements NavigatorOnLine, NavigatorID native "Navigator" {

  @DomName('Navigator.language')
  String get language => JS('String', '#.language || #.userLanguage', this,
      this);

  /**
   * Gets a stream (video and or audio) from the local computer.
   *
   * Use [MediaStream.supported] to check if this is supported by the current
   * platform. The arguments `audio` and `video` default to `false` (stream does
   * not use audio or video, respectively).
   *
   * Simple example usage:
   *
   *     window.navigator.getUserMedia(audio: true, video: true).then((stream) {
   *       var video = new VideoElement()
   *         ..autoplay = true
   *         ..src = Url.createObjectUrlFromStream(stream);
   *       document.body.append(video);
   *     });
   *
   * The user can also pass in Maps to the audio or video parameters to specify
   * mandatory and optional constraints for the media stream. Not passing in a
   * map, but passing in `true` will provide a MediaStream with audio or
   * video capabilities, but without any additional constraints. The particular
   * constraint names for audio and video are still in flux, but as of this
   * writing, here is an example providing more constraints.
   *
   *     window.navigator.getUserMedia(
   *         audio: true,
   *         video: {'mandatory':
   *                    { 'minAspectRatio': 1.333, 'maxAspectRatio': 1.334 },
   *                 'optional':
   *                    [{ 'minFrameRate': 60 },
   *                     { 'maxWidth': 640 }]
   *     });
   *
   * See also:
   * * [MediaStream.supported]
   */
  @DomName('Navigator.webkitGetUserMedia')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @Experimental()
  Future<MediaStream> getUserMedia({audio: false, video: false}) {
    var completer = new Completer<MediaStream>();
    var options = {
      'audio': audio,
      'video': video
    };
    _ensureGetUserMedia();
    this._getUserMedia(convertDartToNative_SerializedScriptValue(options),
      (stream) {
        completer.complete(stream);
      },
      (error) {
        completer.completeError(error);
      });
    return completer.future;
  }

  _ensureGetUserMedia() {
    if (JS('bool', '!(#.getUserMedia)', this)) {
      JS('void', '#.getUserMedia = '
          '(#.getUserMedia || #.webkitGetUserMedia || #.mozGetUserMedia ||'
          '#.msGetUserMedia)', this, this, this, this, this);
    }
  }

  @JSName('getUserMedia')
  void _getUserMedia(options, _NavigatorUserMediaSuccessCallback success,
      _NavigatorUserMediaErrorCallback error) native;

  // To suppress missing implicit constructor warnings.
  factory Navigator._() { throw new UnsupportedError("Not supported"); }

  @DomName('Navigator.cookieEnabled')
  @DocsEditable()
  @Unstable()
  final bool cookieEnabled;

  @DomName('Navigator.doNotTrack')
  @DocsEditable()
  // http://www.w3.org/2011/tracking-protection/drafts/tracking-dnt.html#js-dom
  @Experimental() // experimental
  final String doNotTrack;

  @DomName('Navigator.geolocation')
  @DocsEditable()
  @Unstable()
  final Geolocation geolocation;

  @DomName('Navigator.maxTouchPoints')
  @DocsEditable()
  @Experimental() // untriaged
  final int maxTouchPoints;

  @DomName('Navigator.mimeTypes')
  @DocsEditable()
  @Experimental() // nonstandard
  final MimeTypeArray mimeTypes;

  @DomName('Navigator.productSub')
  @DocsEditable()
  @Unstable()
  final String productSub;

  @DomName('Navigator.serviceWorker')
  @DocsEditable()
  @Experimental() // untriaged
  final ServiceWorkerContainer serviceWorker;

  @DomName('Navigator.storageQuota')
  @DocsEditable()
  @Experimental() // untriaged
  final StorageQuota storageQuota;

  @DomName('Navigator.vendor')
  @DocsEditable()
  @Unstable()
  final String vendor;

  @DomName('Navigator.vendorSub')
  @DocsEditable()
  @Unstable()
  final String vendorSub;

  @JSName('webkitPersistentStorage')
  @DomName('Navigator.webkitPersistentStorage')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.w3.org/TR/quota-api/#accessing-storagequota
  final DeprecatedStorageQuota persistentStorage;

  @JSName('webkitTemporaryStorage')
  @DomName('Navigator.webkitTemporaryStorage')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.w3.org/TR/quota-api/#accessing-storagequota
  final DeprecatedStorageQuota temporaryStorage;

  @DomName('Navigator.getStorageUpdates')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#navigatorstorageutils
  @Experimental()
  void getStorageUpdates() native;

  @DomName('Navigator.isProtocolHandlerRegistered')
  @DocsEditable()
  @Experimental() // untriaged
  String isProtocolHandlerRegistered(String scheme, String url) native;

  @DomName('Navigator.registerProtocolHandler')
  @DocsEditable()
  @Unstable()
  void registerProtocolHandler(String scheme, String url, String title) native;

  @DomName('Navigator.requestMIDIAccess')
  @DocsEditable()
  @Experimental() // untriaged
  MidiAccessPromise requestMidiAccess([Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _requestMidiAccess_1(options_1);
    }
    return _requestMidiAccess_2();
  }
  @JSName('requestMIDIAccess')
  @DomName('Navigator.requestMIDIAccess')
  @DocsEditable()
  @Experimental() // untriaged
  MidiAccessPromise _requestMidiAccess_1(options) native;
  @JSName('requestMIDIAccess')
  @DomName('Navigator.requestMIDIAccess')
  @DocsEditable()
  @Experimental() // untriaged
  MidiAccessPromise _requestMidiAccess_2() native;

  @DomName('Navigator.unregisterProtocolHandler')
  @DocsEditable()
  @Experimental() // untriaged
  void unregisterProtocolHandler(String scheme, String url) native;

  @JSName('webkitGetGamepads')
  @DomName('Navigator.webkitGetGamepads')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/gamepad/raw-file/default/gamepad.html#widl-Navigator-getGamepads-Gamepad
  @Returns('_GamepadList')
  @Creates('_GamepadList')
  List<Gamepad> getGamepads() native;

  // From NavigatorID

  @DomName('Navigator.appCodeName')
  @DocsEditable()
  @Experimental() // non-standard
  final String appCodeName;

  @DomName('Navigator.appName')
  @DocsEditable()
  final String appName;

  @DomName('Navigator.appVersion')
  @DocsEditable()
  final String appVersion;

  @DomName('Navigator.platform')
  @DocsEditable()
  final String platform;

  @DomName('Navigator.product')
  @DocsEditable()
  @Unstable()
  final String product;

  @DomName('Navigator.userAgent')
  @DocsEditable()
  final String userAgent;

  // From NavigatorOnLine

  @DomName('Navigator.onLine')
  @DocsEditable()
  @Unstable()
  final bool onLine;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('NavigatorID')
@Experimental() // untriaged
abstract class NavigatorID extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigatorID._() { throw new UnsupportedError("Not supported"); }

  final String appCodeName;

  final String appName;

  final String appVersion;

  final String platform;

  final String product;

  final String userAgent;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('NavigatorOnLine')
@Experimental() // untriaged
abstract class NavigatorOnLine extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigatorOnLine._() { throw new UnsupportedError("Not supported"); }

  final bool onLine;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('NavigatorUserMediaError')
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html#idl-def-NavigatorUserMediaError
@Experimental()
class NavigatorUserMediaError extends Interceptor native "NavigatorUserMediaError" {
  // To suppress missing implicit constructor warnings.
  factory NavigatorUserMediaError._() { throw new UnsupportedError("Not supported"); }

  @DomName('NavigatorUserMediaError.constraintName')
  @DocsEditable()
  final String constraintName;

  @DomName('NavigatorUserMediaError.message')
  @DocsEditable()
  final String message;

  @DomName('NavigatorUserMediaError.name')
  @DocsEditable()
  final String name;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('NavigatorUserMediaErrorCallback')
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html#idl-def-NavigatorUserMediaErrorCallback
@Experimental()
typedef void _NavigatorUserMediaErrorCallback(NavigatorUserMediaError error);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('NavigatorUserMediaSuccessCallback')
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html#idl-def-NavigatorUserMediaSuccessCallback
@Experimental()
typedef void _NavigatorUserMediaSuccessCallback(MediaStream stream);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * Lazy implementation of the child nodes of an element that does not request
 * the actual child nodes of an element until strictly necessary greatly
 * improving performance for the typical cases where it is not required.
 */
class _ChildNodeListLazy extends ListBase<Node> implements NodeListWrapper {
  final Node _this;

  _ChildNodeListLazy(this._this);


  Node get first {
    Node result = JS('Node|Null', '#.firstChild', _this);
    if (result == null) throw new StateError("No elements");
    return result;
  }
  Node get last {
    Node result = JS('Node|Null', '#.lastChild', _this);
    if (result == null) throw new StateError("No elements");
    return result;
  }
  Node get single {
    int l = this.length;
    if (l == 0) throw new StateError("No elements");
    if (l > 1) throw new StateError("More than one element");
    return JS('Node|Null', '#.firstChild', _this);
  }

  void add(Node value) {
    _this.append(value);
  }

  void addAll(Iterable<Node> iterable) {
    if (iterable is _ChildNodeListLazy) {
      _ChildNodeListLazy otherList = iterable;
      if (!identical(otherList._this, _this)) {
        // Optimized route for copying between nodes.
        for (var i = 0, len = otherList.length; i < len; ++i) {
          _this.append(otherList._this.firstChild);
        }
      }
      return;
    }
    for (Node node in iterable) {
      _this.append(node);
    }
  }

  void insert(int index, Node node) {
    if (index < 0 || index > length) {
      throw new RangeError.range(index, 0, length);
    }
    if (index == length) {
      _this.append(node);
    } else {
      _this.insertBefore(node, this[index]);
    }
  }

  void insertAll(int index, Iterable<Node> iterable) {
    var item = this[index];
    _this.insertAllBefore(iterable, item);
  }

  void setAll(int index, Iterable<Node> iterable) {
    throw new UnsupportedError("Cannot setAll on Node list");
  }

  Node removeLast() {
    final result = last;
    if (result != null) {
      _this._removeChild(result);
    }
    return result;
  }

  Node removeAt(int index) {
    var result = this[index];
    if (result != null) {
      _this._removeChild(result);
    }
    return result;
  }

  bool remove(Object object) {
    if (object is! Node) return false;
    Node node = object;
    if (!identical(_this, node.parentNode)) return false;
    _this._removeChild(node);
    return true;
  }

  void _filter(bool test(Node node), bool removeMatching) {
    // This implementation of removeWhere/retainWhere is more efficient
    // than the default in ListBase. Child nodes can be removed in constant
    // time.
    Node child = _this.firstChild;
    while (child != null) {
      Node nextChild = child.nextNode;
      if (test(child) == removeMatching) {
        _this._removeChild(child);
      }
      child = nextChild;
    }
  }

  void removeWhere(bool test(Node node)) {
    _filter(test, true);
  }

  void retainWhere(bool test(Node node)) {
    _filter(test, false);
  }

  void clear() {
    _this._clearChildren();
  }

  void operator []=(int index, Node value) {
    _this._replaceChild(value, this[index]);
  }

  Iterator<Node> get iterator => _this.childNodes.iterator;

  // From List<Node>:

  // TODO(jacobr): this could be implemented for child node lists.
  // The exception we throw here is misleading.
  void sort([Comparator<Node> compare]) {
    throw new UnsupportedError("Cannot sort Node list");
  }

  void shuffle([Random random]) {
    throw new UnsupportedError("Cannot shuffle Node list");
  }

  // FIXME: implement these.
  void setRange(int start, int end, Iterable<Node> iterable,
                [int skipCount = 0]) {
    throw new UnsupportedError("Cannot setRange on Node list");
  }

  void fillRange(int start, int end, [Node fill]) {
    throw new UnsupportedError("Cannot fillRange on Node list");
  }
  // -- end List<Node> mixins.

  // TODO(jacobr): benchmark whether this is more efficient or whether caching
  // a local copy of childNodes is more efficient.
  int get length => _this.childNodes.length;

  void set length(int value) {
    throw new UnsupportedError(
        "Cannot set length on immutable List.");
  }

  Node operator[](int index) => _this.childNodes[index];

  List<Node> get rawList => _this.childNodes;
}


@DomName('Node')
class Node extends EventTarget native "Node" {

  // Custom element created callback.
  Node._created() : super._created();

  /**
   * A modifiable list of this node's children.
   */
  List<Node> get nodes {
    return new _ChildNodeListLazy(this);
  }

  void set nodes(Iterable<Node> value) {
    // Copy list first since we don't want liveness during iteration.
    // TODO(jacobr): there is a better way to do this.
    List copy = new List.from(value);
    text = '';
    for (Node node in copy) {
      append(node);
    }
  }

  /**
   * Removes this node from the DOM.
   */
  @DomName('Node.removeChild')
  void remove() {
    // TODO(jacobr): should we throw an exception if parent is already null?
    // TODO(vsm): Use the native remove when available.
    if (this.parentNode != null) {
      final Node parent = this.parentNode;
      parentNode._removeChild(this);
    }
  }

  /**
   * Replaces this node with another node.
   */
  @DomName('Node.replaceChild')
  Node replaceWith(Node otherNode) {
    try {
      final Node parent = this.parentNode;
      parent._replaceChild(otherNode, this);
    } catch (e) {

    };
    return this;
  }

  /**
   * Inserts all of the nodes into this node directly before refChild.
   *
   * See also:
   *
   * * [insertBefore]
   */
  Node insertAllBefore(Iterable<Node> newNodes, Node refChild) {
    if (newNodes is _ChildNodeListLazy) {
      _ChildNodeListLazy otherList = newNodes;
      if (identical(otherList._this, this)) {
        throw new ArgumentError(newNodes);
      }

      // Optimized route for copying between nodes.
      for (var i = 0, len = otherList.length; i < len; ++i) {
        this.insertBefore(otherList._this.firstChild, refChild);
      }
    } else {
      for (var node in newNodes) {
        this.insertBefore(node, refChild);
      }
    }
  }

  void _clearChildren() {
    while (firstChild != null) {
      _removeChild(firstChild);
    }
  }

  /**
   * Print out a String representation of this Node.
   */
  String toString() => nodeValue == null ? super.toString() : nodeValue;
  // To suppress missing implicit constructor warnings.
  factory Node._() { throw new UnsupportedError("Not supported"); }

  @DomName('Node.ATTRIBUTE_NODE')
  @DocsEditable()
  static const int ATTRIBUTE_NODE = 2;

  @DomName('Node.CDATA_SECTION_NODE')
  @DocsEditable()
  static const int CDATA_SECTION_NODE = 4;

  @DomName('Node.COMMENT_NODE')
  @DocsEditable()
  static const int COMMENT_NODE = 8;

  @DomName('Node.DOCUMENT_FRAGMENT_NODE')
  @DocsEditable()
  static const int DOCUMENT_FRAGMENT_NODE = 11;

  @DomName('Node.DOCUMENT_NODE')
  @DocsEditable()
  static const int DOCUMENT_NODE = 9;

  @DomName('Node.DOCUMENT_TYPE_NODE')
  @DocsEditable()
  static const int DOCUMENT_TYPE_NODE = 10;

  @DomName('Node.ELEMENT_NODE')
  @DocsEditable()
  static const int ELEMENT_NODE = 1;

  @DomName('Node.ENTITY_NODE')
  @DocsEditable()
  static const int ENTITY_NODE = 6;

  @DomName('Node.ENTITY_REFERENCE_NODE')
  @DocsEditable()
  static const int ENTITY_REFERENCE_NODE = 5;

  @DomName('Node.NOTATION_NODE')
  @DocsEditable()
  static const int NOTATION_NODE = 12;

  @DomName('Node.PROCESSING_INSTRUCTION_NODE')
  @DocsEditable()
  static const int PROCESSING_INSTRUCTION_NODE = 7;

  @DomName('Node.TEXT_NODE')
  @DocsEditable()
  static const int TEXT_NODE = 3;

  @JSName('baseURI')
  @DomName('Node.baseURI')
  @DocsEditable()
  final String baseUri;

  /**
   * A list of this node's children.
   *
   * ## Other resources
   *
   * * [Node.childNodes]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)
   * from MDN.
   */
  @DomName('Node.childNodes')
  @DocsEditable()
  @Returns('NodeList')
  @Creates('NodeList')
  final List<Node> childNodes;

  /**
   * The first child of this node.
   *
   * ## Other resources
   *
   * * [Node.firstChild]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.firstChild)
   * from MDN.
   */
  @DomName('Node.firstChild')
  @DocsEditable()
  final Node firstChild;

  /**
   * The last child of this node.
   *
   * ## Other resources
   *
   * * [Node.lastChild]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.lastChild)
   * from MDN.
   */
  @DomName('Node.lastChild')
  @DocsEditable()
  final Node lastChild;

  @JSName('localName')
  @DomName('Node.localName')
  @DocsEditable()
  final String _localName;

  @JSName('namespaceURI')
  @DomName('Node.namespaceURI')
  @DocsEditable()
  final String _namespaceUri;

  @JSName('nextSibling')
  /**
   * The next sibling node.
   *
   * ## Other resources
   *
   * * [Node.nextSibling]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nextSibling)
   * from MDN.
   */
  @DomName('Node.nextSibling')
  @DocsEditable()
  final Node nextNode;

  /**
   * The name of this node.
   *
   * This varies by this node's [nodeType].
   *
   * ## Other resources
   *
   * * [Node.nodeName]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeName)
   * from MDN. This page contains a table of [nodeName] values for each
   * [nodeType].
   */
  @DomName('Node.nodeName')
  @DocsEditable()
  final String nodeName;

  /**
   * The type of node.
   *
   * This value is one of:
   *
   * * [ATTRIBUTE_NODE] if this node is an attribute.
   * * [CDATA_SECTION_NODE] if this node is a [CDataSection].
   * * [COMMENT_NODE] if this node is a [Comment].
   * * [DOCUMENT_FRAGMENT_NODE] if this node is a [DocumentFragment].
   * * [DOCUMENT_NODE] if this node is a [Document].
   * * [DOCUMENT_TYPE_NODE] if this node is a [DocumentType] node.
   * * [ELEMENT_NODE] if this node is an [Element].
   * * [ENTITY_NODE] if this node is an entity.
   * * [ENTITY_REFERENCE_NODE] if this node is an entity reference.
   * * [NOTATION_NODE] if this node is a notation.
   * * [PROCESSING_INSTRUCTION_NODE] if this node is a [ProcessingInstruction].
   * * [TEXT_NODE] if this node is a [Text] node.
   *
   * ## Other resources
   *
   * * [Node.nodeType]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeType) from MDN.
   */
  @DomName('Node.nodeType')
  @DocsEditable()
  final int nodeType;

  /**
   * The value of this node.
   *
   * This varies by this type's [nodeType].
   *
   * ## Other resources
   *
   * * [Node.nodeValue]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeValue)
   * from MDN. This page contains a table of [nodeValue] values for each
   * [nodeType].
   */
  @DomName('Node.nodeValue')
  @DocsEditable()
  final String nodeValue;

  /**
   * The document this node belongs to.
   *
   * Returns null if this node does not belong to any document.
   *
   * ## Other resources
   *
   * * [Node.ownerDocument]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.ownerDocument) from
   * MDN.
   */
  @DomName('Node.ownerDocument')
  @DocsEditable()
  final Document ownerDocument;

  @JSName('parentElement')
  /**
   * The parent element of this node.
   *
   * Returns null if this node either does not have a parent or its parent is
   * not an element.
   *
   * ## Other resources
   *
   * * [Node.parentElement]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.parentElement) from
   * W3C.
   */
  @DomName('Node.parentElement')
  @DocsEditable()
  final Element parent;

  /**
   * The parent node of this node.
   *
   * ## Other resources
   *
   * * [Node.parentNode]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.parentNode) from
   * MDN.
   */
  @DomName('Node.parentNode')
  @DocsEditable()
  final Node parentNode;

  @JSName('previousSibling')
  /**
   * The previous sibling node.
   *
   * ## Other resources
   *
   * * [Node.previousSibling]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.previousSibling)
   * from MDN.
   */
  @DomName('Node.previousSibling')
  @DocsEditable()
  final Node previousNode;

  @JSName('textContent')
  /**
   * All text within this node and its decendents.
   *
   * ## Other resources
   *
   * * [Node.textContent]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent) from
   * MDN.
   */
  @DomName('Node.textContent')
  @DocsEditable()
  String text;

  @JSName('appendChild')
  /**
   * Adds a node to the end of the child [nodes] list of this node.
   *
   * If the node already exists in this document, it will be removed from its
   * current parent node, then added to this node.
   *
   * This method is more efficient than `nodes.add`, and is the preferred
   * way of appending a child node.
   */
  @DomName('Node.appendChild')
  @DocsEditable()
  Node append(Node newChild) native;

  @JSName('cloneNode')
  /**
   * Returns a copy of this node.
   *
   * If [deep] is `true`, then all of this node's children and decendents are
   * copied as well. If [deep] is `false`, then only this node is copied.
   *
   * ## Other resources
   *
   * * [Node.cloneNode]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.cloneNode) from
   * MDN.
   */
  @DomName('Node.cloneNode')
  @DocsEditable()
  Node clone(bool deep) native;

  /**
   * Returns true if this node contains the specified node.
   *
   * ## Other resources
   *
   * * [Node.contains]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.contains) from MDN.
   */
  @DomName('Node.contains')
  @DocsEditable()
  bool contains(Node other) native;

  /**
   * Returns true if this node has any children.
   *
   * ## Other resources
   *
   * * [Node.hasChildNodes]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.hasChildNodes) from
   * MDN.
   */
  @DomName('Node.hasChildNodes')
  @DocsEditable()
  bool hasChildNodes() native;

  /**
   * Inserts all of the nodes into this node directly before refChild.
   *
   * ## Other resources
   *
   * * [Node.insertBefore]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.insertBefore) from
   * MDN.
   */
  @DomName('Node.insertBefore')
  @DocsEditable()
  Node insertBefore(Node newChild, Node refChild) native;

  @JSName('removeChild')
  @DomName('Node.removeChild')
  @DocsEditable()
  Node _removeChild(Node oldChild) native;

  @JSName('replaceChild')
  @DomName('Node.replaceChild')
  @DocsEditable()
  Node _replaceChild(Node newChild, Node oldChild) native;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('NodeFilter')
@Unstable()
class NodeFilter extends Interceptor native "NodeFilter" {
  // To suppress missing implicit constructor warnings.
  factory NodeFilter._() { throw new UnsupportedError("Not supported"); }

  @DomName('NodeFilter.FILTER_ACCEPT')
  @DocsEditable()
  static const int FILTER_ACCEPT = 1;

  @DomName('NodeFilter.FILTER_REJECT')
  @DocsEditable()
  static const int FILTER_REJECT = 2;

  @DomName('NodeFilter.FILTER_SKIP')
  @DocsEditable()
  static const int FILTER_SKIP = 3;

  @DomName('NodeFilter.SHOW_ALL')
  @DocsEditable()
  static const int SHOW_ALL = 0xFFFFFFFF;

  @DomName('NodeFilter.SHOW_COMMENT')
  @DocsEditable()
  static const int SHOW_COMMENT = 0x00000080;

  @DomName('NodeFilter.SHOW_DOCUMENT')
  @DocsEditable()
  static const int SHOW_DOCUMENT = 0x00000100;

  @DomName('NodeFilter.SHOW_DOCUMENT_FRAGMENT')
  @DocsEditable()
  static const int SHOW_DOCUMENT_FRAGMENT = 0x00000400;

  @DomName('NodeFilter.SHOW_DOCUMENT_TYPE')
  @DocsEditable()
  static const int SHOW_DOCUMENT_TYPE = 0x00000200;

  @DomName('NodeFilter.SHOW_ELEMENT')
  @DocsEditable()
  static const int SHOW_ELEMENT = 0x00000001;

  @DomName('NodeFilter.SHOW_PROCESSING_INSTRUCTION')
  @DocsEditable()
  static const int SHOW_PROCESSING_INSTRUCTION = 0x00000040;

  @DomName('NodeFilter.SHOW_TEXT')
  @DocsEditable()
  static const int SHOW_TEXT = 0x00000004;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('NodeIterator')
@Unstable()
class NodeIterator extends Interceptor native "NodeIterator" {
  factory NodeIterator(Node root, int whatToShow) {
    return document._createNodeIterator(root, whatToShow, null);
  }
  // To suppress missing implicit constructor warnings.
  factory NodeIterator._() { throw new UnsupportedError("Not supported"); }

  @DomName('NodeIterator.pointerBeforeReferenceNode')
  @DocsEditable()
  final bool pointerBeforeReferenceNode;

  @DomName('NodeIterator.referenceNode')
  @DocsEditable()
  final Node referenceNode;

  @DomName('NodeIterator.root')
  @DocsEditable()
  final Node root;

  @DomName('NodeIterator.whatToShow')
  @DocsEditable()
  final int whatToShow;

  @DomName('NodeIterator.detach')
  @DocsEditable()
  void detach() native;

  @DomName('NodeIterator.nextNode')
  @DocsEditable()
  Node nextNode() native;

  @DomName('NodeIterator.previousNode')
  @DocsEditable()
  Node previousNode() native;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('NodeList')
class NodeList extends Interceptor with ListMixin<Node>, ImmutableListMixin<Node> implements JavaScriptIndexingBehavior, List<Node> native "NodeList,RadioNodeList" {
  // To suppress missing implicit constructor warnings.
  factory NodeList._() { throw new UnsupportedError("Not supported"); }

  @DomName('NodeList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  Node operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("Node", "#[#]", this, index);
  }
  void operator[]=(int index, Node value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Node> mixins.
  // Node is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Node get first {
    if (this.length > 0) {
      return JS('Node', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Node get last {
    int len = this.length;
    if (len > 0) {
      return JS('Node', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Node get single {
    int len = this.length;
    if (len == 1) {
      return JS('Node', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Node elementAt(int index) => this[index];
  // -- end List<Node> mixins.

  @JSName('item')
  @DomName('NodeList.item')
  @DocsEditable()
  Node _item(int index) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('Notification')
// http://www.w3.org/TR/notifications/#notification
@Experimental() // experimental
class Notification extends EventTarget native "Notification" {

  factory Notification(String title, {String titleDir: null, String body: null,
      String bodyDir: null, String tag: null, String iconUrl: null}) {

    var parsedOptions = {};
    if (titleDir != null) parsedOptions['titleDir'] = titleDir;
    if (body != null) parsedOptions['body'] = body;
    if (bodyDir != null) parsedOptions['bodyDir'] = bodyDir;
    if (tag != null) parsedOptions['tag'] = tag;
    if (iconUrl != null) parsedOptions['iconUrl'] = iconUrl;

    return Notification._factoryNotification(title, parsedOptions);
  }
  // To suppress missing implicit constructor warnings.
  factory Notification._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `click` events to event
   * handlers that are not necessarily instances of [Notification].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Notification.clickEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> clickEvent = const EventStreamProvider<Event>('click');

  /**
   * Static factory designed to expose `close` events to event
   * handlers that are not necessarily instances of [Notification].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Notification.closeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> closeEvent = const EventStreamProvider<Event>('close');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [Notification].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Notification.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `show` events to event
   * handlers that are not necessarily instances of [Notification].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Notification.showEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> showEvent = const EventStreamProvider<Event>('show');

  @DomName('Notification.Notification')
  @DocsEditable()
  static Notification _factoryNotification(String title, [Map options]) {
    if (options != null) {
      return Notification._create_1(title, options);
    }
    return Notification._create_2(title);
  }
  static Notification _create_1(title, options) => JS('Notification', 'new Notification(#,#)', title, options);
  static Notification _create_2(title) => JS('Notification', 'new Notification(#)', title);

  @DomName('Notification.body')
  @DocsEditable()
  @Experimental() // untriaged
  final String body;

  @DomName('Notification.dir')
  @DocsEditable()
  @Experimental() // nonstandard
  final String dir;

  @DomName('Notification.icon')
  @DocsEditable()
  @Experimental() // untriaged
  final String icon;

  @DomName('Notification.lang')
  @DocsEditable()
  @Experimental() // untriaged
  final String lang;

  @DomName('Notification.permission')
  @DocsEditable()
  final String permission;

  @DomName('Notification.tag')
  @DocsEditable()
  @Experimental() // nonstandard
  final String tag;

  @DomName('Notification.title')
  @DocsEditable()
  @Experimental() // untriaged
  final String title;

  @DomName('Notification.close')
  @DocsEditable()
  void close() native;

  @JSName('requestPermission')
  @DomName('Notification.requestPermission')
  @DocsEditable()
  static void _requestPermission([_NotificationPermissionCallback callback]) native;

  @JSName('requestPermission')
  @DomName('Notification.requestPermission')
  @DocsEditable()
  static Future<String> requestPermission() {
    var completer = new Completer<String>();
    _requestPermission(
        (value) { completer.complete(value); });
    return completer.future;
  }

  /// Stream of `click` events handled by this [Notification].
  @DomName('Notification.onclick')
  @DocsEditable()
  Stream<Event> get onClick => clickEvent.forTarget(this);

  /// Stream of `close` events handled by this [Notification].
  @DomName('Notification.onclose')
  @DocsEditable()
  Stream<Event> get onClose => closeEvent.forTarget(this);

  /// Stream of `error` events handled by this [Notification].
  @DomName('Notification.onerror')
  @DocsEditable()
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `show` events handled by this [Notification].
  @DomName('Notification.onshow')
  @DocsEditable()
  Stream<Event> get onShow => showEvent.forTarget(this);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('NotificationPermissionCallback')
// http://www.w3.org/TR/notifications/#notificationpermissioncallback
@Experimental()
typedef void _NotificationPermissionCallback(String permission);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLOListElement')
class OListElement extends HtmlElement native "HTMLOListElement" {
  // To suppress missing implicit constructor warnings.
  factory OListElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLOListElement.HTMLOListElement')
  @DocsEditable()
  factory OListElement() => document.createElement("ol");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  OListElement.created() : super.created();

  @DomName('HTMLOListElement.reversed')
  @DocsEditable()
  bool reversed;

  @DomName('HTMLOListElement.start')
  @DocsEditable()
  int start;

  @DomName('HTMLOListElement.type')
  @DocsEditable()
  String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLObjectElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
class ObjectElement extends HtmlElement native "HTMLObjectElement" {
  // To suppress missing implicit constructor warnings.
  factory ObjectElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLObjectElement.HTMLObjectElement')
  @DocsEditable()
  factory ObjectElement() => document.createElement("object");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ObjectElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('object');

  @DomName('HTMLObjectElement.data')
  @DocsEditable()
  String data;

  @DomName('HTMLObjectElement.form')
  @DocsEditable()
  final FormElement form;

  @DomName('HTMLObjectElement.height')
  @DocsEditable()
  String height;

  @DomName('HTMLObjectElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLObjectElement.type')
  @DocsEditable()
  String type;

  @DomName('HTMLObjectElement.useMap')
  @DocsEditable()
  String useMap;

  @DomName('HTMLObjectElement.validationMessage')
  @DocsEditable()
  final String validationMessage;

  @DomName('HTMLObjectElement.validity')
  @DocsEditable()
  final ValidityState validity;

  @DomName('HTMLObjectElement.width')
  @DocsEditable()
  String width;

  @DomName('HTMLObjectElement.willValidate')
  @DocsEditable()
  final bool willValidate;

  @DomName('HTMLObjectElement.__getter__')
  @DocsEditable()
  bool __getter__(index_OR_name) native;

  @DomName('HTMLObjectElement.__setter__')
  @DocsEditable()
  void __setter__(index_OR_name, Node value) native;

  @DomName('HTMLObjectElement.checkValidity')
  @DocsEditable()
  bool checkValidity() native;

  @DomName('HTMLObjectElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLOptGroupElement')
class OptGroupElement extends HtmlElement native "HTMLOptGroupElement" {
  // To suppress missing implicit constructor warnings.
  factory OptGroupElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLOptGroupElement.HTMLOptGroupElement')
  @DocsEditable()
  factory OptGroupElement() => document.createElement("optgroup");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  OptGroupElement.created() : super.created();

  @DomName('HTMLOptGroupElement.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('HTMLOptGroupElement.label')
  @DocsEditable()
  String label;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('HTMLOptionElement')
class OptionElement extends HtmlElement native "HTMLOptionElement" {
  factory OptionElement({String data: '', String value : '', bool selected: false}) {
    return new OptionElement._(data, value, null, selected);
  }

  @DomName('HTMLOptionElement.HTMLOptionElement')
  @DocsEditable()
  factory OptionElement._([String data, String value, bool defaultSelected, bool selected]) {
    if (selected != null) {
      return OptionElement._create_1(data, value, defaultSelected, selected);
    }
    if (defaultSelected != null) {
      return OptionElement._create_2(data, value, defaultSelected);
    }
    if (value != null) {
      return OptionElement._create_3(data, value);
    }
    if (data != null) {
      return OptionElement._create_4(data);
    }
    return OptionElement._create_5();
  }
  static OptionElement _create_1(data, value, defaultSelected, selected) => JS('OptionElement', 'new Option(#,#,#,#)', data, value, defaultSelected, selected);
  static OptionElement _create_2(data, value, defaultSelected) => JS('OptionElement', 'new Option(#,#,#)', data, value, defaultSelected);
  static OptionElement _create_3(data, value) => JS('OptionElement', 'new Option(#,#)', data, value);
  static OptionElement _create_4(data) => JS('OptionElement', 'new Option(#)', data);
  static OptionElement _create_5() => JS('OptionElement', 'new Option()');
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  OptionElement.created() : super.created();

  @DomName('HTMLOptionElement.defaultSelected')
  @DocsEditable()
  bool defaultSelected;

  @DomName('HTMLOptionElement.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('HTMLOptionElement.form')
  @DocsEditable()
  final FormElement form;

  @DomName('HTMLOptionElement.index')
  @DocsEditable()
  final int index;

  @DomName('HTMLOptionElement.label')
  @DocsEditable()
  String label;

  @DomName('HTMLOptionElement.selected')
  @DocsEditable()
  bool selected;

  @DomName('HTMLOptionElement.value')
  @DocsEditable()
  String value;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLOutputElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
class OutputElement extends HtmlElement native "HTMLOutputElement" {
  // To suppress missing implicit constructor warnings.
  factory OutputElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLOutputElement.HTMLOutputElement')
  @DocsEditable()
  factory OutputElement() => document.createElement("output");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  OutputElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('output');

  @DomName('HTMLOutputElement.defaultValue')
  @DocsEditable()
  String defaultValue;

  @DomName('HTMLOutputElement.form')
  @DocsEditable()
  final FormElement form;

  @DomName('HTMLOutputElement.htmlFor')
  @DocsEditable()
  final DomSettableTokenList htmlFor;

  @DomName('HTMLOutputElement.labels')
  @DocsEditable()
  @Unstable()
  @Returns('NodeList')
  @Creates('NodeList')
  final List<Node> labels;

  @DomName('HTMLOutputElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLOutputElement.type')
  @DocsEditable()
  final String type;

  @DomName('HTMLOutputElement.validationMessage')
  @DocsEditable()
  final String validationMessage;

  @DomName('HTMLOutputElement.validity')
  @DocsEditable()
  final ValidityState validity;

  @DomName('HTMLOutputElement.value')
  @DocsEditable()
  String value;

  @DomName('HTMLOutputElement.willValidate')
  @DocsEditable()
  final bool willValidate;

  @DomName('HTMLOutputElement.checkValidity')
  @DocsEditable()
  bool checkValidity() native;

  @DomName('HTMLOutputElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('OverflowEvent')
@Experimental() // nonstandard
class OverflowEvent extends Event native "OverflowEvent" {
  // To suppress missing implicit constructor warnings.
  factory OverflowEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('OverflowEvent.BOTH')
  @DocsEditable()
  static const int BOTH = 2;

  @DomName('OverflowEvent.HORIZONTAL')
  @DocsEditable()
  static const int HORIZONTAL = 0;

  @DomName('OverflowEvent.VERTICAL')
  @DocsEditable()
  static const int VERTICAL = 1;

  @DomName('OverflowEvent.horizontalOverflow')
  @DocsEditable()
  final bool horizontalOverflow;

  @DomName('OverflowEvent.orient')
  @DocsEditable()
  final int orient;

  @DomName('OverflowEvent.verticalOverflow')
  @DocsEditable()
  final bool verticalOverflow;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('PageTransitionEvent')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html#pagetransitionevent
@Experimental()
class PageTransitionEvent extends Event native "PageTransitionEvent" {
  // To suppress missing implicit constructor warnings.
  factory PageTransitionEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('PageTransitionEvent.persisted')
  @DocsEditable()
  final bool persisted;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLParagraphElement')
class ParagraphElement extends HtmlElement native "HTMLParagraphElement" {
  // To suppress missing implicit constructor warnings.
  factory ParagraphElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLParagraphElement.HTMLParagraphElement')
  @DocsEditable()
  factory ParagraphElement() => document.createElement("p");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ParagraphElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLParamElement')
@Unstable()
class ParamElement extends HtmlElement native "HTMLParamElement" {
  // To suppress missing implicit constructor warnings.
  factory ParamElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLParamElement.HTMLParamElement')
  @DocsEditable()
  factory ParamElement() => document.createElement("param");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ParamElement.created() : super.created();

  @DomName('HTMLParamElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLParamElement.value')
  @DocsEditable()
  String value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('ParentNode')
@Experimental() // untriaged
abstract class ParentNode extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ParentNode._() { throw new UnsupportedError("Not supported"); }

  final int _childElementCount;

  final List<Node> _children;

  final Element _firstElementChild;

  final Element _lastElementChild;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('Path')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#path-objects
@Experimental()
class Path extends Interceptor native "Path" {
  // To suppress missing implicit constructor warnings.
  factory Path._() { throw new UnsupportedError("Not supported"); }

  @DomName('Path.Path')
  @DocsEditable()
  factory Path([path_OR_text]) {
    if (path_OR_text == null) {
      return Path._create_1();
    }
    if ((path_OR_text is Path || path_OR_text == null)) {
      return Path._create_2(path_OR_text);
    }
    if ((path_OR_text is String || path_OR_text == null)) {
      return Path._create_3(path_OR_text);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static Path _create_1() => JS('Path', 'new Path()');
  static Path _create_2(path_OR_text) => JS('Path', 'new Path(#)', path_OR_text);
  static Path _create_3(path_OR_text) => JS('Path', 'new Path(#)', path_OR_text);

  @DomName('Path.arc')
  @DocsEditable()
  void arc(num x, num y, num radius, num startAngle, num endAngle, bool anticlockwise) native;

  @DomName('Path.arcTo')
  @DocsEditable()
  void arcTo(num x1, num y1, num x2, num y2, num radius) native;

  @DomName('Path.bezierCurveTo')
  @DocsEditable()
  void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y, num x, num y) native;

  @DomName('Path.closePath')
  @DocsEditable()
  void closePath() native;

  @DomName('Path.lineTo')
  @DocsEditable()
  void lineTo(num x, num y) native;

  @DomName('Path.moveTo')
  @DocsEditable()
  void moveTo(num x, num y) native;

  @DomName('Path.quadraticCurveTo')
  @DocsEditable()
  void quadraticCurveTo(num cpx, num cpy, num x, num y) native;

  @DomName('Path.rect')
  @DocsEditable()
  void rect(num x, num y, num width, num height) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('Performance')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE)
class Performance extends EventTarget native "Performance" {
  // To suppress missing implicit constructor warnings.
  factory Performance._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `resourcetimingbufferfull` events to event
   * handlers that are not necessarily instances of [Performance].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Performance.webkitresourcetimingbufferfullEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.w3c-test.org/webperf/specs/ResourceTiming/#performanceresourcetiming-methods
  static const EventStreamProvider<Event> resourceTimingBufferFullEvent = const EventStreamProvider<Event>('webkitresourcetimingbufferfull');

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.performance)');

  @DomName('Performance.memory')
  @DocsEditable()
  @Experimental() // nonstandard
  final MemoryInfo memory;

  @DomName('Performance.navigation')
  @DocsEditable()
  final PerformanceNavigation navigation;

  @DomName('Performance.timing')
  @DocsEditable()
  final PerformanceTiming timing;

  @DomName('Performance.clearMarks')
  @DocsEditable()
  // https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/UserTiming/Overview.html#extensions-performance-interface
  @Experimental()
  void clearMarks(String markName) native;

  @DomName('Performance.clearMeasures')
  @DocsEditable()
  // https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/UserTiming/Overview.html#extensions-performance-interface
  @Experimental()
  void clearMeasures(String measureName) native;

  @DomName('Performance.getEntries')
  @DocsEditable()
  // http://www.w3.org/TR/performance-timeline/#sec-window.performance-attribute
  @Experimental()
  List<PerformanceEntry> getEntries() native;

  @DomName('Performance.getEntriesByName')
  @DocsEditable()
  // http://www.w3.org/TR/performance-timeline/#sec-window.performance-attribute
  @Experimental()
  List<PerformanceEntry> getEntriesByName(String name, String entryType) native;

  @DomName('Performance.getEntriesByType')
  @DocsEditable()
  // http://www.w3.org/TR/performance-timeline/#sec-window.performance-attribute
  @Experimental()
  List<PerformanceEntry> getEntriesByType(String entryType) native;

  @DomName('Performance.mark')
  @DocsEditable()
  // https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/UserTiming/Overview.html#extensions-performance-interface
  @Experimental()
  void mark(String markName) native;

  @DomName('Performance.measure')
  @DocsEditable()
  // https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/UserTiming/Overview.html#extensions-performance-interface
  @Experimental()
  void measure(String measureName, String startMark, String endMark) native;

  @DomName('Performance.now')
  @DocsEditable()
  double now() native;

  @JSName('webkitClearResourceTimings')
  @DomName('Performance.webkitClearResourceTimings')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.w3c-test.org/webperf/specs/ResourceTiming/#extensions-performance-interface
  void clearResourceTimings() native;

  @JSName('webkitSetResourceTimingBufferSize')
  @DomName('Performance.webkitSetResourceTimingBufferSize')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.w3c-test.org/webperf/specs/ResourceTiming/#performanceresourcetiming-methods
  void setResourceTimingBufferSize(int maxSize) native;

  /// Stream of `resourcetimingbufferfull` events handled by this [Performance].
  @DomName('Performance.onwebkitresourcetimingbufferfull')
  @DocsEditable()
  // http://www.w3c-test.org/webperf/specs/ResourceTiming/#performanceresourcetiming-methods
  @Experimental()
  Stream<Event> get onResourceTimingBufferFull => resourceTimingBufferFullEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('PerformanceEntry')
// http://www.w3.org/TR/performance-timeline/#sec-PerformanceEntry-interface
@Experimental()
class PerformanceEntry extends Interceptor native "PerformanceEntry" {
  // To suppress missing implicit constructor warnings.
  factory PerformanceEntry._() { throw new UnsupportedError("Not supported"); }

  @DomName('PerformanceEntry.duration')
  @DocsEditable()
  final double duration;

  @DomName('PerformanceEntry.entryType')
  @DocsEditable()
  final String entryType;

  @DomName('PerformanceEntry.name')
  @DocsEditable()
  final String name;

  @DomName('PerformanceEntry.startTime')
  @DocsEditable()
  final double startTime;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('PerformanceMark')
// http://www.w3.org/TR/user-timing/#performancemark
@Experimental()
class PerformanceMark extends PerformanceEntry native "PerformanceMark" {
  // To suppress missing implicit constructor warnings.
  factory PerformanceMark._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('PerformanceMeasure')
// http://www.w3.org/TR/user-timing/#performancemeasure
@Experimental()
class PerformanceMeasure extends PerformanceEntry native "PerformanceMeasure" {
  // To suppress missing implicit constructor warnings.
  factory PerformanceMeasure._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('PerformanceNavigation')
@Unstable()
class PerformanceNavigation extends Interceptor native "PerformanceNavigation" {
  // To suppress missing implicit constructor warnings.
  factory PerformanceNavigation._() { throw new UnsupportedError("Not supported"); }

  @DomName('PerformanceNavigation.TYPE_BACK_FORWARD')
  @DocsEditable()
  static const int TYPE_BACK_FORWARD = 2;

  @DomName('PerformanceNavigation.TYPE_NAVIGATE')
  @DocsEditable()
  static const int TYPE_NAVIGATE = 0;

  @DomName('PerformanceNavigation.TYPE_RELOAD')
  @DocsEditable()
  static const int TYPE_RELOAD = 1;

  @DomName('PerformanceNavigation.TYPE_RESERVED')
  @DocsEditable()
  static const int TYPE_RESERVED = 255;

  @DomName('PerformanceNavigation.redirectCount')
  @DocsEditable()
  final int redirectCount;

  @DomName('PerformanceNavigation.type')
  @DocsEditable()
  final int type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('PerformanceResourceTiming')
// http://www.w3c-test.org/webperf/specs/ResourceTiming/#performanceresourcetiming
@Experimental()
class PerformanceResourceTiming extends PerformanceEntry native "PerformanceResourceTiming" {
  // To suppress missing implicit constructor warnings.
  factory PerformanceResourceTiming._() { throw new UnsupportedError("Not supported"); }

  @DomName('PerformanceResourceTiming.connectEnd')
  @DocsEditable()
  final double connectEnd;

  @DomName('PerformanceResourceTiming.connectStart')
  @DocsEditable()
  final double connectStart;

  @DomName('PerformanceResourceTiming.domainLookupEnd')
  @DocsEditable()
  final double domainLookupEnd;

  @DomName('PerformanceResourceTiming.domainLookupStart')
  @DocsEditable()
  final double domainLookupStart;

  @DomName('PerformanceResourceTiming.fetchStart')
  @DocsEditable()
  final double fetchStart;

  @DomName('PerformanceResourceTiming.initiatorType')
  @DocsEditable()
  final String initiatorType;

  @DomName('PerformanceResourceTiming.redirectEnd')
  @DocsEditable()
  final double redirectEnd;

  @DomName('PerformanceResourceTiming.redirectStart')
  @DocsEditable()
  final double redirectStart;

  @DomName('PerformanceResourceTiming.requestStart')
  @DocsEditable()
  @Experimental() // nonstandard
  final double requestStart;

  @DomName('PerformanceResourceTiming.responseEnd')
  @DocsEditable()
  @Experimental() // nonstandard
  final double responseEnd;

  @DomName('PerformanceResourceTiming.responseStart')
  @DocsEditable()
  @Experimental() // nonstandard
  final double responseStart;

  @DomName('PerformanceResourceTiming.secureConnectionStart')
  @DocsEditable()
  final double secureConnectionStart;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('PerformanceTiming')
@Unstable()
class PerformanceTiming extends Interceptor native "PerformanceTiming" {
  // To suppress missing implicit constructor warnings.
  factory PerformanceTiming._() { throw new UnsupportedError("Not supported"); }

  @DomName('PerformanceTiming.connectEnd')
  @DocsEditable()
  final int connectEnd;

  @DomName('PerformanceTiming.connectStart')
  @DocsEditable()
  final int connectStart;

  @DomName('PerformanceTiming.domComplete')
  @DocsEditable()
  final int domComplete;

  @DomName('PerformanceTiming.domContentLoadedEventEnd')
  @DocsEditable()
  final int domContentLoadedEventEnd;

  @DomName('PerformanceTiming.domContentLoadedEventStart')
  @DocsEditable()
  final int domContentLoadedEventStart;

  @DomName('PerformanceTiming.domInteractive')
  @DocsEditable()
  final int domInteractive;

  @DomName('PerformanceTiming.domLoading')
  @DocsEditable()
  final int domLoading;

  @DomName('PerformanceTiming.domainLookupEnd')
  @DocsEditable()
  final int domainLookupEnd;

  @DomName('PerformanceTiming.domainLookupStart')
  @DocsEditable()
  final int domainLookupStart;

  @DomName('PerformanceTiming.fetchStart')
  @DocsEditable()
  final int fetchStart;

  @DomName('PerformanceTiming.loadEventEnd')
  @DocsEditable()
  final int loadEventEnd;

  @DomName('PerformanceTiming.loadEventStart')
  @DocsEditable()
  final int loadEventStart;

  @DomName('PerformanceTiming.navigationStart')
  @DocsEditable()
  final int navigationStart;

  @DomName('PerformanceTiming.redirectEnd')
  @DocsEditable()
  final int redirectEnd;

  @DomName('PerformanceTiming.redirectStart')
  @DocsEditable()
  final int redirectStart;

  @DomName('PerformanceTiming.requestStart')
  @DocsEditable()
  final int requestStart;

  @DomName('PerformanceTiming.responseEnd')
  @DocsEditable()
  final int responseEnd;

  @DomName('PerformanceTiming.responseStart')
  @DocsEditable()
  final int responseStart;

  @DomName('PerformanceTiming.secureConnectionStart')
  @DocsEditable()
  final int secureConnectionStart;

  @DomName('PerformanceTiming.unloadEventEnd')
  @DocsEditable()
  final int unloadEventEnd;

  @DomName('PerformanceTiming.unloadEventStart')
  @DocsEditable()
  final int unloadEventStart;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('Player')
@Experimental() // untriaged
class Player extends Interceptor native "Player" {
  // To suppress missing implicit constructor warnings.
  factory Player._() { throw new UnsupportedError("Not supported"); }

  @DomName('Player.currentTime')
  @DocsEditable()
  @Experimental() // untriaged
  num currentTime;

  @DomName('Player.finished')
  @DocsEditable()
  @Experimental() // untriaged
  final bool finished;

  @DomName('Player.paused')
  @DocsEditable()
  @Experimental() // untriaged
  final bool paused;

  @DomName('Player.playbackRate')
  @DocsEditable()
  @Experimental() // untriaged
  num playbackRate;

  @DomName('Player.source')
  @DocsEditable()
  @Experimental() // untriaged
  TimedItem source;

  @DomName('Player.startTime')
  @DocsEditable()
  @Experimental() // untriaged
  num startTime;

  @DomName('Player.timeLag')
  @DocsEditable()
  @Experimental() // untriaged
  final double timeLag;

  @DomName('Player.cancel')
  @DocsEditable()
  @Experimental() // untriaged
  void cancel() native;

  @DomName('Player.finish')
  @DocsEditable()
  @Experimental() // untriaged
  void finish() native;

  @DomName('Player.pause')
  @DocsEditable()
  @Experimental() // untriaged
  void pause() native;

  @DomName('Player.play')
  @DocsEditable()
  @Experimental() // untriaged
  void play() native;

  @DomName('Player.reverse')
  @DocsEditable()
  @Experimental() // untriaged
  void reverse() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('Plugin')
@Experimental() // non-standard
class Plugin extends Interceptor native "Plugin" {
  // To suppress missing implicit constructor warnings.
  factory Plugin._() { throw new UnsupportedError("Not supported"); }

  @DomName('Plugin.description')
  @DocsEditable()
  final String description;

  @DomName('Plugin.filename')
  @DocsEditable()
  final String filename;

  @DomName('Plugin.length')
  @DocsEditable()
  final int length;

  @DomName('Plugin.name')
  @DocsEditable()
  final String name;

  @DomName('Plugin.__getter__')
  @DocsEditable()
  MimeType __getter__(String name) native;

  @DomName('Plugin.item')
  @DocsEditable()
  MimeType item(int index) native;

  @DomName('Plugin.namedItem')
  @DocsEditable()
  MimeType namedItem(String name) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('PluginArray')
@Experimental() // non-standard
class PluginArray extends Interceptor with ListMixin<Plugin>, ImmutableListMixin<Plugin> implements JavaScriptIndexingBehavior, List<Plugin> native "PluginArray" {
  // To suppress missing implicit constructor warnings.
  factory PluginArray._() { throw new UnsupportedError("Not supported"); }

  @DomName('PluginArray.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  Plugin operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("Plugin", "#[#]", this, index);
  }
  void operator[]=(int index, Plugin value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Plugin> mixins.
  // Plugin is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Plugin get first {
    if (this.length > 0) {
      return JS('Plugin', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Plugin get last {
    int len = this.length;
    if (len > 0) {
      return JS('Plugin', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Plugin get single {
    int len = this.length;
    if (len == 1) {
      return JS('Plugin', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Plugin elementAt(int index) => this[index];
  // -- end List<Plugin> mixins.

  @DomName('PluginArray.__getter__')
  @DocsEditable()
  Plugin __getter__(String name) native;

  @DomName('PluginArray.item')
  @DocsEditable()
  Plugin item(int index) native;

  @DomName('PluginArray.namedItem')
  @DocsEditable()
  Plugin namedItem(String name) native;

  @DomName('PluginArray.refresh')
  @DocsEditable()
  void refresh(bool reload) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('PopStateEvent')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
class PopStateEvent extends Event native "PopStateEvent" {
  // To suppress missing implicit constructor warnings.
  factory PopStateEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('PopStateEvent.state')
  @DocsEditable()
  dynamic get state => convertNativeToDart_SerializedScriptValue(this._get_state);
  @JSName('state')
  @DomName('PopStateEvent.state')
  @DocsEditable()
  @annotation_Creates_SerializedScriptValue
  @annotation_Returns_SerializedScriptValue
  final dynamic _get_state;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('PositionCallback')
@Unstable()
typedef void _PositionCallback(Geoposition position);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('PositionError')
@Unstable()
class PositionError extends Interceptor native "PositionError" {
  // To suppress missing implicit constructor warnings.
  factory PositionError._() { throw new UnsupportedError("Not supported"); }

  @DomName('PositionError.PERMISSION_DENIED')
  @DocsEditable()
  static const int PERMISSION_DENIED = 1;

  @DomName('PositionError.POSITION_UNAVAILABLE')
  @DocsEditable()
  static const int POSITION_UNAVAILABLE = 2;

  @DomName('PositionError.TIMEOUT')
  @DocsEditable()
  static const int TIMEOUT = 3;

  @DomName('PositionError.code')
  @DocsEditable()
  final int code;

  @DomName('PositionError.message')
  @DocsEditable()
  final String message;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('PositionErrorCallback')
@Unstable()
typedef void _PositionErrorCallback(PositionError error);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLPreElement')
class PreElement extends HtmlElement native "HTMLPreElement" {
  // To suppress missing implicit constructor warnings.
  factory PreElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLPreElement.HTMLPreElement')
  @DocsEditable()
  factory PreElement() => document.createElement("pre");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  PreElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('ProcessingInstruction')
@Unstable()
class ProcessingInstruction extends CharacterData native "ProcessingInstruction" {
  // To suppress missing implicit constructor warnings.
  factory ProcessingInstruction._() { throw new UnsupportedError("Not supported"); }

  @DomName('ProcessingInstruction.sheet')
  @DocsEditable()
  @Experimental() // non-standard
  final StyleSheet sheet;

  @DomName('ProcessingInstruction.target')
  @DocsEditable()
  final String target;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLProgressElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
class ProgressElement extends HtmlElement native "HTMLProgressElement" {
  // To suppress missing implicit constructor warnings.
  factory ProgressElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLProgressElement.HTMLProgressElement')
  @DocsEditable()
  factory ProgressElement() => document.createElement("progress");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ProgressElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('progress');

  @DomName('HTMLProgressElement.labels')
  @DocsEditable()
  @Unstable()
  @Returns('NodeList')
  @Creates('NodeList')
  final List<Node> labels;

  @DomName('HTMLProgressElement.max')
  @DocsEditable()
  num max;

  @DomName('HTMLProgressElement.position')
  @DocsEditable()
  final double position;

  @DomName('HTMLProgressElement.value')
  @DocsEditable()
  num value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('ProgressEvent')
class ProgressEvent extends Event native "ProgressEvent" {
  // To suppress missing implicit constructor warnings.
  factory ProgressEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('ProgressEvent.lengthComputable')
  @DocsEditable()
  final bool lengthComputable;

  @DomName('ProgressEvent.loaded')
  @DocsEditable()
  final int loaded;

  @DomName('ProgressEvent.total')
  @DocsEditable()
  final int total;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLQuoteElement')
class QuoteElement extends HtmlElement native "HTMLQuoteElement" {
  // To suppress missing implicit constructor warnings.
  factory QuoteElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLQuoteElement.HTMLQuoteElement')
  @DocsEditable()
  factory QuoteElement() => document.createElement("q");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  QuoteElement.created() : super.created();

  @DomName('HTMLQuoteElement.cite')
  @DocsEditable()
  String cite;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('RTCErrorCallback')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#rtcerror
@Experimental()
typedef void _RtcErrorCallback(String errorInformation);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('RTCSessionDescriptionCallback')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCSessionDescription
@Experimental()
typedef void _RtcSessionDescriptionCallback(RtcSessionDescription sdp);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('RTCStatsCallback')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCStatsCallback
@Experimental()
typedef void RtcStatsCallback(RtcStatsResponse response);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('Range')
@Unstable()
class Range extends Interceptor native "Range" {
  factory Range() => document.createRange();

  factory Range.fromPoint(Point point) =>
      document._caretRangeFromPoint(point.x, point.y);
  // To suppress missing implicit constructor warnings.
  factory Range._() { throw new UnsupportedError("Not supported"); }

  @DomName('Range.END_TO_END')
  @DocsEditable()
  static const int END_TO_END = 2;

  @DomName('Range.END_TO_START')
  @DocsEditable()
  static const int END_TO_START = 3;

  @DomName('Range.NODE_AFTER')
  @DocsEditable()
  @Experimental() // nonstandard
  static const int NODE_AFTER = 1;

  @DomName('Range.NODE_BEFORE')
  @DocsEditable()
  @Experimental() // nonstandard
  static const int NODE_BEFORE = 0;

  @DomName('Range.NODE_BEFORE_AND_AFTER')
  @DocsEditable()
  @Experimental() // nonstandard
  static const int NODE_BEFORE_AND_AFTER = 2;

  @DomName('Range.NODE_INSIDE')
  @DocsEditable()
  @Experimental() // nonstandard
  static const int NODE_INSIDE = 3;

  @DomName('Range.START_TO_END')
  @DocsEditable()
  static const int START_TO_END = 1;

  @DomName('Range.START_TO_START')
  @DocsEditable()
  static const int START_TO_START = 0;

  @DomName('Range.collapsed')
  @DocsEditable()
  final bool collapsed;

  @DomName('Range.commonAncestorContainer')
  @DocsEditable()
  final Node commonAncestorContainer;

  @DomName('Range.endContainer')
  @DocsEditable()
  final Node endContainer;

  @DomName('Range.endOffset')
  @DocsEditable()
  final int endOffset;

  @DomName('Range.startContainer')
  @DocsEditable()
  final Node startContainer;

  @DomName('Range.startOffset')
  @DocsEditable()
  final int startOffset;

  @DomName('Range.cloneContents')
  @DocsEditable()
  DocumentFragment cloneContents() native;

  @DomName('Range.cloneRange')
  @DocsEditable()
  Range cloneRange() native;

  @DomName('Range.collapse')
  @DocsEditable()
  void collapse(bool toStart) native;

  @DomName('Range.comparePoint')
  @DocsEditable()
  int comparePoint(Node refNode, int offset) native;

  @DomName('Range.createContextualFragment')
  @DocsEditable()
  DocumentFragment createContextualFragment(String html) native;

  @DomName('Range.deleteContents')
  @DocsEditable()
  void deleteContents() native;

  @DomName('Range.detach')
  @DocsEditable()
  void detach() native;

  @DomName('Range.expand')
  @DocsEditable()
  @Experimental() // non-standard
  void expand(String unit) native;

  @DomName('Range.extractContents')
  @DocsEditable()
  DocumentFragment extractContents() native;

  @DomName('Range.getBoundingClientRect')
  @DocsEditable()
  Rectangle getBoundingClientRect() native;

  @DomName('Range.getClientRects')
  @DocsEditable()
  @Returns('_ClientRectList')
  @Creates('_ClientRectList')
  List<Rectangle> getClientRects() native;

  @DomName('Range.insertNode')
  @DocsEditable()
  void insertNode(Node newNode) native;

  @DomName('Range.isPointInRange')
  @DocsEditable()
  bool isPointInRange(Node refNode, int offset) native;

  @DomName('Range.selectNode')
  @DocsEditable()
  void selectNode(Node refNode) native;

  @DomName('Range.selectNodeContents')
  @DocsEditable()
  void selectNodeContents(Node refNode) native;

  @DomName('Range.setEnd')
  @DocsEditable()
  void setEnd(Node refNode, int offset) native;

  @DomName('Range.setEndAfter')
  @DocsEditable()
  void setEndAfter(Node refNode) native;

  @DomName('Range.setEndBefore')
  @DocsEditable()
  void setEndBefore(Node refNode) native;

  @DomName('Range.setStart')
  @DocsEditable()
  void setStart(Node refNode, int offset) native;

  @DomName('Range.setStartAfter')
  @DocsEditable()
  void setStartAfter(Node refNode) native;

  @DomName('Range.setStartBefore')
  @DocsEditable()
  void setStartBefore(Node refNode) native;

  @DomName('Range.surroundContents')
  @DocsEditable()
  void surroundContents(Node newParent) native;

  @DomName('Range.toString')
  @DocsEditable()
  String toString() native;


  /**
   * Checks if createContextualFragment is supported.
   *
   * See also:
   *
   * * [createContextualFragment]
   */
  static bool get supportsCreateContextualFragment =>
      JS('bool', '("createContextualFragment" in window.Range.prototype)');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('RequestAnimationFrameCallback')
typedef void RequestAnimationFrameCallback(num highResTime);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('ResourceProgressEvent')
// https://chromiumcodereview.appspot.com/14773025/
@deprecated // experimental
class ResourceProgressEvent extends ProgressEvent native "ResourceProgressEvent" {
  // To suppress missing implicit constructor warnings.
  factory ResourceProgressEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('ResourceProgressEvent.url')
  @DocsEditable()
  final String url;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('RTCDataChannel')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCDataChannel
@Experimental()
class RtcDataChannel extends EventTarget native "RTCDataChannel,DataChannel" {
  // To suppress missing implicit constructor warnings.
  factory RtcDataChannel._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `close` events to event
   * handlers that are not necessarily instances of [RtcDataChannel].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCDataChannel.closeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> closeEvent = const EventStreamProvider<Event>('close');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [RtcDataChannel].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCDataChannel.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [RtcDataChannel].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCDataChannel.messageEvent')
  @DocsEditable()
  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');

  /**
   * Static factory designed to expose `open` events to event
   * handlers that are not necessarily instances of [RtcDataChannel].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCDataChannel.openEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> openEvent = const EventStreamProvider<Event>('open');

  @DomName('RTCDataChannel.binaryType')
  @DocsEditable()
  String binaryType;

  @DomName('RTCDataChannel.bufferedAmount')
  @DocsEditable()
  final int bufferedAmount;

  @DomName('RTCDataChannel.id')
  @DocsEditable()
  @Experimental() // untriaged
  final int id;

  @DomName('RTCDataChannel.label')
  @DocsEditable()
  final String label;

  @DomName('RTCDataChannel.maxRetransmitTime')
  @DocsEditable()
  @Experimental() // untriaged
  final int maxRetransmitTime;

  @DomName('RTCDataChannel.maxRetransmits')
  @DocsEditable()
  @Experimental() // untriaged
  final int maxRetransmits;

  @DomName('RTCDataChannel.negotiated')
  @DocsEditable()
  @Experimental() // untriaged
  final bool negotiated;

  @DomName('RTCDataChannel.ordered')
  @DocsEditable()
  @Experimental() // untriaged
  final bool ordered;

  @DomName('RTCDataChannel.protocol')
  @DocsEditable()
  @Experimental() // untriaged
  final String protocol;

  @DomName('RTCDataChannel.readyState')
  @DocsEditable()
  final String readyState;

  @DomName('RTCDataChannel.reliable')
  @DocsEditable()
  final bool reliable;

  @DomName('RTCDataChannel.close')
  @DocsEditable()
  void close() native;

  @DomName('RTCDataChannel.send')
  @DocsEditable()
  void send(data) native;

  @JSName('send')
  @DomName('RTCDataChannel.send')
  @DocsEditable()
  void sendBlob(Blob data) native;

  @JSName('send')
  @DomName('RTCDataChannel.send')
  @DocsEditable()
  void sendByteBuffer(ByteBuffer data) native;

  @JSName('send')
  @DomName('RTCDataChannel.send')
  @DocsEditable()
  void sendString(String data) native;

  @JSName('send')
  @DomName('RTCDataChannel.send')
  @DocsEditable()
  void sendTypedData(TypedData data) native;

  /// Stream of `close` events handled by this [RtcDataChannel].
  @DomName('RTCDataChannel.onclose')
  @DocsEditable()
  Stream<Event> get onClose => closeEvent.forTarget(this);

  /// Stream of `error` events handled by this [RtcDataChannel].
  @DomName('RTCDataChannel.onerror')
  @DocsEditable()
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `message` events handled by this [RtcDataChannel].
  @DomName('RTCDataChannel.onmessage')
  @DocsEditable()
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  /// Stream of `open` events handled by this [RtcDataChannel].
  @DomName('RTCDataChannel.onopen')
  @DocsEditable()
  Stream<Event> get onOpen => openEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('RTCDataChannelEvent')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#rtcdatachannelevent
@Experimental()
class RtcDataChannelEvent extends Event native "RTCDataChannelEvent" {
  // To suppress missing implicit constructor warnings.
  factory RtcDataChannelEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('RTCDataChannelEvent.channel')
  @DocsEditable()
  final RtcDataChannel channel;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('RTCDTMFSender')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCDTMFSender
@Experimental()
class RtcDtmfSender extends EventTarget native "RTCDTMFSender" {
  // To suppress missing implicit constructor warnings.
  factory RtcDtmfSender._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `tonechange` events to event
   * handlers that are not necessarily instances of [RtcDtmfSender].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCDTMFSender.tonechangeEvent')
  @DocsEditable()
  static const EventStreamProvider<RtcDtmfToneChangeEvent> toneChangeEvent = const EventStreamProvider<RtcDtmfToneChangeEvent>('tonechange');

  @JSName('canInsertDTMF')
  @DomName('RTCDTMFSender.canInsertDTMF')
  @DocsEditable()
  final bool canInsertDtmf;

  @DomName('RTCDTMFSender.duration')
  @DocsEditable()
  final int duration;

  @DomName('RTCDTMFSender.interToneGap')
  @DocsEditable()
  final int interToneGap;

  @DomName('RTCDTMFSender.toneBuffer')
  @DocsEditable()
  final String toneBuffer;

  @DomName('RTCDTMFSender.track')
  @DocsEditable()
  final MediaStreamTrack track;

  @JSName('insertDTMF')
  @DomName('RTCDTMFSender.insertDTMF')
  @DocsEditable()
  void insertDtmf(String tones, [int duration, int interToneGap]) native;

  /// Stream of `tonechange` events handled by this [RtcDtmfSender].
  @DomName('RTCDTMFSender.ontonechange')
  @DocsEditable()
  Stream<RtcDtmfToneChangeEvent> get onToneChange => toneChangeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('RTCDTMFToneChangeEvent')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCDTMFToneChangeEvent
@Experimental()
class RtcDtmfToneChangeEvent extends Event native "RTCDTMFToneChangeEvent" {
  // To suppress missing implicit constructor warnings.
  factory RtcDtmfToneChangeEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('RTCDTMFToneChangeEvent.tone')
  @DocsEditable()
  final String tone;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('RTCIceCandidate')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCIceCandidate
class RtcIceCandidate extends Interceptor native "RTCIceCandidate,mozRTCIceCandidate" {
  factory RtcIceCandidate(Map dictionary) {
    // TODO(efortuna): Remove this check if when you can actually construct with
    // the unprefixed RTCIceCandidate in Firefox (currently both are defined,
    // but one can't be used as a constructor).
    var constructorName = JS('', 'window[#]',
        Device.isFirefox ? '${Device.propertyPrefix}RTCIceCandidate' :
        'RTCIceCandidate');
    return JS('RtcIceCandidate', 'new #(#)', constructorName,
        convertDartToNative_SerializedScriptValue(dictionary));
  }
  // To suppress missing implicit constructor warnings.
  factory RtcIceCandidate._() { throw new UnsupportedError("Not supported"); }

  @DomName('RTCIceCandidate.candidate')
  @DocsEditable()
  final String candidate;

  @DomName('RTCIceCandidate.sdpMLineIndex')
  @DocsEditable()
  final int sdpMLineIndex;

  @DomName('RTCIceCandidate.sdpMid')
  @DocsEditable()
  final String sdpMid;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('RTCIceCandidateEvent')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#rtcicecandidate-type
@Experimental()
class RtcIceCandidateEvent extends Event native "RTCIceCandidateEvent" {
  // To suppress missing implicit constructor warnings.
  factory RtcIceCandidateEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('RTCIceCandidateEvent.candidate')
  @DocsEditable()
  final RtcIceCandidate candidate;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('RTCPeerConnection')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCPeerConnection
class RtcPeerConnection extends EventTarget native "RTCPeerConnection,mozRTCPeerConnection" {
  factory RtcPeerConnection(Map rtcIceServers, [Map mediaConstraints]) {
    var constructorName = JS('RtcPeerConnection', 'window[#]',
        '${Device.propertyPrefix}RTCPeerConnection');
    if (mediaConstraints != null) {
      return JS('RtcPeerConnection', 'new #(#,#)', constructorName,
          convertDartToNative_SerializedScriptValue(rtcIceServers),
          convertDartToNative_SerializedScriptValue(mediaConstraints));
    } else {
      return JS('RtcPeerConnection', 'new #(#)', constructorName,
          convertDartToNative_SerializedScriptValue(rtcIceServers));
    }
  }

  /**
   * Checks if Real Time Communication (RTC) APIs are supported and enabled on
   * the current platform.
   */
  static bool get supported {
    // Currently in Firefox some of the RTC elements are defined but throw an
    // error unless the user has specifically enabled them in their
    // about:config. So we have to construct an element to actually test if RTC
    // is supported at the given time.
    try {
      new RtcPeerConnection(
          {"iceServers": [ {"url":"stun:localhost"}]});
      return true;
    } catch (_) { return false;}
    return false;
  }
  Future<RtcSessionDescription> createOffer([Map mediaConstraints]) {
    var completer = new Completer<RtcSessionDescription>();
    _createOffer(
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); }, mediaConstraints);
    return completer.future;
  }

  Future<RtcSessionDescription> createAnswer([Map mediaConstraints]) {
    var completer = new Completer<RtcSessionDescription>();
    _createAnswer(
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); }, mediaConstraints);
    return completer.future;
  }

  @DomName('RTCPeerConnection.getStats')
  Future<RtcStatsResponse> getStats(MediaStreamTrack selector) {
    var completer = new Completer<RtcStatsResponse>();
    _getStats((value) { completer.complete(value); }, selector);
    return completer.future;
  }
  // To suppress missing implicit constructor warnings.
  factory RtcPeerConnection._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `addstream` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCPeerConnection.addstreamEvent')
  @DocsEditable()
  static const EventStreamProvider<MediaStreamEvent> addStreamEvent = const EventStreamProvider<MediaStreamEvent>('addstream');

  /**
   * Static factory designed to expose `datachannel` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCPeerConnection.datachannelEvent')
  @DocsEditable()
  static const EventStreamProvider<RtcDataChannelEvent> dataChannelEvent = const EventStreamProvider<RtcDataChannelEvent>('datachannel');

  /**
   * Static factory designed to expose `icecandidate` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCPeerConnection.icecandidateEvent')
  @DocsEditable()
  static const EventStreamProvider<RtcIceCandidateEvent> iceCandidateEvent = const EventStreamProvider<RtcIceCandidateEvent>('icecandidate');

  /**
   * Static factory designed to expose `iceconnectionstatechange` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCPeerConnection.iceconnectionstatechangeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> iceConnectionStateChangeEvent = const EventStreamProvider<Event>('iceconnectionstatechange');

  /**
   * Static factory designed to expose `negotiationneeded` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCPeerConnection.negotiationneededEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> negotiationNeededEvent = const EventStreamProvider<Event>('negotiationneeded');

  /**
   * Static factory designed to expose `removestream` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCPeerConnection.removestreamEvent')
  @DocsEditable()
  static const EventStreamProvider<MediaStreamEvent> removeStreamEvent = const EventStreamProvider<MediaStreamEvent>('removestream');

  /**
   * Static factory designed to expose `signalingstatechange` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCPeerConnection.signalingstatechangeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> signalingStateChangeEvent = const EventStreamProvider<Event>('signalingstatechange');

  @DomName('RTCPeerConnection.iceConnectionState')
  @DocsEditable()
  final String iceConnectionState;

  @DomName('RTCPeerConnection.iceGatheringState')
  @DocsEditable()
  final String iceGatheringState;

  @DomName('RTCPeerConnection.localDescription')
  @DocsEditable()
  final RtcSessionDescription localDescription;

  @DomName('RTCPeerConnection.remoteDescription')
  @DocsEditable()
  final RtcSessionDescription remoteDescription;

  @DomName('RTCPeerConnection.signalingState')
  @DocsEditable()
  final String signalingState;

  @DomName('RTCPeerConnection.addIceCandidate')
  @DocsEditable()
  void addIceCandidate(RtcIceCandidate candidate, VoidCallback successCallback, _RtcErrorCallback failureCallback) native;

  @DomName('RTCPeerConnection.addStream')
  @DocsEditable()
  void addStream(MediaStream stream, [Map mediaConstraints]) {
    if (mediaConstraints != null) {
      var mediaConstraints_1 = convertDartToNative_Dictionary(mediaConstraints);
      _addStream_1(stream, mediaConstraints_1);
      return;
    }
    _addStream_2(stream);
    return;
  }
  @JSName('addStream')
  @DomName('RTCPeerConnection.addStream')
  @DocsEditable()
  void _addStream_1(MediaStream stream, mediaConstraints) native;
  @JSName('addStream')
  @DomName('RTCPeerConnection.addStream')
  @DocsEditable()
  void _addStream_2(MediaStream stream) native;

  @DomName('RTCPeerConnection.close')
  @DocsEditable()
  void close() native;

  @DomName('RTCPeerConnection.createAnswer')
  @DocsEditable()
  void _createAnswer(_RtcSessionDescriptionCallback successCallback, [_RtcErrorCallback failureCallback, Map mediaConstraints]) {
    if (mediaConstraints != null) {
      var mediaConstraints_1 = convertDartToNative_Dictionary(mediaConstraints);
      _createAnswer_1(successCallback, failureCallback, mediaConstraints_1);
      return;
    }
    _createAnswer_2(successCallback, failureCallback);
    return;
  }
  @JSName('createAnswer')
  @DomName('RTCPeerConnection.createAnswer')
  @DocsEditable()
  void _createAnswer_1(_RtcSessionDescriptionCallback successCallback, _RtcErrorCallback failureCallback, mediaConstraints) native;
  @JSName('createAnswer')
  @DomName('RTCPeerConnection.createAnswer')
  @DocsEditable()
  void _createAnswer_2(_RtcSessionDescriptionCallback successCallback, _RtcErrorCallback failureCallback) native;

  @JSName('createDTMFSender')
  @DomName('RTCPeerConnection.createDTMFSender')
  @DocsEditable()
  RtcDtmfSender createDtmfSender(MediaStreamTrack track) native;

  @DomName('RTCPeerConnection.createDataChannel')
  @DocsEditable()
  RtcDataChannel createDataChannel(String label, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _createDataChannel_1(label, options_1);
    }
    return _createDataChannel_2(label);
  }
  @JSName('createDataChannel')
  @DomName('RTCPeerConnection.createDataChannel')
  @DocsEditable()
  RtcDataChannel _createDataChannel_1(label, options) native;
  @JSName('createDataChannel')
  @DomName('RTCPeerConnection.createDataChannel')
  @DocsEditable()
  RtcDataChannel _createDataChannel_2(label) native;

  @DomName('RTCPeerConnection.createOffer')
  @DocsEditable()
  void _createOffer(_RtcSessionDescriptionCallback successCallback, [_RtcErrorCallback failureCallback, Map mediaConstraints]) {
    if (mediaConstraints != null) {
      var mediaConstraints_1 = convertDartToNative_Dictionary(mediaConstraints);
      _createOffer_1(successCallback, failureCallback, mediaConstraints_1);
      return;
    }
    _createOffer_2(successCallback, failureCallback);
    return;
  }
  @JSName('createOffer')
  @DomName('RTCPeerConnection.createOffer')
  @DocsEditable()
  void _createOffer_1(_RtcSessionDescriptionCallback successCallback, _RtcErrorCallback failureCallback, mediaConstraints) native;
  @JSName('createOffer')
  @DomName('RTCPeerConnection.createOffer')
  @DocsEditable()
  void _createOffer_2(_RtcSessionDescriptionCallback successCallback, _RtcErrorCallback failureCallback) native;

  @DomName('RTCPeerConnection.getLocalStreams')
  @DocsEditable()
  List<MediaStream> getLocalStreams() native;

  @DomName('RTCPeerConnection.getRemoteStreams')
  @DocsEditable()
  List<MediaStream> getRemoteStreams() native;

  @JSName('getStats')
  @DomName('RTCPeerConnection.getStats')
  @DocsEditable()
  void _getStats(RtcStatsCallback successCallback, MediaStreamTrack selector) native;

  @DomName('RTCPeerConnection.getStreamById')
  @DocsEditable()
  MediaStream getStreamById(String streamId) native;

  @DomName('RTCPeerConnection.removeStream')
  @DocsEditable()
  void removeStream(MediaStream stream) native;

  @JSName('setLocalDescription')
  @DomName('RTCPeerConnection.setLocalDescription')
  @DocsEditable()
  void _setLocalDescription(RtcSessionDescription description, [VoidCallback successCallback, _RtcErrorCallback failureCallback]) native;

  @JSName('setLocalDescription')
  @DomName('RTCPeerConnection.setLocalDescription')
  @DocsEditable()
  Future setLocalDescription(RtcSessionDescription description) {
    var completer = new Completer();
    _setLocalDescription(description,
        () { completer.complete(); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  @JSName('setRemoteDescription')
  @DomName('RTCPeerConnection.setRemoteDescription')
  @DocsEditable()
  void _setRemoteDescription(RtcSessionDescription description, [VoidCallback successCallback, _RtcErrorCallback failureCallback]) native;

  @JSName('setRemoteDescription')
  @DomName('RTCPeerConnection.setRemoteDescription')
  @DocsEditable()
  Future setRemoteDescription(RtcSessionDescription description) {
    var completer = new Completer();
    _setRemoteDescription(description,
        () { completer.complete(); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  @DomName('RTCPeerConnection.updateIce')
  @DocsEditable()
  void updateIce([Map configuration, Map mediaConstraints]) {
    if (mediaConstraints != null) {
      var configuration_1 = convertDartToNative_Dictionary(configuration);
      var mediaConstraints_2 = convertDartToNative_Dictionary(mediaConstraints);
      _updateIce_1(configuration_1, mediaConstraints_2);
      return;
    }
    if (configuration != null) {
      var configuration_3 = convertDartToNative_Dictionary(configuration);
      _updateIce_2(configuration_3);
      return;
    }
    _updateIce_3();
    return;
  }
  @JSName('updateIce')
  @DomName('RTCPeerConnection.updateIce')
  @DocsEditable()
  void _updateIce_1(configuration, mediaConstraints) native;
  @JSName('updateIce')
  @DomName('RTCPeerConnection.updateIce')
  @DocsEditable()
  void _updateIce_2(configuration) native;
  @JSName('updateIce')
  @DomName('RTCPeerConnection.updateIce')
  @DocsEditable()
  void _updateIce_3() native;

  /// Stream of `addstream` events handled by this [RtcPeerConnection].
  @DomName('RTCPeerConnection.onaddstream')
  @DocsEditable()
  Stream<MediaStreamEvent> get onAddStream => addStreamEvent.forTarget(this);

  /// Stream of `datachannel` events handled by this [RtcPeerConnection].
  @DomName('RTCPeerConnection.ondatachannel')
  @DocsEditable()
  Stream<RtcDataChannelEvent> get onDataChannel => dataChannelEvent.forTarget(this);

  /// Stream of `icecandidate` events handled by this [RtcPeerConnection].
  @DomName('RTCPeerConnection.onicecandidate')
  @DocsEditable()
  Stream<RtcIceCandidateEvent> get onIceCandidate => iceCandidateEvent.forTarget(this);

  /// Stream of `iceconnectionstatechange` events handled by this [RtcPeerConnection].
  @DomName('RTCPeerConnection.oniceconnectionstatechange')
  @DocsEditable()
  Stream<Event> get onIceConnectionStateChange => iceConnectionStateChangeEvent.forTarget(this);

  /// Stream of `negotiationneeded` events handled by this [RtcPeerConnection].
  @DomName('RTCPeerConnection.onnegotiationneeded')
  @DocsEditable()
  Stream<Event> get onNegotiationNeeded => negotiationNeededEvent.forTarget(this);

  /// Stream of `removestream` events handled by this [RtcPeerConnection].
  @DomName('RTCPeerConnection.onremovestream')
  @DocsEditable()
  Stream<MediaStreamEvent> get onRemoveStream => removeStreamEvent.forTarget(this);

  /// Stream of `signalingstatechange` events handled by this [RtcPeerConnection].
  @DomName('RTCPeerConnection.onsignalingstatechange')
  @DocsEditable()
  Stream<Event> get onSignalingStateChange => signalingStateChangeEvent.forTarget(this);

}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('RTCSessionDescription')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCSessionDescription
class RtcSessionDescription extends Interceptor native "RTCSessionDescription,mozRTCSessionDescription" {
  factory RtcSessionDescription(Map dictionary) {
    // TODO(efortuna): Remove this check if when you can actually construct with
    // the unprefixed RTCIceCandidate in Firefox (currently both are defined,
    // but one can't be used as a constructor).
    var constructorName = JS('', 'window[#]',
        Device.isFirefox ? '${Device.propertyPrefix}RTCSessionDescription' :
       'RTCSessionDescription');
    return JS('RtcSessionDescription',
        'new #(#)', constructorName,
        convertDartToNative_SerializedScriptValue(dictionary));
  }
  // To suppress missing implicit constructor warnings.
  factory RtcSessionDescription._() { throw new UnsupportedError("Not supported"); }

  @DomName('RTCSessionDescription.sdp')
  @DocsEditable()
  String sdp;

  @DomName('RTCSessionDescription.type')
  @DocsEditable()
  String type;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('RTCStatsReport')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCStatsReport
@Experimental()
class RtcStatsReport extends Interceptor native "RTCStatsReport" {
  // To suppress missing implicit constructor warnings.
  factory RtcStatsReport._() { throw new UnsupportedError("Not supported"); }

  @DomName('RTCStatsReport.id')
  @DocsEditable()
  final String id;

  @DomName('RTCStatsReport.local')
  @DocsEditable()
  final RtcStatsReport local;

  @DomName('RTCStatsReport.remote')
  @DocsEditable()
  final RtcStatsReport remote;

  @DomName('RTCStatsReport.timestamp')
  @DocsEditable()
  DateTime get timestamp => convertNativeToDart_DateTime(this._get_timestamp);
  @JSName('timestamp')
  @DomName('RTCStatsReport.timestamp')
  @DocsEditable()
  @Creates('Null')
  final dynamic _get_timestamp;

  @DomName('RTCStatsReport.type')
  @DocsEditable()
  final String type;

  @DomName('RTCStatsReport.names')
  @DocsEditable()
  List<String> names() native;

  @DomName('RTCStatsReport.stat')
  @DocsEditable()
  String stat(String name) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('RTCStatsResponse')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#widl-RTCStatsReport-RTCStats-getter-DOMString-id
@Experimental()
class RtcStatsResponse extends Interceptor native "RTCStatsResponse" {
  // To suppress missing implicit constructor warnings.
  factory RtcStatsResponse._() { throw new UnsupportedError("Not supported"); }

  @DomName('RTCStatsResponse.__getter__')
  @DocsEditable()
  RtcStatsReport __getter__(String name) native;

  @DomName('RTCStatsResponse.namedItem')
  @DocsEditable()
  RtcStatsReport namedItem(String name) native;

  @DomName('RTCStatsResponse.result')
  @DocsEditable()
  List<RtcStatsReport> result() native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('Screen')
class Screen extends EventTarget native "Screen" {

  @DomName('Screen.availHeight')
  @DomName('Screen.availLeft')
  @DomName('Screen.availTop')
  @DomName('Screen.availWidth')
  Rectangle get available => new Rectangle(_availLeft, _availTop, _availWidth,
      _availHeight);
  // To suppress missing implicit constructor warnings.
  factory Screen._() { throw new UnsupportedError("Not supported"); }

  @JSName('availHeight')
  @DomName('Screen.availHeight')
  @DocsEditable()
  final int _availHeight;

  @JSName('availLeft')
  @DomName('Screen.availLeft')
  @DocsEditable()
  @Experimental() // nonstandard
  final int _availLeft;

  @JSName('availTop')
  @DomName('Screen.availTop')
  @DocsEditable()
  @Experimental() // nonstandard
  final int _availTop;

  @JSName('availWidth')
  @DomName('Screen.availWidth')
  @DocsEditable()
  final int _availWidth;

  @DomName('Screen.colorDepth')
  @DocsEditable()
  final int colorDepth;

  @DomName('Screen.height')
  @DocsEditable()
  final int height;

  @DomName('Screen.orientation')
  @DocsEditable()
  @Experimental() // untriaged
  final String orientation;

  @DomName('Screen.pixelDepth')
  @DocsEditable()
  final int pixelDepth;

  @DomName('Screen.width')
  @DocsEditable()
  final int width;

  @DomName('Screen.lockOrientation')
  @DocsEditable()
  @Experimental() // untriaged
  bool lockOrientation(String orientation) native;

  @DomName('Screen.unlockOrientation')
  @DocsEditable()
  @Experimental() // untriaged
  void unlockOrientation() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLScriptElement')
class ScriptElement extends HtmlElement native "HTMLScriptElement" {
  // To suppress missing implicit constructor warnings.
  factory ScriptElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLScriptElement.HTMLScriptElement')
  @DocsEditable()
  factory ScriptElement() => document.createElement("script");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ScriptElement.created() : super.created();

  @DomName('HTMLScriptElement.async')
  @DocsEditable()
  bool async;

  @DomName('HTMLScriptElement.charset')
  @DocsEditable()
  String charset;

  @DomName('HTMLScriptElement.crossOrigin')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#attr-script-crossorigin
  @Experimental()
  String crossOrigin;

  @DomName('HTMLScriptElement.defer')
  @DocsEditable()
  bool defer;

  @DomName('HTMLScriptElement.nonce')
  @DocsEditable()
  // https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#interaction-with-the-script-src-directive
  @Experimental()
  String nonce;

  @DomName('HTMLScriptElement.src')
  @DocsEditable()
  String src;

  @DomName('HTMLScriptElement.type')
  @DocsEditable()
  String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('SecurityPolicyViolationEvent')
// https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#securitypolicyviolationevent-events
@Experimental()
class SecurityPolicyViolationEvent extends Event native "SecurityPolicyViolationEvent" {
  // To suppress missing implicit constructor warnings.
  factory SecurityPolicyViolationEvent._() { throw new UnsupportedError("Not supported"); }

  @JSName('blockedURI')
  @DomName('SecurityPolicyViolationEvent.blockedURI')
  @DocsEditable()
  final String blockedUri;

  @DomName('SecurityPolicyViolationEvent.columnNumber')
  @DocsEditable()
  final int columnNumber;

  @JSName('documentURI')
  @DomName('SecurityPolicyViolationEvent.documentURI')
  @DocsEditable()
  final String documentUri;

  @DomName('SecurityPolicyViolationEvent.effectiveDirective')
  @DocsEditable()
  final String effectiveDirective;

  @DomName('SecurityPolicyViolationEvent.lineNumber')
  @DocsEditable()
  final int lineNumber;

  @DomName('SecurityPolicyViolationEvent.originalPolicy')
  @DocsEditable()
  final String originalPolicy;

  @DomName('SecurityPolicyViolationEvent.referrer')
  @DocsEditable()
  final String referrer;

  @DomName('SecurityPolicyViolationEvent.sourceFile')
  @DocsEditable()
  final String sourceFile;

  @DomName('SecurityPolicyViolationEvent.statusCode')
  @DocsEditable()
  @Experimental() // untriaged
  final int statusCode;

  @DomName('SecurityPolicyViolationEvent.violatedDirective')
  @DocsEditable()
  final String violatedDirective;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('HTMLSelectElement')
class SelectElement extends HtmlElement native "HTMLSelectElement" {
  // To suppress missing implicit constructor warnings.
  factory SelectElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLSelectElement.HTMLSelectElement')
  @DocsEditable()
  factory SelectElement() => document.createElement("select");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  SelectElement.created() : super.created();

  @DomName('HTMLSelectElement.autofocus')
  @DocsEditable()
  bool autofocus;

  @DomName('HTMLSelectElement.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('HTMLSelectElement.form')
  @DocsEditable()
  final FormElement form;

  @DomName('HTMLSelectElement.labels')
  @DocsEditable()
  @Unstable()
  @Returns('NodeList')
  @Creates('NodeList')
  final List<Node> labels;

  @DomName('HTMLSelectElement.length')
  @DocsEditable()
  int length;

  @DomName('HTMLSelectElement.multiple')
  @DocsEditable()
  bool multiple;

  @DomName('HTMLSelectElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLSelectElement.required')
  @DocsEditable()
  bool required;

  @DomName('HTMLSelectElement.selectedIndex')
  @DocsEditable()
  int selectedIndex;

  @DomName('HTMLSelectElement.size')
  @DocsEditable()
  int size;

  @DomName('HTMLSelectElement.type')
  @DocsEditable()
  final String type;

  @DomName('HTMLSelectElement.validationMessage')
  @DocsEditable()
  final String validationMessage;

  @DomName('HTMLSelectElement.validity')
  @DocsEditable()
  final ValidityState validity;

  @DomName('HTMLSelectElement.value')
  @DocsEditable()
  String value;

  @DomName('HTMLSelectElement.willValidate')
  @DocsEditable()
  final bool willValidate;

  @DomName('HTMLSelectElement.__setter__')
  @DocsEditable()
  void __setter__(int index, OptionElement value) native;

  @DomName('HTMLSelectElement.checkValidity')
  @DocsEditable()
  bool checkValidity() native;

  @DomName('HTMLSelectElement.item')
  @DocsEditable()
  Element item(int index) native;

  @DomName('HTMLSelectElement.namedItem')
  @DocsEditable()
  Element namedItem(String name) native;

  @DomName('HTMLSelectElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) native;


  // Override default options, since IE returns SelectElement itself and it
  // does not operate as a List.
  List<OptionElement> get options {
    var options = this.querySelectorAll('option').where(
        (e) => e is OptionElement).toList();
    return new UnmodifiableListView(options);
  }

  List<OptionElement> get selectedOptions {
    // IE does not change the selected flag for single-selection items.
    if (this.multiple) {
      var options = this.options.where((o) => o.selected).toList();
      return new UnmodifiableListView(options);
    } else {
      return [this.options[this.selectedIndex]];
    }
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('Selection')
class Selection extends Interceptor native "Selection" {
  // To suppress missing implicit constructor warnings.
  factory Selection._() { throw new UnsupportedError("Not supported"); }

  @DomName('Selection.anchorNode')
  @DocsEditable()
  final Node anchorNode;

  @DomName('Selection.anchorOffset')
  @DocsEditable()
  final int anchorOffset;

  @DomName('Selection.baseNode')
  @DocsEditable()
  @Experimental() // non-standard
  final Node baseNode;

  @DomName('Selection.baseOffset')
  @DocsEditable()
  @Experimental() // non-standard
  final int baseOffset;

  @DomName('Selection.extentNode')
  @DocsEditable()
  @Experimental() // non-standard
  final Node extentNode;

  @DomName('Selection.extentOffset')
  @DocsEditable()
  @Experimental() // non-standard
  final int extentOffset;

  @DomName('Selection.focusNode')
  @DocsEditable()
  final Node focusNode;

  @DomName('Selection.focusOffset')
  @DocsEditable()
  final int focusOffset;

  @DomName('Selection.isCollapsed')
  @DocsEditable()
  final bool isCollapsed;

  @DomName('Selection.rangeCount')
  @DocsEditable()
  final int rangeCount;

  @DomName('Selection.type')
  @DocsEditable()
  @Experimental() // non-standard
  final String type;

  @DomName('Selection.addRange')
  @DocsEditable()
  void addRange(Range range) native;

  @DomName('Selection.collapse')
  @DocsEditable()
  void collapse(Node node, int index) native;

  @DomName('Selection.collapseToEnd')
  @DocsEditable()
  void collapseToEnd() native;

  @DomName('Selection.collapseToStart')
  @DocsEditable()
  void collapseToStart() native;

  @DomName('Selection.containsNode')
  @DocsEditable()
  @Experimental() // non-standard
  bool containsNode(Node node, bool allowPartial) native;

  @DomName('Selection.deleteFromDocument')
  @DocsEditable()
  void deleteFromDocument() native;

  @DomName('Selection.empty')
  @DocsEditable()
  @Experimental() // non-standard
  void empty() native;

  @DomName('Selection.extend')
  @DocsEditable()
  void extend(Node node, int offset) native;

  @DomName('Selection.getRangeAt')
  @DocsEditable()
  Range getRangeAt(int index) native;

  @DomName('Selection.modify')
  @DocsEditable()
  @Experimental() // non-standard
  void modify(String alter, String direction, String granularity) native;

  @DomName('Selection.removeAllRanges')
  @DocsEditable()
  void removeAllRanges() native;

  @DomName('Selection.selectAllChildren')
  @DocsEditable()
  void selectAllChildren(Node node) native;

  @DomName('Selection.setBaseAndExtent')
  @DocsEditable()
  @Experimental() // non-standard
  void setBaseAndExtent(Node baseNode, int baseOffset, Node extentNode, int extentOffset) native;

  @DomName('Selection.setPosition')
  @DocsEditable()
  @Experimental() // non-standard
  void setPosition(Node node, int offset) native;

  @DomName('Selection.toString')
  @DocsEditable()
  String toString() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('ServiceWorkerContainer')
@Experimental() // untriaged
class ServiceWorkerContainer extends Interceptor native "ServiceWorkerContainer" {
  // To suppress missing implicit constructor warnings.
  factory ServiceWorkerContainer._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('ServiceWorkerGlobalScope')
@Experimental() // untriaged
class ServiceWorkerGlobalScope extends WorkerGlobalScope native "ServiceWorkerGlobalScope" {
  // To suppress missing implicit constructor warnings.
  factory ServiceWorkerGlobalScope._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLShadowElement')
@SupportedBrowser(SupportedBrowser.CHROME, '26')
@Experimental()
// https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#shadow-element
class ShadowElement extends HtmlElement native "HTMLShadowElement" {
  // To suppress missing implicit constructor warnings.
  factory ShadowElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLShadowElement.HTMLShadowElement')
  @DocsEditable()
  factory ShadowElement() => document.createElement("shadow");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ShadowElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('shadow');

  @DomName('HTMLShadowElement.resetStyleInheritance')
  @DocsEditable()
  bool resetStyleInheritance;

  @DomName('HTMLShadowElement.getDistributedNodes')
  @DocsEditable()
  @Experimental() // untriaged
  @Returns('NodeList')
  @Creates('NodeList')
  List<Node> getDistributedNodes() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('ShadowRoot')
@SupportedBrowser(SupportedBrowser.CHROME, '26')
@Experimental()
// https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#api-shadow-root
class ShadowRoot extends DocumentFragment native "ShadowRoot" {
  // To suppress missing implicit constructor warnings.
  factory ShadowRoot._() { throw new UnsupportedError("Not supported"); }

  @DomName('ShadowRoot.activeElement')
  @DocsEditable()
  final Element activeElement;

  @DomName('ShadowRoot.host')
  @DocsEditable()
  @Experimental() // untriaged
  final Element host;

  @JSName('innerHTML')
  @DomName('ShadowRoot.innerHTML')
  @DocsEditable()
  String innerHtml;

  @DomName('ShadowRoot.olderShadowRoot')
  @DocsEditable()
  @Experimental() // untriaged
  final ShadowRoot olderShadowRoot;

  @JSName('resetStyleInheritance')
  @DomName('ShadowRoot.resetStyleInheritance')
  @DocsEditable()
  bool _resetStyleInheritance;

  @DomName('ShadowRoot.styleSheets')
  @DocsEditable()
  @Experimental() // untriaged
  @Returns('_StyleSheetList')
  @Creates('_StyleSheetList')
  final List<StyleSheet> styleSheets;

  @JSName('cloneNode')
  @DomName('ShadowRoot.cloneNode')
  @DocsEditable()
  Node clone(bool deep) native;

  @DomName('ShadowRoot.elementFromPoint')
  @DocsEditable()
  Element elementFromPoint(int x, int y) native;

  @DomName('ShadowRoot.getElementById')
  @DocsEditable()
  Element getElementById(String elementId) native;

  @DomName('ShadowRoot.getElementsByClassName')
  @DocsEditable()
  @Creates('NodeList|HtmlCollection')
  @Returns('NodeList|HtmlCollection')
  List<Node> getElementsByClassName(String className) native;

  @DomName('ShadowRoot.getElementsByTagName')
  @DocsEditable()
  @Creates('NodeList|HtmlCollection')
  @Returns('NodeList|HtmlCollection')
  List<Node> getElementsByTagName(String tagName) native;

  @DomName('ShadowRoot.getSelection')
  @DocsEditable()
  Selection getSelection() native;

  static bool get supported =>
      JS('bool', '!!(Element.prototype.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
  void set resetStyleInheritance(bool value) {
    _shadowRootDeprecationReport();
  }

  @deprecated
  bool get applyAuthorStyles {
    _shadowRootDeprecationReport();
    // Default value from when it was specified.
    return false;
  }

  @deprecated
  void 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()
class SharedWorker extends EventTarget implements AbstractWorker native "SharedWorker" {
  // To suppress missing implicit constructor warnings.
  factory SharedWorker._() { throw new UnsupportedError("Not supported"); }

  @DomName('SharedWorker.errorEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  @DomName('SharedWorker.SharedWorker')
  @DocsEditable()
  factory SharedWorker(String scriptURL, [String name]) {
    if (name != null) {
      return SharedWorker._create_1(scriptURL, name);
    }
    return SharedWorker._create_2(scriptURL);
  }
  static SharedWorker _create_1(scriptURL, name) => JS('SharedWorker', 'new SharedWorker(#,#)', scriptURL, name);
  static SharedWorker _create_2(scriptURL) => JS('SharedWorker', 'new SharedWorker(#)', scriptURL);

  @DomName('SharedWorker.port')
  @DocsEditable()
  final MessagePort port;

  @DomName('SharedWorker.workerStart')
  @DocsEditable()
  @Experimental() // untriaged
  final double workerStart;

  @DomName('SharedWorker.onerror')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onError => errorEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('SharedWorkerGlobalScope')
@Experimental() // untriaged
class SharedWorkerGlobalScope extends WorkerGlobalScope native "SharedWorkerGlobalScope" {
  // To suppress missing implicit constructor warnings.
  factory SharedWorkerGlobalScope._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `connect` events to event
   * handlers that are not necessarily instances of [SharedWorkerGlobalScope].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SharedWorkerGlobalScope.connectEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> connectEvent = const EventStreamProvider<Event>('connect');

  @DomName('SharedWorkerGlobalScope.name')
  @DocsEditable()
  @Experimental() // untriaged
  final String name;

  /// Stream of `connect` events handled by this [SharedWorkerGlobalScope].
  @DomName('SharedWorkerGlobalScope.onconnect')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onConnect => connectEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('SourceBuffer')
// https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#sourcebuffer
@Experimental()
class SourceBuffer extends EventTarget native "SourceBuffer" {
  // To suppress missing implicit constructor warnings.
  factory SourceBuffer._() { throw new UnsupportedError("Not supported"); }

  @DomName('SourceBuffer.appendWindowEnd')
  @DocsEditable()
  @Experimental() // untriaged
  num appendWindowEnd;

  @DomName('SourceBuffer.appendWindowStart')
  @DocsEditable()
  @Experimental() // untriaged
  num appendWindowStart;

  @DomName('SourceBuffer.buffered')
  @DocsEditable()
  final TimeRanges buffered;

  @DomName('SourceBuffer.mode')
  @DocsEditable()
  @Experimental() // untriaged
  String mode;

  @DomName('SourceBuffer.timestampOffset')
  @DocsEditable()
  num timestampOffset;

  @DomName('SourceBuffer.updating')
  @DocsEditable()
  @Experimental() // untriaged
  final bool updating;

  @DomName('SourceBuffer.abort')
  @DocsEditable()
  void abort() native;

  @DomName('SourceBuffer.appendBuffer')
  @DocsEditable()
  @Experimental() // untriaged
  void appendBuffer(ByteBuffer data) native;

  @DomName('SourceBuffer.appendStream')
  @DocsEditable()
  @Experimental() // untriaged
  void appendStream(FileStream stream, [int maxSize]) native;

  @JSName('appendBuffer')
  @DomName('SourceBuffer.appendBuffer')
  @DocsEditable()
  @Experimental() // untriaged
  void appendTypedData(TypedData data) native;

  @DomName('SourceBuffer.remove')
  @DocsEditable()
  @Experimental() // untriaged
  void remove(num start, num end) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('SourceBufferList')
// https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#sourcebufferlist
@Experimental()
class SourceBufferList extends EventTarget with ListMixin<SourceBuffer>, ImmutableListMixin<SourceBuffer> implements JavaScriptIndexingBehavior, List<SourceBuffer> native "SourceBufferList" {
  // To suppress missing implicit constructor warnings.
  factory SourceBufferList._() { throw new UnsupportedError("Not supported"); }

  @DomName('SourceBufferList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  SourceBuffer operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("SourceBuffer", "#[#]", this, index);
  }
  void operator[]=(int index, SourceBuffer value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<SourceBuffer> mixins.
  // SourceBuffer is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  SourceBuffer get first {
    if (this.length > 0) {
      return JS('SourceBuffer', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  SourceBuffer get last {
    int len = this.length;
    if (len > 0) {
      return JS('SourceBuffer', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  SourceBuffer get single {
    int len = this.length;
    if (len == 1) {
      return JS('SourceBuffer', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  SourceBuffer elementAt(int index) => this[index];
  // -- end List<SourceBuffer> mixins.

  @DomName('SourceBufferList.item')
  @DocsEditable()
  SourceBuffer item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLSourceElement')
class SourceElement extends HtmlElement native "HTMLSourceElement" {
  // To suppress missing implicit constructor warnings.
  factory SourceElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLSourceElement.HTMLSourceElement')
  @DocsEditable()
  factory SourceElement() => document.createElement("source");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  SourceElement.created() : super.created();

  @DomName('HTMLSourceElement.media')
  @DocsEditable()
  String media;

  @DomName('HTMLSourceElement.src')
  @DocsEditable()
  String src;

  @DomName('HTMLSourceElement.type')
  @DocsEditable()
  String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('SourceInfo')
@Experimental() // untriaged
class SourceInfo extends Interceptor native "SourceInfo" {
  // To suppress missing implicit constructor warnings.
  factory SourceInfo._() { throw new UnsupportedError("Not supported"); }

  @DomName('SourceInfo.facing')
  @DocsEditable()
  @Experimental() // untriaged
  final String facing;

  @DomName('SourceInfo.id')
  @DocsEditable()
  @Experimental() // untriaged
  final String id;

  @DomName('SourceInfo.kind')
  @DocsEditable()
  @Experimental() // untriaged
  final String kind;

  @DomName('SourceInfo.label')
  @DocsEditable()
  @Experimental() // untriaged
  final String label;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLSpanElement')
class SpanElement extends HtmlElement native "HTMLSpanElement" {
  // To suppress missing implicit constructor warnings.
  factory SpanElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLSpanElement.HTMLSpanElement')
  @DocsEditable()
  factory SpanElement() => document.createElement("span");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  SpanElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('SpeechGrammar')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#dfn-speechgrammar
@Experimental()
class SpeechGrammar extends Interceptor native "SpeechGrammar" {
  // To suppress missing implicit constructor warnings.
  factory SpeechGrammar._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechGrammar.SpeechGrammar')
  @DocsEditable()
  factory SpeechGrammar() {
    return SpeechGrammar._create_1();
  }
  static SpeechGrammar _create_1() => JS('SpeechGrammar', 'new SpeechGrammar()');

  @DomName('SpeechGrammar.src')
  @DocsEditable()
  String src;

  @DomName('SpeechGrammar.weight')
  @DocsEditable()
  num weight;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('SpeechGrammarList')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#dfn-speechgrammarlist
@Experimental()
class SpeechGrammarList extends Interceptor with ListMixin<SpeechGrammar>, ImmutableListMixin<SpeechGrammar> implements JavaScriptIndexingBehavior, List<SpeechGrammar> native "SpeechGrammarList" {
  // To suppress missing implicit constructor warnings.
  factory SpeechGrammarList._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechGrammarList.SpeechGrammarList')
  @DocsEditable()
  factory SpeechGrammarList() {
    return SpeechGrammarList._create_1();
  }
  static SpeechGrammarList _create_1() => JS('SpeechGrammarList', 'new SpeechGrammarList()');

  @DomName('SpeechGrammarList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  SpeechGrammar operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("SpeechGrammar", "#[#]", this, index);
  }
  void operator[]=(int index, SpeechGrammar value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<SpeechGrammar> mixins.
  // SpeechGrammar is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  SpeechGrammar get first {
    if (this.length > 0) {
      return JS('SpeechGrammar', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  SpeechGrammar get last {
    int len = this.length;
    if (len > 0) {
      return JS('SpeechGrammar', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  SpeechGrammar get single {
    int len = this.length;
    if (len == 1) {
      return JS('SpeechGrammar', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  SpeechGrammar elementAt(int index) => this[index];
  // -- end List<SpeechGrammar> mixins.

  @DomName('SpeechGrammarList.addFromString')
  @DocsEditable()
  void addFromString(String string, [num weight]) native;

  @DomName('SpeechGrammarList.addFromUri')
  @DocsEditable()
  void addFromUri(String src, [num weight]) native;

  @DomName('SpeechGrammarList.item')
  @DocsEditable()
  SpeechGrammar item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('SpeechInputEvent')
// http://lists.w3.org/Archives/Public/public-xg-htmlspeech/2011Feb/att-0020/api-draft.html#speech_input_event_interface
@Experimental()
class SpeechInputEvent extends Event native "SpeechInputEvent" {
  // To suppress missing implicit constructor warnings.
  factory SpeechInputEvent._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('SpeechInputResult')
// http://lists.w3.org/Archives/Public/public-xg-htmlspeech/2011Feb/att-0020/api-draft.html#speech_input_result_interface
@Experimental()
class SpeechInputResult extends Interceptor native "SpeechInputResult" {
  // To suppress missing implicit constructor warnings.
  factory SpeechInputResult._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('SpeechRecognition')
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechreco-section
class SpeechRecognition extends EventTarget native "SpeechRecognition" {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognition._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `audioend` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.audioendEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> audioEndEvent = const EventStreamProvider<Event>('audioend');

  /**
   * Static factory designed to expose `audiostart` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.audiostartEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> audioStartEvent = const EventStreamProvider<Event>('audiostart');

  /**
   * Static factory designed to expose `end` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.endEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> endEvent = const EventStreamProvider<Event>('end');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<SpeechRecognitionError> errorEvent = const EventStreamProvider<SpeechRecognitionError>('error');

  /**
   * Static factory designed to expose `nomatch` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.nomatchEvent')
  @DocsEditable()
  static const EventStreamProvider<SpeechRecognitionEvent> noMatchEvent = const EventStreamProvider<SpeechRecognitionEvent>('nomatch');

  /**
   * Static factory designed to expose `result` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.resultEvent')
  @DocsEditable()
  static const EventStreamProvider<SpeechRecognitionEvent> resultEvent = const EventStreamProvider<SpeechRecognitionEvent>('result');

  /**
   * Static factory designed to expose `soundend` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.soundendEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> soundEndEvent = const EventStreamProvider<Event>('soundend');

  /**
   * Static factory designed to expose `soundstart` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.soundstartEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> soundStartEvent = const EventStreamProvider<Event>('soundstart');

  /**
   * Static factory designed to expose `speechend` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.speechendEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> speechEndEvent = const EventStreamProvider<Event>('speechend');

  /**
   * Static factory designed to expose `speechstart` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.speechstartEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> speechStartEvent = const EventStreamProvider<Event>('speechstart');

  /**
   * Static factory designed to expose `start` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.startEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> startEvent = const EventStreamProvider<Event>('start');

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.SpeechRecognition || window.webkitSpeechRecognition)');

  @DomName('SpeechRecognition.continuous')
  @DocsEditable()
  bool continuous;

  @DomName('SpeechRecognition.grammars')
  @DocsEditable()
  SpeechGrammarList grammars;

  @DomName('SpeechRecognition.interimResults')
  @DocsEditable()
  bool interimResults;

  @DomName('SpeechRecognition.lang')
  @DocsEditable()
  String lang;

  @DomName('SpeechRecognition.maxAlternatives')
  @DocsEditable()
  int maxAlternatives;

  @DomName('SpeechRecognition.abort')
  @DocsEditable()
  void abort() native;

  @DomName('SpeechRecognition.start')
  @DocsEditable()
  void start() native;

  @DomName('SpeechRecognition.stop')
  @DocsEditable()
  void stop() native;

  /// Stream of `audioend` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onaudioend')
  @DocsEditable()
  Stream<Event> get onAudioEnd => audioEndEvent.forTarget(this);

  /// Stream of `audiostart` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onaudiostart')
  @DocsEditable()
  Stream<Event> get onAudioStart => audioStartEvent.forTarget(this);

  /// Stream of `end` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onend')
  @DocsEditable()
  Stream<Event> get onEnd => endEvent.forTarget(this);

  /// Stream of `error` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onerror')
  @DocsEditable()
  Stream<SpeechRecognitionError> get onError => errorEvent.forTarget(this);

  /// Stream of `nomatch` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onnomatch')
  @DocsEditable()
  Stream<SpeechRecognitionEvent> get onNoMatch => noMatchEvent.forTarget(this);

  /// Stream of `result` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onresult')
  @DocsEditable()
  Stream<SpeechRecognitionEvent> get onResult => resultEvent.forTarget(this);

  /// Stream of `soundend` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onsoundend')
  @DocsEditable()
  Stream<Event> get onSoundEnd => soundEndEvent.forTarget(this);

  /// Stream of `soundstart` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onsoundstart')
  @DocsEditable()
  Stream<Event> get onSoundStart => soundStartEvent.forTarget(this);

  /// Stream of `speechend` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onspeechend')
  @DocsEditable()
  Stream<Event> get onSpeechEnd => speechEndEvent.forTarget(this);

  /// Stream of `speechstart` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onspeechstart')
  @DocsEditable()
  Stream<Event> get onSpeechStart => speechStartEvent.forTarget(this);

  /// Stream of `start` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onstart')
  @DocsEditable()
  Stream<Event> get onStart => startEvent.forTarget(this);

  factory SpeechRecognition() {
    return JS('SpeechRecognition',
        'new (window.SpeechRecognition || window.webkitSpeechRecognition)()');
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('SpeechRecognitionAlternative')
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechrecognitionalternative
class SpeechRecognitionAlternative extends Interceptor native "SpeechRecognitionAlternative" {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionAlternative._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechRecognitionAlternative.confidence')
  @DocsEditable()
  final double confidence;

  @DomName('SpeechRecognitionAlternative.transcript')
  @DocsEditable()
  final String transcript;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('SpeechRecognitionError')
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechreco-error
class SpeechRecognitionError extends Event native "SpeechRecognitionError" {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionError._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechRecognitionError.error')
  @DocsEditable()
  final String error;

  @DomName('SpeechRecognitionError.message')
  @DocsEditable()
  final String message;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('SpeechRecognitionEvent')
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechreco-event
class SpeechRecognitionEvent extends Event native "SpeechRecognitionEvent" {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechRecognitionEvent.emma')
  @DocsEditable()
  final Document emma;

  @DomName('SpeechRecognitionEvent.interpretation')
  @DocsEditable()
  final Document interpretation;

  @DomName('SpeechRecognitionEvent.resultIndex')
  @DocsEditable()
  final int resultIndex;

  @DomName('SpeechRecognitionEvent.results')
  @DocsEditable()
  @Returns('_SpeechRecognitionResultList')
  @Creates('_SpeechRecognitionResultList')
  final List<SpeechRecognitionResult> results;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('SpeechRecognitionResult')
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechrecognitionresult
class SpeechRecognitionResult extends Interceptor native "SpeechRecognitionResult" {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionResult._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechRecognitionResult.isFinal')
  @DocsEditable()
  final bool isFinal;

  @DomName('SpeechRecognitionResult.length')
  @DocsEditable()
  final int length;

  @DomName('SpeechRecognitionResult.item')
  @DocsEditable()
  SpeechRecognitionAlternative item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('SpeechSynthesis')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section
@Experimental()
class SpeechSynthesis extends EventTarget native "SpeechSynthesis" {
  // To suppress missing implicit constructor warnings.
  factory SpeechSynthesis._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechSynthesis.paused')
  @DocsEditable()
  final bool paused;

  @DomName('SpeechSynthesis.pending')
  @DocsEditable()
  final bool pending;

  @DomName('SpeechSynthesis.speaking')
  @DocsEditable()
  final bool speaking;

  @DomName('SpeechSynthesis.cancel')
  @DocsEditable()
  void cancel() native;

  @DomName('SpeechSynthesis.getVoices')
  @DocsEditable()
  List<SpeechSynthesisVoice> getVoices() native;

  @DomName('SpeechSynthesis.pause')
  @DocsEditable()
  void pause() native;

  @DomName('SpeechSynthesis.resume')
  @DocsEditable()
  void resume() native;

  @DomName('SpeechSynthesis.speak')
  @DocsEditable()
  void speak(SpeechSynthesisUtterance utterance) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('SpeechSynthesisEvent')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section
@Experimental()
class SpeechSynthesisEvent extends Event native "SpeechSynthesisEvent" {
  // To suppress missing implicit constructor warnings.
  factory SpeechSynthesisEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechSynthesisEvent.charIndex')
  @DocsEditable()
  final int charIndex;

  @DomName('SpeechSynthesisEvent.elapsedTime')
  @DocsEditable()
  final double elapsedTime;

  @DomName('SpeechSynthesisEvent.name')
  @DocsEditable()
  final String name;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('SpeechSynthesisUtterance')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section
@Experimental()
class SpeechSynthesisUtterance extends EventTarget native "SpeechSynthesisUtterance" {
  // To suppress missing implicit constructor warnings.
  factory SpeechSynthesisUtterance._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `boundary` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechSynthesisUtterance.boundaryEvent')
  @DocsEditable()
  static const EventStreamProvider<SpeechSynthesisEvent> boundaryEvent = const EventStreamProvider<SpeechSynthesisEvent>('boundary');

  /**
   * Static factory designed to expose `end` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechSynthesisUtterance.endEvent')
  @DocsEditable()
  static const EventStreamProvider<SpeechSynthesisEvent> endEvent = const EventStreamProvider<SpeechSynthesisEvent>('end');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechSynthesisUtterance.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `mark` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechSynthesisUtterance.markEvent')
  @DocsEditable()
  static const EventStreamProvider<SpeechSynthesisEvent> markEvent = const EventStreamProvider<SpeechSynthesisEvent>('mark');

  /**
   * Static factory designed to expose `pause` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechSynthesisUtterance.pauseEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> pauseEvent = const EventStreamProvider<Event>('pause');

  /**
   * Static factory designed to expose `resume` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechSynthesisUtterance.resumeEvent')
  @DocsEditable()
  static const EventStreamProvider<SpeechSynthesisEvent> resumeEvent = const EventStreamProvider<SpeechSynthesisEvent>('resume');

  /**
   * Static factory designed to expose `start` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechSynthesisUtterance.startEvent')
  @DocsEditable()
  static const EventStreamProvider<SpeechSynthesisEvent> startEvent = const EventStreamProvider<SpeechSynthesisEvent>('start');

  @DomName('SpeechSynthesisUtterance.SpeechSynthesisUtterance')
  @DocsEditable()
  factory SpeechSynthesisUtterance([String text]) {
    if (text != null) {
      return SpeechSynthesisUtterance._create_1(text);
    }
    return SpeechSynthesisUtterance._create_2();
  }
  static SpeechSynthesisUtterance _create_1(text) => JS('SpeechSynthesisUtterance', 'new SpeechSynthesisUtterance(#)', text);
  static SpeechSynthesisUtterance _create_2() => JS('SpeechSynthesisUtterance', 'new SpeechSynthesisUtterance()');

  @DomName('SpeechSynthesisUtterance.lang')
  @DocsEditable()
  String lang;

  @DomName('SpeechSynthesisUtterance.pitch')
  @DocsEditable()
  num pitch;

  @DomName('SpeechSynthesisUtterance.rate')
  @DocsEditable()
  num rate;

  @DomName('SpeechSynthesisUtterance.text')
  @DocsEditable()
  String text;

  @DomName('SpeechSynthesisUtterance.voice')
  @DocsEditable()
  SpeechSynthesisVoice voice;

  @DomName('SpeechSynthesisUtterance.volume')
  @DocsEditable()
  num volume;

  /// Stream of `boundary` events handled by this [SpeechSynthesisUtterance].
  @DomName('SpeechSynthesisUtterance.onboundary')
  @DocsEditable()
  Stream<SpeechSynthesisEvent> get onBoundary => boundaryEvent.forTarget(this);

  /// Stream of `end` events handled by this [SpeechSynthesisUtterance].
  @DomName('SpeechSynthesisUtterance.onend')
  @DocsEditable()
  Stream<SpeechSynthesisEvent> get onEnd => endEvent.forTarget(this);

  /// Stream of `error` events handled by this [SpeechSynthesisUtterance].
  @DomName('SpeechSynthesisUtterance.onerror')
  @DocsEditable()
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `mark` events handled by this [SpeechSynthesisUtterance].
  @DomName('SpeechSynthesisUtterance.onmark')
  @DocsEditable()
  Stream<SpeechSynthesisEvent> get onMark => markEvent.forTarget(this);

  /// Stream of `pause` events handled by this [SpeechSynthesisUtterance].
  @DomName('SpeechSynthesisUtterance.onpause')
  @DocsEditable()
  Stream<Event> get onPause => pauseEvent.forTarget(this);

  /// Stream of `resume` events handled by this [SpeechSynthesisUtterance].
  @DomName('SpeechSynthesisUtterance.onresume')
  @DocsEditable()
  Stream<SpeechSynthesisEvent> get onResume => resumeEvent.forTarget(this);

  /// Stream of `start` events handled by this [SpeechSynthesisUtterance].
  @DomName('SpeechSynthesisUtterance.onstart')
  @DocsEditable()
  Stream<SpeechSynthesisEvent> get onStart => startEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('SpeechSynthesisVoice')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section
@Experimental()
class SpeechSynthesisVoice extends Interceptor native "SpeechSynthesisVoice" {
  // To suppress missing implicit constructor warnings.
  factory SpeechSynthesisVoice._() { throw new UnsupportedError("Not supported"); }

  @JSName('default')
  @DomName('SpeechSynthesisVoice.default')
  @DocsEditable()
  final bool defaultValue;

  @DomName('SpeechSynthesisVoice.lang')
  @DocsEditable()
  final String lang;

  @DomName('SpeechSynthesisVoice.localService')
  @DocsEditable()
  final bool localService;

  @DomName('SpeechSynthesisVoice.name')
  @DocsEditable()
  final String name;

  @JSName('voiceURI')
  @DomName('SpeechSynthesisVoice.voiceURI')
  @DocsEditable()
  final String voiceUri;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * The type used by the
 * [Window.localStorage] and [Window.sessionStorage] properties.
 * Storage is implemented as a Map&lt;String, String>.
 *
 * To store and get values, use Dart's built-in map syntax:
 *
 *     window.localStorage['key1'] = 'val1';
 *     window.localStorage['key2'] = 'val2';
 *     window.localStorage['key3'] = 'val3';
 *     assert(window.localStorage['key3'] == 'val3');
 *
 * You can use [Map](http://api.dartlang.org/dart_core/Map.html) APIs
 * such as containsValue(), clear(), and length:
 *
 *     assert(window.localStorage.containsValue('does not exist') == false);
 *     window.localStorage.clear();
 *     assert(window.localStorage.length == 0);
 *
 * For more examples of using this API, see
 * [localstorage_test.dart](http://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/tests/html/localstorage_test.dart).
 * For details on using the Map API, see the
 * [Maps](http://www.dartlang.org/docs/library-tour/#maps-aka-dictionaries-or-hashes)
 * section of the library tour.
 */
@DomName('Storage')
@Unstable()
class Storage extends Interceptor
    implements Map<String, String>  native "Storage" {

  void addAll(Map<String, String> other) {
    other.forEach((k, v) { this[k] = v; });
  }

  // TODO(nweiz): update this when maps support lazy iteration
  bool containsValue(String value) => values.any((e) => e == value);

  bool containsKey(String key) => _getItem(key) != null;

  String operator [](String key) => _getItem(key);

  void operator []=(String key, String value) { _setItem(key, value); }

  String putIfAbsent(String key, String ifAbsent()) {
    if (!containsKey(key)) this[key] = ifAbsent();
    return this[key];
  }

  String remove(String key) {
    final value = this[key];
    _removeItem(key);
    return value;
  }

  void clear() => _clear();

  void forEach(void f(String key, String value)) {
    for (var i = 0; true; i++) {
      final key = _key(i);
      if (key == null) return;

      f(key, this[key]);
    }
  }

  Iterable<String> get keys {
    final keys = [];
    forEach((k, v) => keys.add(k));
    return keys;
  }

  Iterable<String> get values {
    final values = [];
    forEach((k, v) => values.add(v));
    return values;
  }

  int get length => _length;

  bool get isEmpty => _key(0) == null;

  bool get isNotEmpty => !isEmpty;
  // To suppress missing implicit constructor warnings.
  factory Storage._() { throw new UnsupportedError("Not supported"); }

  @JSName('length')
  @DomName('Storage.length')
  @DocsEditable()
  final int _length;

  @DomName('Storage.__delete__')
  @DocsEditable()
  bool __delete__(index_OR_name) native;

  @DomName('Storage.__getter__')
  @DocsEditable()
  String __getter__(index_OR_name) native;

  @DomName('Storage.__setter__')
  @DocsEditable()
  void __setter__(index_OR_name, String value) native;

  @JSName('clear')
  @DomName('Storage.clear')
  @DocsEditable()
  void _clear() native;

  @JSName('getItem')
  @DomName('Storage.getItem')
  @DocsEditable()
  String _getItem(String key) native;

  @JSName('key')
  @DomName('Storage.key')
  @DocsEditable()
  String _key(int index) native;

  @JSName('removeItem')
  @DomName('Storage.removeItem')
  @DocsEditable()
  void _removeItem(String key) native;

  @JSName('setItem')
  @DomName('Storage.setItem')
  @DocsEditable()
  void _setItem(String key, String data) native;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('StorageErrorCallback')
// http://www.w3.org/TR/quota-api/#storageerrorcallback-callback
@Experimental()
typedef void StorageErrorCallback(DomError error);
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('StorageEvent')
@Unstable()
class StorageEvent extends Event native "StorageEvent" {
  factory StorageEvent(String type,
    {bool canBubble: false, bool cancelable: false, String key, String oldValue,
    String newValue, String url, Storage storageArea}) {

    var e = document._createEvent("StorageEvent");
    e._initStorageEvent(type, canBubble, cancelable, key, oldValue,
        newValue, url, storageArea);
    return e;
  }
  // To suppress missing implicit constructor warnings.
  factory StorageEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('StorageEvent.key')
  @DocsEditable()
  final String key;

  @DomName('StorageEvent.newValue')
  @DocsEditable()
  final String newValue;

  @DomName('StorageEvent.oldValue')
  @DocsEditable()
  final String oldValue;

  @DomName('StorageEvent.storageArea')
  @DocsEditable()
  final Storage storageArea;

  @DomName('StorageEvent.url')
  @DocsEditable()
  final String url;

  @JSName('initStorageEvent')
  @DomName('StorageEvent.initStorageEvent')
  @DocsEditable()
  void _initStorageEvent(String typeArg, bool canBubbleArg, bool cancelableArg, String keyArg, String oldValueArg, String newValueArg, String urlArg, Storage storageAreaArg) native;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('StorageInfo')
// http://www.w3.org/TR/file-system-api/
@Experimental()
class StorageInfo extends Interceptor native "StorageInfo" {
  // To suppress missing implicit constructor warnings.
  factory StorageInfo._() { throw new UnsupportedError("Not supported"); }

  @DomName('StorageInfo.quota')
  @DocsEditable()
  @Experimental() // untriaged
  final int quota;

  @DomName('StorageInfo.usage')
  @DocsEditable()
  @Experimental() // untriaged
  final int usage;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('StorageQuota')
// http://www.w3.org/TR/quota-api/#idl-def-StorageQuota
@Experimental()
class StorageQuota extends Interceptor native "StorageQuota" {
  // To suppress missing implicit constructor warnings.
  factory StorageQuota._() { throw new UnsupportedError("Not supported"); }

  @DomName('StorageQuota.supportedTypes')
  @DocsEditable()
  @Experimental() // untriaged
  final List<String> supportedTypes;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('StorageQuotaCallback')
// http://www.w3.org/TR/quota-api/#idl-def-StorageQuotaCallback
@Experimental()
typedef void StorageQuotaCallback(int grantedQuotaInBytes);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('StorageUsageCallback')
// http://www.w3.org/TR/quota-api/#idl-def-StorageUsageCallback
@Experimental()
typedef void StorageUsageCallback(int currentUsageInBytes, int currentQuotaInBytes);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('StringCallback')
// http://www.w3.org/TR/2011/WD-html5-20110113/dnd.html#the-datatransferitem-interface
@Experimental()
typedef void _StringCallback(String data);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLStyleElement')
class StyleElement extends HtmlElement native "HTMLStyleElement" {
  // To suppress missing implicit constructor warnings.
  factory StyleElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLStyleElement.HTMLStyleElement')
  @DocsEditable()
  factory StyleElement() => document.createElement("style");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  StyleElement.created() : super.created();

  @DomName('HTMLStyleElement.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('HTMLStyleElement.media')
  @DocsEditable()
  String media;

  @DomName('HTMLStyleElement.scoped')
  @DocsEditable()
  bool scoped;

  @DomName('HTMLStyleElement.sheet')
  @DocsEditable()
  final StyleSheet sheet;

  @DomName('HTMLStyleElement.type')
  @DocsEditable()
  String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('StyleMedia')
// http://developer.apple.com/library/safari/#documentation/SafariDOMAdditions/Reference/StyleMedia/StyleMedia/StyleMedia.html
@Experimental() // nonstandard
class StyleMedia extends Interceptor native "StyleMedia" {
  // To suppress missing implicit constructor warnings.
  factory StyleMedia._() { throw new UnsupportedError("Not supported"); }

  @DomName('StyleMedia.type')
  @DocsEditable()
  final String type;

  @DomName('StyleMedia.matchMedium')
  @DocsEditable()
  bool matchMedium(String mediaquery) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('StyleSheet')
class StyleSheet extends Interceptor native "StyleSheet" {
  // To suppress missing implicit constructor warnings.
  factory StyleSheet._() { throw new UnsupportedError("Not supported"); }

  @DomName('StyleSheet.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('StyleSheet.href')
  @DocsEditable()
  final String href;

  @DomName('StyleSheet.media')
  @DocsEditable()
  final MediaList media;

  @DomName('StyleSheet.ownerNode')
  @DocsEditable()
  final Node ownerNode;

  @DomName('StyleSheet.parentStyleSheet')
  @DocsEditable()
  final StyleSheet parentStyleSheet;

  @DomName('StyleSheet.title')
  @DocsEditable()
  final String title;

  @DomName('StyleSheet.type')
  @DocsEditable()
  final String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLTableCaptionElement')
class TableCaptionElement extends HtmlElement native "HTMLTableCaptionElement" {
  // To suppress missing implicit constructor warnings.
  factory TableCaptionElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLTableCaptionElement.HTMLTableCaptionElement')
  @DocsEditable()
  factory TableCaptionElement() => document.createElement("caption");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableCaptionElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLTableCellElement')
class TableCellElement extends HtmlElement native "HTMLTableCellElement,HTMLTableDataCellElement,HTMLTableHeaderCellElement" {
  // To suppress missing implicit constructor warnings.
  factory TableCellElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLTableCellElement.HTMLTableCellElement')
  @DocsEditable()
  factory TableCellElement() => document.createElement("td");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableCellElement.created() : super.created();

  @DomName('HTMLTableCellElement.cellIndex')
  @DocsEditable()
  final int cellIndex;

  @DomName('HTMLTableCellElement.colSpan')
  @DocsEditable()
  int colSpan;

  @DomName('HTMLTableCellElement.headers')
  @DocsEditable()
  String headers;

  @DomName('HTMLTableCellElement.rowSpan')
  @DocsEditable()
  int rowSpan;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLTableColElement')
class TableColElement extends HtmlElement native "HTMLTableColElement" {
  // To suppress missing implicit constructor warnings.
  factory TableColElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLTableColElement.HTMLTableColElement')
  @DocsEditable()
  factory TableColElement() => document.createElement("col");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableColElement.created() : super.created();

  @DomName('HTMLTableColElement.span')
  @DocsEditable()
  int span;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLTableElement')
class TableElement extends HtmlElement native "HTMLTableElement" {

  @DomName('HTMLTableElement.tBodies')
  List<TableSectionElement> get tBodies =>
  new _WrappedList<TableSectionElement>(_tBodies);

  @DomName('HTMLTableElement.rows')
  List<TableRowElement> get rows =>
      new _WrappedList<TableRowElement>(_rows);

  TableRowElement addRow() {
    return insertRow(-1);
  }

  TableCaptionElement createCaption() => _createCaption();
  TableSectionElement createTBody() => _createTBody();
  TableSectionElement createTFoot() => _createTFoot();
  TableSectionElement createTHead() => _createTHead();
  TableRowElement insertRow(int index) => _insertRow(index);

  TableSectionElement _createTBody() {
    if (JS('bool', '!!#.createTBody', this)) {
      return this._nativeCreateTBody();
    }
    var tbody = new Element.tag('tbody');
    this.children.add(tbody);
    return tbody;
  }

  @JSName('createTBody')
  TableSectionElement _nativeCreateTBody() native;

  DocumentFragment createFragment(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    if (Range.supportsCreateContextualFragment) {
      return super.createFragment(
          html, validator: validator, treeSanitizer: treeSanitizer);
    }
    // IE9 workaround which does not support innerHTML on Table elements.
    var contextualHtml = '<table>$html</table>';
    var table = new Element.html(contextualHtml, validator: validator,
        treeSanitizer: treeSanitizer);
    var fragment = new DocumentFragment();
    fragment.nodes.addAll(table.nodes);

    return fragment;
  }

  // To suppress missing implicit constructor warnings.
  factory TableElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLTableElement.HTMLTableElement')
  @DocsEditable()
  factory TableElement() => document.createElement("table");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableElement.created() : super.created();

  @DomName('HTMLTableElement.caption')
  @DocsEditable()
  TableCaptionElement caption;

  @JSName('rows')
  @DomName('HTMLTableElement.rows')
  @DocsEditable()
  @Returns('HtmlCollection')
  @Creates('HtmlCollection')
  final List<Node> _rows;

  @JSName('tBodies')
  @DomName('HTMLTableElement.tBodies')
  @DocsEditable()
  @Returns('HtmlCollection')
  @Creates('HtmlCollection')
  final List<Node> _tBodies;

  @DomName('HTMLTableElement.tFoot')
  @DocsEditable()
  TableSectionElement tFoot;

  @DomName('HTMLTableElement.tHead')
  @DocsEditable()
  TableSectionElement tHead;

  @JSName('createCaption')
  @DomName('HTMLTableElement.createCaption')
  @DocsEditable()
  HtmlElement _createCaption() native;

  @JSName('createTFoot')
  @DomName('HTMLTableElement.createTFoot')
  @DocsEditable()
  HtmlElement _createTFoot() native;

  @JSName('createTHead')
  @DomName('HTMLTableElement.createTHead')
  @DocsEditable()
  HtmlElement _createTHead() native;

  @DomName('HTMLTableElement.deleteCaption')
  @DocsEditable()
  void deleteCaption() native;

  @DomName('HTMLTableElement.deleteRow')
  @DocsEditable()
  void deleteRow(int index) native;

  @DomName('HTMLTableElement.deleteTFoot')
  @DocsEditable()
  void deleteTFoot() native;

  @DomName('HTMLTableElement.deleteTHead')
  @DocsEditable()
  void deleteTHead() native;

  @JSName('insertRow')
  @DomName('HTMLTableElement.insertRow')
  @DocsEditable()
  HtmlElement _insertRow(int index) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLTableRowElement')
class TableRowElement extends HtmlElement native "HTMLTableRowElement" {

  @DomName('HTMLTableRowElement.cells')
  List<TableCellElement> get cells =>
      new _WrappedList<TableCellElement>(_cells);

  TableCellElement addCell() {
    return insertCell(-1);
  }

  TableCellElement insertCell(int index) => _insertCell(index);

  DocumentFragment createFragment(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    if (Range.supportsCreateContextualFragment) {
      return super.createFragment(
          html, validator: validator, treeSanitizer: treeSanitizer);
    }
    // IE9 workaround which does not support innerHTML on Table elements.
    var fragment = new DocumentFragment();
    var section = new TableElement().createFragment(
        html, validator: validator, treeSanitizer: treeSanitizer).nodes.single;
    var row = section.nodes.single;
    fragment.nodes.addAll(row.nodes);
    return fragment;
  }

  // To suppress missing implicit constructor warnings.
  factory TableRowElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLTableRowElement.HTMLTableRowElement')
  @DocsEditable()
  factory TableRowElement() => document.createElement("tr");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableRowElement.created() : super.created();

  @JSName('cells')
  @DomName('HTMLTableRowElement.cells')
  @DocsEditable()
  @Returns('HtmlCollection')
  @Creates('HtmlCollection')
  final List<Node> _cells;

  @DomName('HTMLTableRowElement.rowIndex')
  @DocsEditable()
  final int rowIndex;

  @DomName('HTMLTableRowElement.sectionRowIndex')
  @DocsEditable()
  final int sectionRowIndex;

  @DomName('HTMLTableRowElement.deleteCell')
  @DocsEditable()
  void deleteCell(int index) native;

  @JSName('insertCell')
  @DomName('HTMLTableRowElement.insertCell')
  @DocsEditable()
  HtmlElement _insertCell(int index) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLTableSectionElement')
class TableSectionElement extends HtmlElement native "HTMLTableSectionElement" {

  @DomName('HTMLTableSectionElement.rows')
  List<TableRowElement> get rows =>
    new _WrappedList<TableRowElement>(_rows);

  TableRowElement addRow() {
    return insertRow(-1);
  }

  TableRowElement insertRow(int index) => _insertRow(index);

  DocumentFragment createFragment(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    if (Range.supportsCreateContextualFragment) {
      return super.createFragment(
          html, validator: validator, treeSanitizer: treeSanitizer);
    }
    // IE9 workaround which does not support innerHTML on Table elements.
    var fragment = new DocumentFragment();
    var section = new TableElement().createFragment(
        html, validator: validator, treeSanitizer: treeSanitizer).nodes.single;
    fragment.nodes.addAll(section.nodes);
    return fragment;
  }

  // To suppress missing implicit constructor warnings.
  factory TableSectionElement._() { throw new UnsupportedError("Not supported"); }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableSectionElement.created() : super.created();

  @JSName('rows')
  @DomName('HTMLTableSectionElement.rows')
  @DocsEditable()
  @Returns('HtmlCollection')
  @Creates('HtmlCollection')
  final List<Node> _rows;

  @DomName('HTMLTableSectionElement.deleteRow')
  @DocsEditable()
  void deleteRow(int index) native;

  @JSName('insertRow')
  @DomName('HTMLTableSectionElement.insertRow')
  @DocsEditable()
  HtmlElement _insertRow(int index) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@Experimental()
@DomName('HTMLTemplateElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#template-element
class TemplateElement extends HtmlElement native "HTMLTemplateElement" {
  // To suppress missing implicit constructor warnings.
  factory TemplateElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLTemplateElement.HTMLTemplateElement')
  @DocsEditable()
  factory TemplateElement() => document.createElement("template");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TemplateElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('template');

  @DomName('HTMLTemplateElement.content')
  @DocsEditable()
  final DocumentFragment content;


  /**
   * An override to place the contents into content rather than as child nodes.
   *
   * See also:
   *
   * * <https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#innerhtml-on-templates>
   */
  void setInnerHtml(String html,
    {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    text = null;
    var fragment = createFragment(
        html, validator: validator, treeSanitizer: treeSanitizer);

    content.append(fragment);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('Text')
class Text extends CharacterData native "Text" {
  factory Text(String data) => document._createTextNode(data);
  // To suppress missing implicit constructor warnings.
  factory Text._() { throw new UnsupportedError("Not supported"); }

  @DomName('Text.wholeText')
  @DocsEditable()
  final String wholeText;

  @DomName('Text.getDestinationInsertionPoints')
  @DocsEditable()
  @Experimental() // untriaged
  @Returns('NodeList')
  @Creates('NodeList')
  List<Node> getDestinationInsertionPoints() native;

  @DomName('Text.splitText')
  @DocsEditable()
  Text splitText(int offset) native;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLTextAreaElement')
class TextAreaElement extends HtmlElement native "HTMLTextAreaElement" {
  // To suppress missing implicit constructor warnings.
  factory TextAreaElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLTextAreaElement.HTMLTextAreaElement')
  @DocsEditable()
  factory TextAreaElement() => document.createElement("textarea");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TextAreaElement.created() : super.created();

  @DomName('HTMLTextAreaElement.autofocus')
  @DocsEditable()
  bool autofocus;

  @DomName('HTMLTextAreaElement.cols')
  @DocsEditable()
  int cols;

  @DomName('HTMLTextAreaElement.defaultValue')
  @DocsEditable()
  String defaultValue;

  @DomName('HTMLTextAreaElement.dirName')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#dom-textarea-dirname
  @Experimental()
  String dirName;

  @DomName('HTMLTextAreaElement.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('HTMLTextAreaElement.form')
  @DocsEditable()
  final FormElement form;

  @DomName('HTMLTextAreaElement.inputMode')
  @DocsEditable()
  @Experimental() // untriaged
  String inputMode;

  @DomName('HTMLTextAreaElement.labels')
  @DocsEditable()
  @Unstable()
  @Returns('NodeList')
  @Creates('NodeList')
  final List<Node> labels;

  @DomName('HTMLTextAreaElement.maxLength')
  @DocsEditable()
  int maxLength;

  @DomName('HTMLTextAreaElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLTextAreaElement.placeholder')
  @DocsEditable()
  String placeholder;

  @DomName('HTMLTextAreaElement.readOnly')
  @DocsEditable()
  bool readOnly;

  @DomName('HTMLTextAreaElement.required')
  @DocsEditable()
  bool required;

  @DomName('HTMLTextAreaElement.rows')
  @DocsEditable()
  int rows;

  @DomName('HTMLTextAreaElement.selectionDirection')
  @DocsEditable()
  String selectionDirection;

  @DomName('HTMLTextAreaElement.selectionEnd')
  @DocsEditable()
  int selectionEnd;

  @DomName('HTMLTextAreaElement.selectionStart')
  @DocsEditable()
  int selectionStart;

  @DomName('HTMLTextAreaElement.textLength')
  @DocsEditable()
  final int textLength;

  @DomName('HTMLTextAreaElement.type')
  @DocsEditable()
  final String type;

  @DomName('HTMLTextAreaElement.validationMessage')
  @DocsEditable()
  final String validationMessage;

  @DomName('HTMLTextAreaElement.validity')
  @DocsEditable()
  final ValidityState validity;

  @DomName('HTMLTextAreaElement.value')
  @DocsEditable()
  String value;

  @DomName('HTMLTextAreaElement.willValidate')
  @DocsEditable()
  final bool willValidate;

  @DomName('HTMLTextAreaElement.wrap')
  @DocsEditable()
  String wrap;

  @DomName('HTMLTextAreaElement.checkValidity')
  @DocsEditable()
  bool checkValidity() native;

  @DomName('HTMLTextAreaElement.select')
  @DocsEditable()
  void select() native;

  @DomName('HTMLTextAreaElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) native;

  @DomName('HTMLTextAreaElement.setRangeText')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#dom-textarea/input-setrangetext
  @Experimental()
  void setRangeText(String replacement, {int start, int end, String selectionMode}) native;

  @DomName('HTMLTextAreaElement.setSelectionRange')
  @DocsEditable()
  void setSelectionRange(int start, int end, [String direction]) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('TextEvent')
@Unstable()
class TextEvent extends UIEvent native "TextEvent" {
  factory TextEvent(String type,
    {bool canBubble: false, bool cancelable: false, Window view, String data}) {
    if (view == null) {
      view = window;
    }
    var e = document._createEvent("TextEvent");
    e._initTextEvent(type, canBubble, cancelable, view, data);
    return e;
  }
  // To suppress missing implicit constructor warnings.
  factory TextEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('TextEvent.data')
  @DocsEditable()
  final String data;

  @JSName('initTextEvent')
  @DomName('TextEvent.initTextEvent')
  @DocsEditable()
  void _initTextEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Window viewArg, String dataArg) native;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('TextMetrics')
class TextMetrics extends Interceptor native "TextMetrics" {
  // To suppress missing implicit constructor warnings.
  factory TextMetrics._() { throw new UnsupportedError("Not supported"); }

  @DomName('TextMetrics.width')
  @DocsEditable()
  final double width;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('TextTrack')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#texttrack
@Experimental()
class TextTrack extends EventTarget native "TextTrack" {
  // To suppress missing implicit constructor warnings.
  factory TextTrack._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `cuechange` events to event
   * handlers that are not necessarily instances of [TextTrack].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('TextTrack.cuechangeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> cueChangeEvent = const EventStreamProvider<Event>('cuechange');

  @DomName('TextTrack.activeCues')
  @DocsEditable()
  final TextTrackCueList activeCues;

  @DomName('TextTrack.cues')
  @DocsEditable()
  final TextTrackCueList cues;

  @DomName('TextTrack.id')
  @DocsEditable()
  @Experimental() // untriaged
  final String id;

  @DomName('TextTrack.kind')
  @DocsEditable()
  final String kind;

  @DomName('TextTrack.label')
  @DocsEditable()
  final String label;

  @DomName('TextTrack.language')
  @DocsEditable()
  final String language;

  @DomName('TextTrack.mode')
  @DocsEditable()
  String mode;

  @DomName('TextTrack.regions')
  @DocsEditable()
  @Experimental() // untriaged
  final VttRegionList regions;

  @DomName('TextTrack.addCue')
  @DocsEditable()
  void addCue(TextTrackCue cue) native;

  @DomName('TextTrack.addRegion')
  @DocsEditable()
  @Experimental() // untriaged
  void addRegion(VttRegion region) native;

  @DomName('TextTrack.removeCue')
  @DocsEditable()
  void removeCue(TextTrackCue cue) native;

  @DomName('TextTrack.removeRegion')
  @DocsEditable()
  @Experimental() // untriaged
  void removeRegion(VttRegion region) native;

  /// Stream of `cuechange` events handled by this [TextTrack].
  @DomName('TextTrack.oncuechange')
  @DocsEditable()
  Stream<Event> get onCueChange => cueChangeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('TextTrackCue')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#texttrackcue
@Experimental()
class TextTrackCue extends EventTarget native "TextTrackCue" {
  // To suppress missing implicit constructor warnings.
  factory TextTrackCue._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `enter` events to event
   * handlers that are not necessarily instances of [TextTrackCue].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('TextTrackCue.enterEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> enterEvent = const EventStreamProvider<Event>('enter');

  /**
   * Static factory designed to expose `exit` events to event
   * handlers that are not necessarily instances of [TextTrackCue].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('TextTrackCue.exitEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> exitEvent = const EventStreamProvider<Event>('exit');

  @DomName('TextTrackCue.endTime')
  @DocsEditable()
  num endTime;

  @DomName('TextTrackCue.id')
  @DocsEditable()
  String id;

  @DomName('TextTrackCue.pauseOnExit')
  @DocsEditable()
  bool pauseOnExit;

  @DomName('TextTrackCue.startTime')
  @DocsEditable()
  num startTime;

  @DomName('TextTrackCue.track')
  @DocsEditable()
  final TextTrack track;

  /// Stream of `enter` events handled by this [TextTrackCue].
  @DomName('TextTrackCue.onenter')
  @DocsEditable()
  Stream<Event> get onEnter => enterEvent.forTarget(this);

  /// Stream of `exit` events handled by this [TextTrackCue].
  @DomName('TextTrackCue.onexit')
  @DocsEditable()
  Stream<Event> get onExit => exitEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('TextTrackCueList')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#texttrackcuelist
@Experimental()
class TextTrackCueList extends Interceptor with ListMixin<TextTrackCue>, ImmutableListMixin<TextTrackCue> implements List<TextTrackCue>, JavaScriptIndexingBehavior native "TextTrackCueList" {
  // To suppress missing implicit constructor warnings.
  factory TextTrackCueList._() { throw new UnsupportedError("Not supported"); }

  @DomName('TextTrackCueList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  TextTrackCue operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("TextTrackCue", "#[#]", this, index);
  }
  void operator[]=(int index, TextTrackCue value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<TextTrackCue> mixins.
  // TextTrackCue is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  TextTrackCue get first {
    if (this.length > 0) {
      return JS('TextTrackCue', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  TextTrackCue get last {
    int len = this.length;
    if (len > 0) {
      return JS('TextTrackCue', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  TextTrackCue get single {
    int len = this.length;
    if (len == 1) {
      return JS('TextTrackCue', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  TextTrackCue elementAt(int index) => this[index];
  // -- end List<TextTrackCue> mixins.

  @DomName('TextTrackCueList.getCueById')
  @DocsEditable()
  TextTrackCue getCueById(String id) native;

  @DomName('TextTrackCueList.item')
  @DocsEditable()
  TextTrackCue item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('TextTrackList')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#texttracklist
@Experimental()
class TextTrackList extends EventTarget with ListMixin<TextTrack>, ImmutableListMixin<TextTrack> implements JavaScriptIndexingBehavior, List<TextTrack> native "TextTrackList" {
  // To suppress missing implicit constructor warnings.
  factory TextTrackList._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `addtrack` events to event
   * handlers that are not necessarily instances of [TextTrackList].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('TextTrackList.addtrackEvent')
  @DocsEditable()
  static const EventStreamProvider<TrackEvent> addTrackEvent = const EventStreamProvider<TrackEvent>('addtrack');

  @DomName('TextTrackList.changeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> changeEvent = const EventStreamProvider<Event>('change');

  @DomName('TextTrackList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  TextTrack operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("TextTrack", "#[#]", this, index);
  }
  void operator[]=(int index, TextTrack value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<TextTrack> mixins.
  // TextTrack is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  TextTrack get first {
    if (this.length > 0) {
      return JS('TextTrack', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  TextTrack get last {
    int len = this.length;
    if (len > 0) {
      return JS('TextTrack', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  TextTrack get single {
    int len = this.length;
    if (len == 1) {
      return JS('TextTrack', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  TextTrack elementAt(int index) => this[index];
  // -- end List<TextTrack> mixins.

  @DomName('TextTrackList.getTrackById')
  @DocsEditable()
  @Experimental() // untriaged
  TextTrack getTrackById(String id) native;

  @DomName('TextTrackList.item')
  @DocsEditable()
  TextTrack item(int index) native;

  /// Stream of `addtrack` events handled by this [TextTrackList].
  @DomName('TextTrackList.onaddtrack')
  @DocsEditable()
  Stream<TrackEvent> get onAddTrack => addTrackEvent.forTarget(this);

  @DomName('TextTrackList.onchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onChange => changeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('TimeRanges')
@Unstable()
class TimeRanges extends Interceptor native "TimeRanges" {
  // To suppress missing implicit constructor warnings.
  factory TimeRanges._() { throw new UnsupportedError("Not supported"); }

  @DomName('TimeRanges.length')
  @DocsEditable()
  final int length;

  @DomName('TimeRanges.end')
  @DocsEditable()
  double end(int index) native;

  @DomName('TimeRanges.start')
  @DocsEditable()
  double start(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('TimedItem')
@Experimental() // untriaged
class TimedItem extends Interceptor native "TimedItem" {
  // To suppress missing implicit constructor warnings.
  factory TimedItem._() { throw new UnsupportedError("Not supported"); }

  @DomName('TimedItem.activeDuration')
  @DocsEditable()
  @Experimental() // untriaged
  final double activeDuration;

  @DomName('TimedItem.currentIteration')
  @DocsEditable()
  @Experimental() // untriaged
  final int currentIteration;

  @DomName('TimedItem.duration')
  @DocsEditable()
  @Experimental() // untriaged
  final double duration;

  @DomName('TimedItem.endTime')
  @DocsEditable()
  @Experimental() // untriaged
  final double endTime;

  @DomName('TimedItem.localTime')
  @DocsEditable()
  @Experimental() // untriaged
  final double localTime;

  @DomName('TimedItem.player')
  @DocsEditable()
  @Experimental() // untriaged
  final Player player;

  @DomName('TimedItem.startTime')
  @DocsEditable()
  @Experimental() // untriaged
  final double startTime;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('Timeline')
@Experimental() // untriaged
class Timeline extends Interceptor native "Timeline" {
  // To suppress missing implicit constructor warnings.
  factory Timeline._() { throw new UnsupportedError("Not supported"); }

  @DomName('Timeline.play')
  @DocsEditable()
  @Experimental() // untriaged
  Player play(TimedItem source) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('TimeoutHandler')
typedef void TimeoutHandler();
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('Timing')
@Experimental() // untriaged
class Timing extends Interceptor native "Timing" {
  // To suppress missing implicit constructor warnings.
  factory Timing._() { throw new UnsupportedError("Not supported"); }

  @DomName('Timing.delay')
  @DocsEditable()
  @Experimental() // untriaged
  num delay;

  @DomName('Timing.direction')
  @DocsEditable()
  @Experimental() // untriaged
  String direction;

  @DomName('Timing.easing')
  @DocsEditable()
  @Experimental() // untriaged
  String easing;

  @DomName('Timing.endDelay')
  @DocsEditable()
  @Experimental() // untriaged
  num endDelay;

  @DomName('Timing.fill')
  @DocsEditable()
  @Experimental() // untriaged
  String fill;

  @DomName('Timing.iterationStart')
  @DocsEditable()
  @Experimental() // untriaged
  num iterationStart;

  @DomName('Timing.iterations')
  @DocsEditable()
  @Experimental() // untriaged
  num iterations;

  @DomName('Timing.playbackRate')
  @DocsEditable()
  @Experimental() // untriaged
  num playbackRate;

  @DomName('Timing.__setter__')
  @DocsEditable()
  @Experimental() // untriaged
  void __setter__(String name, num duration) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLTitleElement')
class TitleElement extends HtmlElement native "HTMLTitleElement" {
  // To suppress missing implicit constructor warnings.
  factory TitleElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLTitleElement.HTMLTitleElement')
  @DocsEditable()
  factory TitleElement() => document.createElement("title");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TitleElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('Touch')
// http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
@Experimental()
class Touch extends Interceptor native "Touch" {
  // To suppress missing implicit constructor warnings.
  factory Touch._() { throw new UnsupportedError("Not supported"); }

  @JSName('clientX')
  @DomName('Touch.clientX')
  @DocsEditable()
  final int _clientX;

  @JSName('clientY')
  @DomName('Touch.clientY')
  @DocsEditable()
  final int _clientY;

  @DomName('Touch.identifier')
  @DocsEditable()
  final int identifier;

  @JSName('pageX')
  @DomName('Touch.pageX')
  @DocsEditable()
  final int _pageX;

  @JSName('pageY')
  @DomName('Touch.pageY')
  @DocsEditable()
  final int _pageY;

  @JSName('screenX')
  @DomName('Touch.screenX')
  @DocsEditable()
  final int _screenX;

  @JSName('screenY')
  @DomName('Touch.screenY')
  @DocsEditable()
  final int _screenY;

  @DomName('Touch.target')
  @DocsEditable()
  EventTarget get target => _convertNativeToDart_EventTarget(this._get_target);
  @JSName('target')
  @DomName('Touch.target')
  @DocsEditable()
  @Creates('Element|Document')
  @Returns('Element|Document')
  final dynamic _get_target;

  @JSName('webkitForce')
  @DomName('Touch.webkitForce')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  final double force;

  @JSName('webkitRadiusX')
  @DomName('Touch.webkitRadiusX')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  final int radiusX;

  @JSName('webkitRadiusY')
  @DomName('Touch.webkitRadiusY')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  final int radiusY;

  @JSName('webkitRotationAngle')
  @DomName('Touch.webkitRotationAngle')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  final double rotationAngle;


  @DomName('Touch.clientX')
  @DomName('Touch.clientY')
  Point get client => new Point(_clientX, _clientY);

  @DomName('Touch.pageX')
  @DomName('Touch.pageY')
  Point get page => new Point(_pageX, _pageY);

  @DomName('Touch.screenX')
  @DomName('Touch.screenY')
  Point get screen => new Point(_screenX, _screenY);
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('TouchEvent')
// http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
@Experimental()
class TouchEvent extends UIEvent native "TouchEvent" {
  factory TouchEvent(TouchList touches, TouchList targetTouches,
      TouchList changedTouches, String type,
      {Window view, int screenX: 0, int screenY: 0, int clientX: 0,
      int clientY: 0, bool ctrlKey: false, bool altKey: false,
      bool shiftKey: false, bool metaKey: false}) {
    if (view == null) {
      view = window;
    }
    var e = document._createEvent("TouchEvent");
    e._initTouchEvent(touches, targetTouches, changedTouches, type, view,
        screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey);
    return e;
  }
  // To suppress missing implicit constructor warnings.
  factory TouchEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('TouchEvent.altKey')
  @DocsEditable()
  final bool altKey;

  @DomName('TouchEvent.changedTouches')
  @DocsEditable()
  final TouchList changedTouches;

  @DomName('TouchEvent.ctrlKey')
  @DocsEditable()
  final bool ctrlKey;

  @DomName('TouchEvent.metaKey')
  @DocsEditable()
  final bool metaKey;

  @DomName('TouchEvent.shiftKey')
  @DocsEditable()
  final bool shiftKey;

  @DomName('TouchEvent.targetTouches')
  @DocsEditable()
  final TouchList targetTouches;

  @DomName('TouchEvent.touches')
  @DocsEditable()
  final TouchList touches;

  @JSName('initTouchEvent')
  @DomName('TouchEvent.initTouchEvent')
  @DocsEditable()
  void _initTouchEvent(TouchList touches, TouchList targetTouches, TouchList changedTouches, String type, Window view, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey) native;


  /**
   * Checks if touch events supported on the current platform.
   *
   * Note that touch events are only supported if the user is using a touch
   * device.
   */
  static bool get supported => Device.isEventTypeSupported('TouchEvent');
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('TouchList')
// http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
@Experimental()
class TouchList extends Interceptor with ListMixin<Touch>, ImmutableListMixin<Touch> implements JavaScriptIndexingBehavior, List<Touch> native "TouchList" {
  /// NB: This constructor likely does not work as you might expect it to! This
  /// constructor will simply fail (returning null) if you are not on a device
  /// with touch enabled. See dartbug.com/8314.
  // TODO(5760): createTouchList now uses varargs.
  factory TouchList() => null;//document._createTouchList();
  // To suppress missing implicit constructor warnings.
  factory TouchList._() { throw new UnsupportedError("Not supported"); }

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!document.createTouchList');

  @DomName('TouchList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  Touch operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("Touch", "#[#]", this, index);
  }
  void operator[]=(int index, Touch value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Touch> mixins.
  // Touch is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Touch get first {
    if (this.length > 0) {
      return JS('Touch', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Touch get last {
    int len = this.length;
    if (len > 0) {
      return JS('Touch', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Touch get single {
    int len = this.length;
    if (len == 1) {
      return JS('Touch', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Touch elementAt(int index) => this[index];
  // -- end List<Touch> mixins.

  @DomName('TouchList.item')
  @DocsEditable()
  Touch item(int index) native;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLTrackElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#the-track-element
@Experimental()
class TrackElement extends HtmlElement native "HTMLTrackElement" {
  // To suppress missing implicit constructor warnings.
  factory TrackElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLTrackElement.HTMLTrackElement')
  @DocsEditable()
  factory TrackElement() => document.createElement("track");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TrackElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('track');

  @DomName('HTMLTrackElement.ERROR')
  @DocsEditable()
  static const int ERROR = 3;

  @DomName('HTMLTrackElement.LOADED')
  @DocsEditable()
  static const int LOADED = 2;

  @DomName('HTMLTrackElement.LOADING')
  @DocsEditable()
  static const int LOADING = 1;

  @DomName('HTMLTrackElement.NONE')
  @DocsEditable()
  static const int NONE = 0;

  @JSName('default')
  @DomName('HTMLTrackElement.default')
  @DocsEditable()
  bool defaultValue;

  @DomName('HTMLTrackElement.kind')
  @DocsEditable()
  String kind;

  @DomName('HTMLTrackElement.label')
  @DocsEditable()
  String label;

  @DomName('HTMLTrackElement.readyState')
  @DocsEditable()
  final int readyState;

  @DomName('HTMLTrackElement.src')
  @DocsEditable()
  String src;

  @DomName('HTMLTrackElement.srclang')
  @DocsEditable()
  String srclang;

  @DomName('HTMLTrackElement.track')
  @DocsEditable()
  final TextTrack track;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('TrackEvent')
@Unstable()
class TrackEvent extends Event native "TrackEvent" {
  // To suppress missing implicit constructor warnings.
  factory TrackEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('TrackEvent.track')
  @DocsEditable()
  @Creates('Null')
  final Object track;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('TransitionEvent')
class TransitionEvent extends Event native "TransitionEvent,WebKitTransitionEvent" {
  // To suppress missing implicit constructor warnings.
  factory TransitionEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('TransitionEvent.elapsedTime')
  @DocsEditable()
  final double elapsedTime;

  @DomName('TransitionEvent.propertyName')
  @DocsEditable()
  final String propertyName;

  @DomName('TransitionEvent.pseudoElement')
  @DocsEditable()
  final String pseudoElement;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('TreeWalker')
@Unstable()
class TreeWalker extends Interceptor native "TreeWalker" {
  factory TreeWalker(Node root, int whatToShow) {
    return document._createTreeWalker(root, whatToShow, null);
  }
  // To suppress missing implicit constructor warnings.
  factory TreeWalker._() { throw new UnsupportedError("Not supported"); }

  @DomName('TreeWalker.currentNode')
  @DocsEditable()
  Node currentNode;

  @DomName('TreeWalker.filter')
  @DocsEditable()
  final NodeFilter filter;

  @DomName('TreeWalker.root')
  @DocsEditable()
  final Node root;

  @DomName('TreeWalker.whatToShow')
  @DocsEditable()
  final int whatToShow;

  @DomName('TreeWalker.firstChild')
  @DocsEditable()
  Node firstChild() native;

  @DomName('TreeWalker.lastChild')
  @DocsEditable()
  Node lastChild() native;

  @DomName('TreeWalker.nextNode')
  @DocsEditable()
  Node nextNode() native;

  @DomName('TreeWalker.nextSibling')
  @DocsEditable()
  Node nextSibling() native;

  @DomName('TreeWalker.parentNode')
  @DocsEditable()
  Node parentNode() native;

  @DomName('TreeWalker.previousNode')
  @DocsEditable()
  Node previousNode() native;

  @DomName('TreeWalker.previousSibling')
  @DocsEditable()
  Node previousSibling() native;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('UIEvent')
class UIEvent extends Event native "UIEvent" {
  // In JS, canBubble and cancelable are technically required parameters to
  // init*Event. In practice, though, if they aren't provided they simply
  // default to false (since that's Boolean(undefined)).
  //
  // Contrary to JS, we default canBubble and cancelable to true, since that's
  // what people want most of the time anyway.
  factory UIEvent(String type,
      {Window view, int detail: 0, bool canBubble: true,
      bool cancelable: true}) {
    if (view == null) {
      view = window;
    }
    final e = document._createEvent("UIEvent");
    e._initUIEvent(type, canBubble, cancelable, view, detail);
    return e;
  }
  // To suppress missing implicit constructor warnings.
  factory UIEvent._() { throw new UnsupportedError("Not supported"); }

  @JSName('charCode')
  @DomName('UIEvent.charCode')
  @DocsEditable()
  @Unstable()
  final int _charCode;

  @DomName('UIEvent.detail')
  @DocsEditable()
  final int detail;

  @JSName('keyCode')
  @DomName('UIEvent.keyCode')
  @DocsEditable()
  @Unstable()
  final int _keyCode;

  @JSName('layerX')
  @DomName('UIEvent.layerX')
  @DocsEditable()
  // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-mouseevents
  @Experimental() // nonstandard
  final int _layerX;

  @JSName('layerY')
  @DomName('UIEvent.layerY')
  @DocsEditable()
  // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-mouseevents
  @Experimental() // nonstandard
  final int _layerY;

  @JSName('pageX')
  @DomName('UIEvent.pageX')
  @DocsEditable()
  // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-mouseevents
  @Experimental() // nonstandard
  final int _pageX;

  @JSName('pageY')
  @DomName('UIEvent.pageY')
  @DocsEditable()
  // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-mouseevents
  @Experimental() // nonstandard
  final int _pageY;

  @DomName('UIEvent.view')
  @DocsEditable()
  WindowBase get view => _convertNativeToDart_Window(this._get_view);
  @JSName('view')
  @DomName('UIEvent.view')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_view;

  @DomName('UIEvent.which')
  @DocsEditable()
  @Unstable()
  final int which;

  @JSName('initUIEvent')
  @DomName('UIEvent.initUIEvent')
  @DocsEditable()
  void _initUIEvent(String type, bool canBubble, bool cancelable, Window view, int detail) native;


  @DomName('UIEvent.layerX')
  @DomName('UIEvent.layerY')
  Point get layer => new Point(_layerX, _layerY);

  @DomName('UIEvent.pageX')
  @DomName('UIEvent.pageY')
  Point get page => new Point(_pageX, _pageY);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLUListElement')
class UListElement extends HtmlElement native "HTMLUListElement" {
  // To suppress missing implicit constructor warnings.
  factory UListElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLUListElement.HTMLUListElement')
  @DocsEditable()
  factory UListElement() => document.createElement("ul");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  UListElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLUnknownElement')
class UnknownElement extends HtmlElement native "HTMLUnknownElement" {
  // To suppress missing implicit constructor warnings.
  factory UnknownElement._() { throw new UnsupportedError("Not supported"); }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  UnknownElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('URL')
class Url extends Interceptor implements UrlUtils native "URL" {

  static String createObjectUrl(blob_OR_source_OR_stream) =>
      JS('String',
         '(self.URL || self.webkitURL).createObjectURL(#)',
          blob_OR_source_OR_stream);

  static String createObjectUrlFromSource(MediaSource source) =>
      JS('String', '(self.URL || self.webkitURL).createObjectURL(#)', source);
  
  static String createObjectUrlFromStream(MediaStream stream) =>
      JS('String', '(self.URL || self.webkitURL).createObjectURL(#)', stream);
  
  static String createObjectUrlFromBlob(Blob blob) =>
      JS('String', '(self.URL || self.webkitURL).createObjectURL(#)', blob);

  static void revokeObjectUrl(String url) =>
      JS('void',
         '(self.URL || self.webkitURL).revokeObjectURL(#)', url);
  // To suppress missing implicit constructor warnings.
  factory Url._() { throw new UnsupportedError("Not supported"); }

  // From URLUtils

  @DomName('URL.hash')
  @DocsEditable()
  @Experimental() // untriaged
  String hash;

  @DomName('URL.host')
  @DocsEditable()
  @Experimental() // untriaged
  String host;

  @DomName('URL.hostname')
  @DocsEditable()
  @Experimental() // untriaged
  String hostname;

  @DomName('URL.href')
  @DocsEditable()
  @Experimental() // untriaged
  String href;

  @DomName('URL.origin')
  @DocsEditable()
  @Experimental() // untriaged
  final String origin;

  @DomName('URL.password')
  @DocsEditable()
  @Experimental() // untriaged
  String password;

  @DomName('URL.pathname')
  @DocsEditable()
  @Experimental() // untriaged
  String pathname;

  @DomName('URL.port')
  @DocsEditable()
  @Experimental() // untriaged
  String port;

  @DomName('URL.protocol')
  @DocsEditable()
  @Experimental() // untriaged
  String protocol;

  @DomName('URL.search')
  @DocsEditable()
  @Experimental() // untriaged
  String search;

  @DomName('URL.username')
  @DocsEditable()
  @Experimental() // untriaged
  String username;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('URLUtils')
@Experimental() // untriaged
abstract class UrlUtils extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory UrlUtils._() { throw new UnsupportedError("Not supported"); }

  String hash;

  String host;

  String hostname;

  String href;

  final String origin;

  String password;

  String pathname;

  String port;

  String protocol;

  String search;

  String username;

  String toString();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('URLUtilsReadOnly')
@Experimental() // untriaged
abstract class UrlUtilsReadOnly extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory UrlUtilsReadOnly._() { throw new UnsupportedError("Not supported"); }

  final String hash;

  final String host;

  final String hostname;

  final String href;

  final String pathname;

  final String port;

  final String protocol;

  final String search;

  String toString();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('ValidityState')
class ValidityState extends Interceptor native "ValidityState" {
  // To suppress missing implicit constructor warnings.
  factory ValidityState._() { throw new UnsupportedError("Not supported"); }

  @DomName('ValidityState.badInput')
  @DocsEditable()
  final bool badInput;

  @DomName('ValidityState.customError')
  @DocsEditable()
  final bool customError;

  @DomName('ValidityState.patternMismatch')
  @DocsEditable()
  final bool patternMismatch;

  @DomName('ValidityState.rangeOverflow')
  @DocsEditable()
  final bool rangeOverflow;

  @DomName('ValidityState.rangeUnderflow')
  @DocsEditable()
  final bool rangeUnderflow;

  @DomName('ValidityState.stepMismatch')
  @DocsEditable()
  final bool stepMismatch;

  @DomName('ValidityState.tooLong')
  @DocsEditable()
  final bool tooLong;

  @DomName('ValidityState.typeMismatch')
  @DocsEditable()
  final bool typeMismatch;

  @DomName('ValidityState.valid')
  @DocsEditable()
  final bool valid;

  @DomName('ValidityState.valueMissing')
  @DocsEditable()
  final bool valueMissing;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('HTMLVideoElement')
class VideoElement extends MediaElement implements CanvasImageSource native "HTMLVideoElement" {
  // To suppress missing implicit constructor warnings.
  factory VideoElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLVideoElement.HTMLVideoElement')
  @DocsEditable()
  factory VideoElement() => document.createElement("video");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  VideoElement.created() : super.created();

  @DomName('HTMLVideoElement.height')
  @DocsEditable()
  int height;

  @DomName('HTMLVideoElement.poster')
  @DocsEditable()
  String poster;

  @DomName('HTMLVideoElement.videoHeight')
  @DocsEditable()
  final int videoHeight;

  @DomName('HTMLVideoElement.videoWidth')
  @DocsEditable()
  final int videoWidth;

  @JSName('webkitDecodedFrameCount')
  @DomName('HTMLVideoElement.webkitDecodedFrameCount')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  final int decodedFrameCount;

  @JSName('webkitDroppedFrameCount')
  @DomName('HTMLVideoElement.webkitDroppedFrameCount')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  final int droppedFrameCount;

  @DomName('HTMLVideoElement.width')
  @DocsEditable()
  int width;

  @DomName('HTMLVideoElement.getVideoPlaybackQuality')
  @DocsEditable()
  @Experimental() // untriaged
  VideoPlaybackQuality getVideoPlaybackQuality() native;

  @JSName('webkitEnterFullscreen')
  @DomName('HTMLVideoElement.webkitEnterFullscreen')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  void enterFullscreen() native;

  @JSName('webkitExitFullscreen')
  @DomName('HTMLVideoElement.webkitExitFullscreen')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#dom-document-exitfullscreen
  void exitFullscreen() native;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('VideoPlaybackQuality')
@Experimental() // untriaged
class VideoPlaybackQuality extends Interceptor native "VideoPlaybackQuality" {
  // To suppress missing implicit constructor warnings.
  factory VideoPlaybackQuality._() { throw new UnsupportedError("Not supported"); }

  @DomName('VideoPlaybackQuality.corruptedVideoFrames')
  @DocsEditable()
  @Experimental() // untriaged
  final int corruptedVideoFrames;

  @DomName('VideoPlaybackQuality.creationTime')
  @DocsEditable()
  @Experimental() // untriaged
  final double creationTime;

  @DomName('VideoPlaybackQuality.droppedVideoFrames')
  @DocsEditable()
  @Experimental() // untriaged
  final int droppedVideoFrames;

  @DomName('VideoPlaybackQuality.totalVideoFrames')
  @DocsEditable()
  @Experimental() // untriaged
  final int totalVideoFrames;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('VoidCallback')
// http://www.w3.org/TR/file-system-api/#the-voidcallback-interface
@Experimental()
typedef void VoidCallback();
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('VTTCue')
@Experimental() // untriaged
class VttCue extends TextTrackCue native "VTTCue" {
  // To suppress missing implicit constructor warnings.
  factory VttCue._() { throw new UnsupportedError("Not supported"); }

  @DomName('VTTCue.VTTCue')
  @DocsEditable()
  factory VttCue(num startTime, num endTime, String text) {
    return VttCue._create_1(startTime, endTime, text);
  }
  static VttCue _create_1(startTime, endTime, text) => JS('VttCue', 'new VTTCue(#,#,#)', startTime, endTime, text);

  @DomName('VTTCue.align')
  @DocsEditable()
  @Experimental() // untriaged
  String align;

  @DomName('VTTCue.line')
  @DocsEditable()
  @Experimental() // untriaged
  int line;

  @DomName('VTTCue.position')
  @DocsEditable()
  @Experimental() // untriaged
  int position;

  @DomName('VTTCue.regionId')
  @DocsEditable()
  @Experimental() // untriaged
  String regionId;

  @DomName('VTTCue.size')
  @DocsEditable()
  @Experimental() // untriaged
  int size;

  @DomName('VTTCue.snapToLines')
  @DocsEditable()
  @Experimental() // untriaged
  bool snapToLines;

  @DomName('VTTCue.text')
  @DocsEditable()
  @Experimental() // untriaged
  String text;

  @DomName('VTTCue.vertical')
  @DocsEditable()
  @Experimental() // untriaged
  String vertical;

  @JSName('getCueAsHTML')
  @DomName('VTTCue.getCueAsHTML')
  @DocsEditable()
  @Experimental() // untriaged
  DocumentFragment getCueAsHtml() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('VTTRegion')
@Experimental() // untriaged
class VttRegion extends Interceptor native "VTTRegion" {
  // To suppress missing implicit constructor warnings.
  factory VttRegion._() { throw new UnsupportedError("Not supported"); }

  @DomName('VTTRegion.VTTRegion')
  @DocsEditable()
  factory VttRegion() {
    return VttRegion._create_1();
  }
  static VttRegion _create_1() => JS('VttRegion', 'new VTTRegion()');

  @DomName('VTTRegion.height')
  @DocsEditable()
  @Experimental() // untriaged
  int height;

  @DomName('VTTRegion.id')
  @DocsEditable()
  @Experimental() // untriaged
  String id;

  @DomName('VTTRegion.regionAnchorX')
  @DocsEditable()
  @Experimental() // untriaged
  num regionAnchorX;

  @DomName('VTTRegion.regionAnchorY')
  @DocsEditable()
  @Experimental() // untriaged
  num regionAnchorY;

  @DomName('VTTRegion.scroll')
  @DocsEditable()
  @Experimental() // untriaged
  String scroll;

  @DomName('VTTRegion.track')
  @DocsEditable()
  @Experimental() // untriaged
  final TextTrack track;

  @DomName('VTTRegion.viewportAnchorX')
  @DocsEditable()
  @Experimental() // untriaged
  num viewportAnchorX;

  @DomName('VTTRegion.viewportAnchorY')
  @DocsEditable()
  @Experimental() // untriaged
  num viewportAnchorY;

  @DomName('VTTRegion.width')
  @DocsEditable()
  @Experimental() // untriaged
  num width;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('VTTRegionList')
@Experimental() // untriaged
class VttRegionList extends Interceptor native "VTTRegionList" {
  // To suppress missing implicit constructor warnings.
  factory VttRegionList._() { throw new UnsupportedError("Not supported"); }

  @DomName('VTTRegionList.length')
  @DocsEditable()
  @Experimental() // untriaged
  final int length;

  @DomName('VTTRegionList.getRegionById')
  @DocsEditable()
  @Experimental() // untriaged
  VttRegion getRegionById(String id) native;

  @DomName('VTTRegionList.item')
  @DocsEditable()
  @Experimental() // untriaged
  VttRegion item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
/**
 * Use the WebSocket interface to connect to a WebSocket,
 * and to send and receive data on that WebSocket.
 *
 * To use a WebSocket in your web app, first create a WebSocket object,
 * passing the WebSocket URL as an argument to the constructor.
 *
 *     var webSocket = new WebSocket('ws://127.0.0.1:1337/ws');
 *
 * To send data on the WebSocket, use the [send] method.
 *
 *     if (webSocket != null && webSocket.readyState == WebSocket.OPEN) {
 *       webSocket.send(data);
 *     } else {
 *       print('WebSocket not connected, message $data not sent');
 *     }
 *
 * To receive data on the WebSocket, register a listener for message events.
 *
 *     webSocket.onMessage.listen((MessageEvent e) {
 *       receivedData(e.data);
 *     });
 *
 * The message event handler receives a [MessageEvent] object
 * as its sole argument.
 * You can also define open, close, and error handlers,
 * as specified by [WebSocketEvents].
 *
 * For more information, see the
 * [WebSockets](http://www.dartlang.org/docs/library-tour/#html-websockets)
 * section of the library tour and
 * [Introducing WebSockets](http://www.html5rocks.com/en/tutorials/websockets/basics/),
 * an HTML5Rocks.com tutorial.
 */
@DomName('WebSocket')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
class WebSocket extends EventTarget native "WebSocket" {
  // To suppress missing implicit constructor warnings.
  factory WebSocket._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `close` events to event
   * handlers that are not necessarily instances of [WebSocket].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('WebSocket.closeEvent')
  @DocsEditable()
  static const EventStreamProvider<CloseEvent> closeEvent = const EventStreamProvider<CloseEvent>('close');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [WebSocket].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('WebSocket.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [WebSocket].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('WebSocket.messageEvent')
  @DocsEditable()
  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');

  /**
   * Static factory designed to expose `open` events to event
   * handlers that are not necessarily instances of [WebSocket].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('WebSocket.openEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> openEvent = const EventStreamProvider<Event>('open');

  @DomName('WebSocket.WebSocket')
  @DocsEditable()
  factory WebSocket(String url, [protocol_OR_protocols]) {
    if ((url is String || url == null) && protocol_OR_protocols == null) {
      return WebSocket._create_1(url);
    }
    if ((protocol_OR_protocols is List<String> || protocol_OR_protocols == null) && (url is String || url == null)) {
      return WebSocket._create_2(url, protocol_OR_protocols);
    }
    if ((protocol_OR_protocols is String || protocol_OR_protocols == null) && (url is String || url == null)) {
      return WebSocket._create_3(url, protocol_OR_protocols);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static WebSocket _create_1(url) => JS('WebSocket', 'new WebSocket(#)', url);
  static WebSocket _create_2(url, protocol_OR_protocols) => JS('WebSocket', 'new WebSocket(#,#)', url, protocol_OR_protocols);
  static WebSocket _create_3(url, protocol_OR_protocols) => JS('WebSocket', 'new WebSocket(#,#)', url, protocol_OR_protocols);

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', 'typeof window.WebSocket != "undefined"');

  @DomName('WebSocket.CLOSED')
  @DocsEditable()
  static const int CLOSED = 3;

  @DomName('WebSocket.CLOSING')
  @DocsEditable()
  static const int CLOSING = 2;

  @DomName('WebSocket.CONNECTING')
  @DocsEditable()
  static const int CONNECTING = 0;

  @DomName('WebSocket.OPEN')
  @DocsEditable()
  static const int OPEN = 1;

  @DomName('WebSocket.binaryType')
  @DocsEditable()
  String binaryType;

  @DomName('WebSocket.bufferedAmount')
  @DocsEditable()
  final int bufferedAmount;

  @DomName('WebSocket.extensions')
  @DocsEditable()
  final String extensions;

  @DomName('WebSocket.protocol')
  @DocsEditable()
  final String protocol;

  @DomName('WebSocket.readyState')
  @DocsEditable()
  final int readyState;

  @DomName('WebSocket.url')
  @DocsEditable()
  final String url;

  @DomName('WebSocket.close')
  @DocsEditable()
  void close([int code, String reason]) native;

  /**
   * Transmit data to the server over this connection.
   *
   * This method accepts data of type [Blob], [ByteBuffer], [String], or
   * [TypedData]. Named variants [sendBlob], [sendByteBuffer], [sendString],
   * or [sendTypedData], in constrast, only accept data of the specified type.
   */
  @DomName('WebSocket.send')
  @DocsEditable()
  void send(data) native;

  @JSName('send')
  /**
   * Transmit data to the server over this connection.
   *
   * This method accepts data of type [Blob], [ByteBuffer], [String], or
   * [TypedData]. Named variants [sendBlob], [sendByteBuffer], [sendString],
   * or [sendTypedData], in constrast, only accept data of the specified type.
   */
  @DomName('WebSocket.send')
  @DocsEditable()
  void sendBlob(Blob data) native;

  @JSName('send')
  /**
   * Transmit data to the server over this connection.
   *
   * This method accepts data of type [Blob], [ByteBuffer], [String], or
   * [TypedData]. Named variants [sendBlob], [sendByteBuffer], [sendString],
   * or [sendTypedData], in constrast, only accept data of the specified type.
   */
  @DomName('WebSocket.send')
  @DocsEditable()
  void sendByteBuffer(ByteBuffer data) native;

  @JSName('send')
  /**
   * Transmit data to the server over this connection.
   *
   * This method accepts data of type [Blob], [ByteBuffer], [String], or
   * [TypedData]. Named variants [sendBlob], [sendByteBuffer], [sendString],
   * or [sendTypedData], in constrast, only accept data of the specified type.
   */
  @DomName('WebSocket.send')
  @DocsEditable()
  void sendString(String data) native;

  @JSName('send')
  /**
   * Transmit data to the server over this connection.
   *
   * This method accepts data of type [Blob], [ByteBuffer], [String], or
   * [TypedData]. Named variants [sendBlob], [sendByteBuffer], [sendString],
   * or [sendTypedData], in constrast, only accept data of the specified type.
   */
  @DomName('WebSocket.send')
  @DocsEditable()
  void sendTypedData(TypedData data) native;

  /// Stream of `close` events handled by this [WebSocket].
  @DomName('WebSocket.onclose')
  @DocsEditable()
  Stream<CloseEvent> get onClose => closeEvent.forTarget(this);

  /// Stream of `error` events handled by this [WebSocket].
  @DomName('WebSocket.onerror')
  @DocsEditable()
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `message` events handled by this [WebSocket].
  @DomName('WebSocket.onmessage')
  @DocsEditable()
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  /// Stream of `open` events handled by this [WebSocket].
  @DomName('WebSocket.onopen')
  @DocsEditable()
  Stream<Event> get onOpen => openEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('WheelEvent')
class WheelEvent extends MouseEvent native "WheelEvent,MouseWheelEvent,MouseScrollEvent" {

  factory WheelEvent(String type,
      {Window view, int deltaX: 0, int deltaY: 0,
      int detail: 0, int screenX: 0, int screenY: 0, int clientX: 0,
      int clientY: 0, int button: 0, bool canBubble: true,
      bool cancelable: true, bool ctrlKey: false, bool altKey: false,
      bool shiftKey: false, bool metaKey: false, EventTarget relatedTarget}) {

    if (view == null) {
      view = window;
    }
    var eventType = 'WheelEvent';
    if (Device.isFirefox) {
      eventType = 'MouseScrollEvents';
    }
    final event = document._createEvent(eventType);
    // If polyfilling, then flip these because we'll flip them back to match
    // the W3C standard:
    // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-WheelEvent-deltaY
    if (JS('bool', '#.deltaY === undefined', event)) {
      deltaX = -deltaX;
      deltaY = -deltaY;
    }
    if (event._hasInitWheelEvent) {
      var modifiers = [];
      if (ctrlKey) {
        modifiers.push('Control');
      }
      if (altKey) {
        modifiers.push('Alt');
      }
      if (shiftKey) {
        modifiers.push('Shift');
      }
      if (metaKey) {
        modifiers.push('Meta');
      }
      event._initWheelEvent(type, canBubble, cancelable, view, detail, screenX,
          screenY, clientX, clientY, button, relatedTarget, modifiers.join(' '),
          deltaX, deltaY, 0, 0);
    } else if (event._hasInitMouseScrollEvent) {
      var axis = 0;
      var detail = 0;
      if (deltaX != 0 && deltaY != 0) {
        throw new UnsupportedError(
            'Cannot modify deltaX and deltaY simultaneously');
      }
      if (deltaY != 0) {
        detail = deltaY;
        axis = JS('int', 'MouseScrollEvent.VERTICAL_AXIS');
      } else if (deltaX != 0) {
        detail = deltaX;
        axis = JS('int', 'MouseScrollEvent.HORIZONTAL_AXIS');
      }
      event._initMouseScrollEvent(type, canBubble, cancelable, view, detail,
          screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey,
          metaKey, button, relatedTarget, axis);
    } else {
      // Chrome does an auto-convert to pixels.
      deltaY = deltaY ~/ 120;
      // Fallthrough for Dartium.
      event._initMouseEvent(type, canBubble, cancelable, view, detail,
          screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey,
          metaKey, button, relatedTarget);
      event._initWebKitWheelEvent(deltaX, deltaY,
          view, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey,
          metaKey);
    }

    return event;
  }

  // To suppress missing implicit constructor warnings.
  factory WheelEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('WheelEvent.DOM_DELTA_LINE')
  @DocsEditable()
  static const int DOM_DELTA_LINE = 0x01;

  @DomName('WheelEvent.DOM_DELTA_PAGE')
  @DocsEditable()
  static const int DOM_DELTA_PAGE = 0x02;

  @DomName('WheelEvent.DOM_DELTA_PIXEL')
  @DocsEditable()
  static const int DOM_DELTA_PIXEL = 0x00;

  @JSName('deltaX')
  @DomName('WheelEvent.deltaX')
  @DocsEditable()
  @Experimental() // untriaged
  final double _deltaX;

  @JSName('deltaY')
  @DomName('WheelEvent.deltaY')
  @DocsEditable()
  @Experimental() // untriaged
  final double _deltaY;

  @DomName('WheelEvent.deltaZ')
  @DocsEditable()
  @Experimental() // untriaged
  final double deltaZ;

  @JSName('webkitDirectionInvertedFromDevice')
  @DomName('WheelEvent.webkitDirectionInvertedFromDevice')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  final bool directionInvertedFromDevice;

  @JSName('initWebKitWheelEvent')
  @DomName('WheelEvent.initWebKitWheelEvent')
  @DocsEditable()
  @Experimental()
  void _initWebKitWheelEvent(int wheelDeltaX, int wheelDeltaY, Window view, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey) native;


  /**
   * The amount that is expected to scroll vertically, in units determined by
   * [deltaMode].
   *
   * See also:
   *
   * * [WheelEvent.deltaY](http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-WheelEvent-deltaY) from the W3C.
   */
  @DomName('WheelEvent.deltaY')
  num get deltaY {
    if (JS('bool', '#.deltaY !== undefined', this)) {
      // W3C WheelEvent
      return this._deltaY;
    } else if (JS('bool', '#.wheelDelta !== undefined', this)) {
      // Chrome and IE
      return -this._wheelDelta;
    } else if (JS('bool', '#.detail !== undefined', this)) {
      // Firefox

      // Handle DOMMouseScroll case where it uses detail and the axis to
      // differentiate.
      if (JS('bool', '#.axis == MouseScrollEvent.VERTICAL_AXIS', this)) {
        var detail = this._detail;
        // Firefox is normally the number of lines to scale (normally 3)
        // so multiply it by 40 to get pixels to move, matching IE & WebKit.
        if (detail.abs() < 100) {
          return -detail * 40;
        }
        return -detail;
      }
      return 0;
    }
    throw new UnsupportedError(
        'deltaY is not supported');
  }

  /**
   * The amount that is expected to scroll horizontally, in units determined by
   * [deltaMode].
   *
   * See also:
   *
   * * [WheelEvent.deltaX](http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-WheelEvent-deltaX) from the W3C.
   */
  @DomName('WheelEvent.deltaX')
  num get deltaX {
    if (JS('bool', '#.deltaX !== undefined', this)) {
      // W3C WheelEvent
      return this._deltaX;
    } else if (JS('bool', '#.wheelDeltaX !== undefined', this)) {
      // Chrome
      return -this._wheelDeltaX;
    } else if (JS('bool', '#.detail !== undefined', this)) {
      // Firefox and IE.
      // IE will have detail set but will not set axis.

      // Handle DOMMouseScroll case where it uses detail and the axis to
      // differentiate.
      if (JS('bool', '#.axis !== undefined && '
        '#.axis == MouseScrollEvent.HORIZONTAL_AXIS', this, this)) {
        var detail = this._detail;
        // Firefox is normally the number of lines to scale (normally 3)
        // so multiply it by 40 to get pixels to move, matching IE & WebKit.
        if (detail < 100) {
          return -detail * 40;
        }
        return -detail;
      }
      return 0;
    }
    throw new UnsupportedError(
        'deltaX is not supported');
  }

  @DomName('WheelEvent.deltaMode')
  int get deltaMode {
    if (JS('bool', '!!(#.deltaMode)', this)) {
      return JS('int', '#.deltaMode', this);
    }
    // If not available then we're poly-filling and doing pixel scroll.
    return 0;
  }

  num get _wheelDelta => JS('num', '#.wheelDelta', this);
  num get _wheelDeltaX => JS('num', '#.wheelDeltaX', this);
  num get _detail => JS('num', '#.detail', this);

  bool get _hasInitMouseScrollEvent =>
      JS('bool', '!!(#.initMouseScrollEvent)', this);

  @JSName('initMouseScrollEvent')
  void _initMouseScrollEvent(
      String type,
      bool canBubble,
      bool cancelable,
      Window view,
      int detail,
      int screenX,
      int screenY,
      int clientX,
      int clientY,
      bool ctrlKey,
      bool altKey,
      bool shiftKey,
      bool metaKey,
      int button,
      EventTarget relatedTarget,
      int axis) native;

  bool get _hasInitWheelEvent =>
      JS('bool', '!!(#.initWheelEvent)', this);
  @JSName('initWheelEvent')
  void _initWheelEvent(
      String eventType,
      bool canBubble,
      bool cancelable,
      Window view,
      int detail,
      int screenX,
      int screenY,
      int clientX,
      int clientY,
      int button,
      EventTarget relatedTarget,
      String modifiersList,
      int deltaX,
      int deltaY,
      int deltaZ,
      int deltaMode) native;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
/**
 * Top-level container for the current browser tab or window.
 *
 * In a web browser, each window has a [Window] object, but within the context
 * of a script, this object represents only the current window.
 * Each other window, tab, and iframe has its own [Window] object.
 *
 * Each window contains a [Document] object, which contains all of the window's
 * content.
 *
 * Use the top-level `window` object to access the current window.
 * For example:
 *
 *     // Draw a scene when the window repaints.
 *     drawScene(num delta) {...}
 *     window.animationFrame.then(drawScene);.
 *
 *     // Write to the console.
 *     window.console.log('Jinkies!');
 *     window.console.error('Jeepers!');
 *
 * **Note:** This class represents only the current window, while [WindowBase]
 * is a representation of any window, including other tabs, windows, and frames.
 *
 * ## See also
 *
 * * [WindowBase]
 *
 * ## Other resources
 *
 * * [DOM Window](https://developer.mozilla.org/en-US/docs/DOM/window) from MDN.
 * * [Window](http://www.w3.org/TR/Window/) from the W3C.
 */
@DomName('Window')
class Window extends EventTarget implements WindowEventHandlers, WindowBase, GlobalEventHandlers, _WindowTimers, WindowBase64 native "Window,DOMWindow" {

  /**
   * Returns a Future that completes just before the window is about to
   * repaint so the user can draw an animation frame.
   *
   * If you need to later cancel this animation, use [requestAnimationFrame]
   * instead.
   *
   * The [Future] completes to a timestamp that represents a floating
   * point value of the number of milliseconds that have elapsed since the page
   * started to load (which is also the timestamp at this call to
   * animationFrame).
   *
   * Note: The code that runs when the future completes should call
   * [animationFrame] again for the animation to continue.
   */
  Future<num> get animationFrame {
    var completer = new Completer<num>.sync();
    requestAnimationFrame((time) {
      completer.complete(time);
    });
    return completer.future;
  }

  /**
   * The newest document in this window.
   *
   * ## Other resources
   *
   * * [Loading web pages]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html)
   * from WHATWG.
   */
  Document get document => JS('Document', '#.document', this);

  WindowBase _open2(url, name) => JS('Window', '#.open(#,#)', this, url, name);

  WindowBase _open3(url, name, options) =>
      JS('Window', '#.open(#,#,#)', this, url, name, options);

  /**
   * Opens a new window.
   *
   * ## Other resources
   *
   * * [Window.open]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.open) from MDN.
   * * [Window open]
   * (http://docs.webplatform.org/wiki/dom/methods/open) from WebPlatform.org.
   */
  WindowBase open(String url, String name, [String options]) {
    if (options == null) {
      return _DOMWindowCrossFrame._createSafe(_open2(url, name));
    } else {
      return _DOMWindowCrossFrame._createSafe(_open3(url, name, options));
    }
  }

  // API level getter and setter for Location.
  // TODO: The cross domain safe wrapper can be inserted here.
  /**
   * The current location of this window.
   *
   *     Location currentLocation = window.location;
   *     print(currentLocation.href); // 'http://www.example.com:80/'
   */
  Location get location => _location;

  // TODO: consider forcing users to do: window.location.assign('string').
  /**
   * Sets the window's location, which causes the browser to navigate to the new
   * location. [value] may be a Location object or a String.
   */
  void set location(value) {
    _location = value;
  }

  // Native getter and setter to access raw Location object.
  dynamic get _location => JS('Location|Null', '#.location', this);
  void set _location(value) {
    JS('void', '#.location = #', this, value);
  }

  /**
   * Called to draw an animation frame and then request the window to repaint
   * after [callback] has finished (creating the animation).
   *
   * Use this method only if you need to later call [cancelAnimationFrame]. If
   * not, the preferred Dart idiom is to set animation frames by calling
   * [animationFrame], which returns a Future.
   *
   * Returns a non-zero valued integer to represent the request id for this
   * request. This value only needs to be saved if you intend to call
   * [cancelAnimationFrame] so you can specify the particular animation to
   * cancel.
   *
   * Note: The supplied [callback] needs to call [requestAnimationFrame] again
   * for the animation to continue.
   */
  @DomName('Window.requestAnimationFrame')
  int requestAnimationFrame(RequestAnimationFrameCallback callback) {
    _ensureRequestAnimationFrame();
    return _requestAnimationFrame(_wrapZone(callback));
  }

  /**
   * Cancels an animation frame request.
   *
   * ## Other resources
   *
   * * [Window.cancelAnimationFrame]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.cancelAnimationFrame) from MDN.
   */
  void cancelAnimationFrame(int id) {
    _ensureRequestAnimationFrame();
    _cancelAnimationFrame(id);
  }

  @JSName('requestAnimationFrame')
  int _requestAnimationFrame(RequestAnimationFrameCallback callback) native;

  @JSName('cancelAnimationFrame')
  void _cancelAnimationFrame(int id) native;

  _ensureRequestAnimationFrame() {
    if (JS('bool',
           '!!(#.requestAnimationFrame && #.cancelAnimationFrame)', this, this))
      return;

    JS('void',
       r"""
  (function($this) {
   var vendors = ['ms', 'moz', 'webkit', 'o'];
   for (var i = 0; i < vendors.length && !$this.requestAnimationFrame; ++i) {
     $this.requestAnimationFrame = $this[vendors[i] + 'RequestAnimationFrame'];
     $this.cancelAnimationFrame =
         $this[vendors[i]+'CancelAnimationFrame'] ||
         $this[vendors[i]+'CancelRequestAnimationFrame'];
   }
   if ($this.requestAnimationFrame && $this.cancelAnimationFrame) return;
   $this.requestAnimationFrame = function(callback) {
      return window.setTimeout(function() {
        callback(Date.now());
      }, 16 /* 16ms ~= 60fps */);
   };
   $this.cancelAnimationFrame = function(id) { clearTimeout(id); }
  })(#)""",
       this);
  }

  /**
   * Gets an instance of the Indexed DB factory to being using Indexed DB.
   *
   * Use [indexed_db.IdbFactory.supported] to check if Indexed DB is supported on the
   * current platform.
   */
  @SupportedBrowser(SupportedBrowser.CHROME, '23.0')
  @SupportedBrowser(SupportedBrowser.FIREFOX, '15.0')
  @SupportedBrowser(SupportedBrowser.IE, '10.0')
  @Experimental()
  IdbFactory get indexedDB =>
      JS('IdbFactory|Null',  // If not supported, returns null.
         '#.indexedDB || #.webkitIndexedDB || #.mozIndexedDB',
         this, this, this);

  /// The debugging console for this window.
  @DomName('Window.console')
  Console get console => Console._safeConsole;


  /**
   * Access a sandboxed file system of the specified `size`. If `persistent` is
   * true, the application will request permission from the user to create
   * lasting storage. This storage cannot be freed without the user's
   * permission. Returns a [Future] whose value stores a reference to the
   * sandboxed file system for use. Because the file system is sandboxed,
   * applications cannot access file systems created in other web pages.
   */
  Future<FileSystem> requestFileSystem(int size, {bool persistent: false}) {
    return _requestFileSystem(persistent? 1 : 0, size);
  }

  /**
   * Converts a point from node coordinates to this window's coordinates.
   *
   * ## Other resources
   *
   * * [webkitConvertPointFromPageToNode]
   * (https://developer.apple.com/library/safari/documentation/DataManagement/Reference/DOMWindowAdditionsReference/DOMWindowAdditions/DOMWindowAdditions.html#//apple_ref/javascript/instm/DOMWindow/webkitConvertPointFromNodeToPage)
   * from Safari Development Library.
   */
  @DomName('Window.convertPointFromNodeToPage')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  Point convertPointFromNodeToPage(Node node, Point point) {
    var result = _convertPointFromNodeToPage(node,
        new _DomPoint(point.x, point.y));
    return new Point(result.x, result.y);
  }

  /**
   * Converts a point from this window's coordinates to node coordinates.
   *
   * ## Other resources
   *
   * * [webkitConvertPointFromPageToNode]
   * (https://developer.apple.com/library/safari/documentation/DataManagement/Reference/DOMWindowAdditionsReference/DOMWindowAdditions/DOMWindowAdditions.html#//apple_ref/javascript/instm/DOMWindow/webkitConvertPointFromPageToNode)
   * from Safari Development Library.
   */
  @DomName('Window.convertPointFromPageToNode')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  Point convertPointFromPageToNode(Node node, Point point) {
    var result = _convertPointFromPageToNode(node,
        new _DomPoint(point.x, point.y));
    return new Point(result.x, result.y);
  }

  /**
   * Checks whether [convertPointFromNodeToPage] and
   * [convertPointFromPageToNode] are supported on the current platform.
   */
  static bool get supportsPointConversions => _DomPoint.supported;
  // To suppress missing implicit constructor warnings.
  factory Window._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `contentloaded` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.DOMContentLoadedEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> contentLoadedEvent = const EventStreamProvider<Event>('DOMContentLoaded');

  /**
   * Static factory designed to expose `devicemotion` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.devicemotionEvent')
  @DocsEditable()
  // http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
  @Experimental()
  static const EventStreamProvider<DeviceMotionEvent> deviceMotionEvent = const EventStreamProvider<DeviceMotionEvent>('devicemotion');

  /**
   * Static factory designed to expose `deviceorientation` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.deviceorientationEvent')
  @DocsEditable()
  // http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
  @Experimental()
  static const EventStreamProvider<DeviceOrientationEvent> deviceOrientationEvent = const EventStreamProvider<DeviceOrientationEvent>('deviceorientation');

  /**
   * Static factory designed to expose `hashchange` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.hashchangeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> hashChangeEvent = const EventStreamProvider<Event>('hashchange');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.messageEvent')
  @DocsEditable()
  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');

  /**
   * Static factory designed to expose `offline` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.offlineEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> offlineEvent = const EventStreamProvider<Event>('offline');

  /**
   * Static factory designed to expose `online` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.onlineEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> onlineEvent = const EventStreamProvider<Event>('online');

  /**
   * Static factory designed to expose `pagehide` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.pagehideEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> pageHideEvent = const EventStreamProvider<Event>('pagehide');

  /**
   * Static factory designed to expose `pageshow` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.pageshowEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> pageShowEvent = const EventStreamProvider<Event>('pageshow');

  /**
   * Static factory designed to expose `popstate` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.popstateEvent')
  @DocsEditable()
  static const EventStreamProvider<PopStateEvent> popStateEvent = const EventStreamProvider<PopStateEvent>('popstate');

  /**
   * Static factory designed to expose `storage` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.storageEvent')
  @DocsEditable()
  static const EventStreamProvider<StorageEvent> storageEvent = const EventStreamProvider<StorageEvent>('storage');

  /**
   * Static factory designed to expose `unload` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.unloadEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> unloadEvent = const EventStreamProvider<Event>('unload');

  /**
   * Static factory designed to expose `animationend` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.webkitAnimationEndEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  static const EventStreamProvider<AnimationEvent> animationEndEvent = const EventStreamProvider<AnimationEvent>('webkitAnimationEnd');

  /**
   * Static factory designed to expose `animationiteration` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.webkitAnimationIterationEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  static const EventStreamProvider<AnimationEvent> animationIterationEvent = const EventStreamProvider<AnimationEvent>('webkitAnimationIteration');

  /**
   * Static factory designed to expose `animationstart` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.webkitAnimationStartEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  static const EventStreamProvider<AnimationEvent> animationStartEvent = const EventStreamProvider<AnimationEvent>('webkitAnimationStart');

  /**
   * Indicates that file system data cannot be cleared unless given user
   * permission.
   *
   * ## Other resources
   *
   * * [Exploring the FileSystem APIs]
   * (http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.
   * * [File API]
   * (http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem) from W3C.
   */
  @DomName('Window.PERSISTENT')
  @DocsEditable()
  // http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem
  @Experimental()
  static const int PERSISTENT = 1;

  /**
   * Indicates that file system data can be cleared at any time.
   *
   * ## Other resources
   *
   * * [Exploring the FileSystem APIs]
   * (http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.
   * * [File API]
   * (http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem) from W3C.
   */
  @DomName('Window.TEMPORARY')
  @DocsEditable()
  // http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem
  @Experimental()
  static const int TEMPORARY = 0;

  @JSName('CSS')
  /**
   * Entrypoint for CSS-related functions.
   *
   * ## Other resources
   *
   * * [The CSS interface](http://dev.w3.org/csswg/css-conditional/#the-css-interface) from W3C.
   */
  @DomName('Window.CSS')
  @DocsEditable()
  final Css css;

  /**
   * The application cache for this window.
   *
   * ## Other resources
   *
   * * [A beginner's guide to using the application cache]
   * (http://www.html5rocks.com/en/tutorials/appcache/beginner) from HTML5Rocks.
   * * [Application cache API]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html#application-cache-api)
   * from WHATWG.
   */
  @DomName('Window.applicationCache')
  @DocsEditable()
  final ApplicationCache applicationCache;

  @DomName('Window.closed')
  @DocsEditable()
  final bool closed;

  /**
   * Entrypoint for the browser's cryptographic functions.
   *
   * ## Other resources
   *
   * * [Web cryptography API](http://www.w3.org/TR/WebCryptoAPI/) from W3C.
   */
  @DomName('Window.crypto')
  @DocsEditable()
  // http://www.w3.org/TR/WebCryptoAPI/
  @Experimental()
  final Crypto crypto;

  /// *Deprecated*.
  @DomName('Window.defaultStatus')
  @DocsEditable()
  @Experimental() // non-standard
  String defaultStatus;

  /// *Deprecated*.
  @DomName('Window.defaultstatus')
  @DocsEditable()
  @Experimental() // non-standard
  String defaultstatus;

  /**
   * The ratio between physical pixels and logical CSS pixels.
   *
   * ## Other resources
   *
   * * [devicePixelRatio]
   * (http://www.quirksmode.org/blog/archives/2012/06/devicepixelrati.html) from
   * quirksmode.
   * * [More about devicePixelRatio]
   * (http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html) from
   * quirksmode.
   */
  @DomName('Window.devicePixelRatio')
  @DocsEditable()
  // http://www.quirksmode.org/blog/archives/2012/06/devicepixelrati.html
  @Experimental() // non-standard
  final double devicePixelRatio;

  /**
   * The current session history for this window's newest document.
   *
   * ## Other resources
   *
   * * [Loading web pages]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html)
   * from WHATWG.
   */
  @DomName('Window.history')
  @DocsEditable()
  final History history;

  /**
   * The height of the viewport including scrollbars.
   *
   * ## Other resources
   *
   * * [innerHeight]
   * (http://docs.webplatform.org/wiki/css/cssom/properties/innerHeight) from
   * WebPlatform.org.
   */
  @DomName('Window.innerHeight')
  @DocsEditable()
  final int innerHeight;

  /**
   * The width of the viewport including scrollbars.
   *
   * ## Other resources
   *
   * * [innerWidth]
   * (http://docs.webplatform.org/wiki/css/cssom/properties/innerWidth) from
   * WebPlatform.org.
   */
  @DomName('Window.innerWidth')
  @DocsEditable()
  final int innerWidth;

  /**
   * Storage for this window that persists across sessions.
   *
   * ## Other resources
   *
   * * [DOM storage guide]
   * (https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage) from
   * MDN.
   * * [The past, present & future of local storage for web applications]
   * (http://diveintohtml5.info/storage.html) from Dive Into HTML5.
   * * [Local storage specification]
   * (http://www.w3.org/TR/webstorage/#the-localstorage-attribute) from W3C.
   */
  @DomName('Window.localStorage')
  @DocsEditable()
  final Storage localStorage;

  /**
   * This window's location bar, which displays the URL.
   *
   * ## Other resources
   *
   * * [Browser interface elements]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
   * from WHATWG.
   */
  @DomName('Window.locationbar')
  @DocsEditable()
  final BarProp locationbar;

  /**
   * This window's menu bar, which displays menu commands.
   *
   * ## Other resources
   *
   * * [Browser interface elements]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
   * from WHATWG.
   */
  @DomName('Window.menubar')
  @DocsEditable()
  final BarProp menubar;

  /**
   * The name of this window.
   *
   * ## Other resources
   *
   * * [Window name]
   * (http://docs.webplatform.org/wiki/html/attributes/name_(window)) from
   * WebPlatform.org.
   */
  @DomName('Window.name')
  @DocsEditable()
  String name;

  /**
   * The user agent accessing this window.
   *
   * ## Other resources
   *
   * * [The navigator object]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#the-navigator-object)
   * from WHATWG.
   */
  @DomName('Window.navigator')
  @DocsEditable()
  final Navigator navigator;

  /**
   * Whether objects are drawn offscreen before being displayed.
   *
   * ## Other resources
   *
   * * [offscreenBuffering]
   * (http://docs.webplatform.org/wiki/dom/properties/offscreenBuffering) from
   * WebPlatform.org.
   */
  @DomName('Window.offscreenBuffering')
  @DocsEditable()
  @Experimental() // non-standard
  final bool offscreenBuffering;

  @DomName('Window.opener')
  @DocsEditable()
  WindowBase get opener => _convertNativeToDart_Window(this._get_opener);
  @JSName('opener')
  @DomName('Window.opener')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_opener;

  void set opener(Window value) {
    JS("void", "#.opener = #", this, value);
  }

  @DomName('Window.orientation')
  @DocsEditable()
  @Experimental() // untriaged
  final int orientation;

  /**
   * The height of this window including all user interface elements.
   *
   * ## Other resources
   *
   * * [outerHeight]
   * (http://docs.webplatform.org/wiki/css/cssom/properties/outerHeight) from
   * WebPlatform.org.
   */
  @DomName('Window.outerHeight')
  @DocsEditable()
  final int outerHeight;

  /**
   * The width of the window including all user interface elements.
   *
   * ## Other resources
   *
   * * [outerWidth]
   * (http://docs.webplatform.org/wiki/css/cssom/properties/outerWidth) from
   * WebPlatform.org.
   */
  @DomName('Window.outerWidth')
  @DocsEditable()
  final int outerWidth;

  /**
   * The distance this window has been scrolled horizontally.
   *
   * This attribute is an alias for [scrollX].
   *
   * ## Other resources
   *
   * * [The Screen interface specification]
   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
   * * [scrollX and pageXOffset]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX) from MDN.
   */
  @DomName('Window.pageXOffset')
  @DocsEditable()
  final int pageXOffset;

  /**
   * The distance this window has been scrolled vertically.
   *
   * This attribute is an alias for [scrollY].
   *
   * ## Other resources
   *
   * * [The Screen interface specification]
   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
   * * [scrollY and pageYOffset]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY) from MDN.
   */
  @DomName('Window.pageYOffset')
  @DocsEditable()
  final int pageYOffset;

  @DomName('Window.parent')
  @DocsEditable()
  WindowBase get parent => _convertNativeToDart_Window(this._get_parent);
  @JSName('parent')
  @DomName('Window.parent')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_parent;

  /**
   * Timing and navigation data for this window.
   *
   * ## Other resources
   *
   * * [Measuring page load speed with navigation timeing]
   * (http://www.html5rocks.com/en/tutorials/webperformance/basics/) from
   * HTML5Rocks.
   * * [Navigation timing specification]
   * (http://www.w3.org/TR/navigation-timing/) from W3C.
   */
  @DomName('Window.performance')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE)
  final Performance performance;

  /**
   * Information about the screen displaying this window.
   *
   * ## Other resources
   *
   * * [The Screen interface specification]
   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
   */
  @DomName('Window.screen')
  @DocsEditable()
  final Screen screen;

  /**
   * The distance from the left side of the screen to the left side of this
   * window.
   *
   * ## Other resources
   *
   * * [The Screen interface specification]
   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
   */
  @DomName('Window.screenLeft')
  @DocsEditable()
  final int screenLeft;

  /**
   * The distance from the top of the screen to the top of this window.
   *
   * ## Other resources
   *
   * * [The Screen interface specification]
   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
   */
  @DomName('Window.screenTop')
  @DocsEditable()
  final int screenTop;

  /**
   * The distance from the left side of the screen to the mouse pointer.
   *
   * ## Other resources
   *
   * * [The Screen interface specification]
   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
   */
  @DomName('Window.screenX')
  @DocsEditable()
  final int screenX;

  /**
   * The distance from the top of the screen to the mouse pointer.
   *
   * ## Other resources
   *
   * * [The Screen interface specification]
   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
   */
  @DomName('Window.screenY')
  @DocsEditable()
  final int screenY;

  /**
   * This window's scroll bars.
   *
   * ## Other resources
   *
   * * [Browser interface elements]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
   * from WHATWG.
   */
  @DomName('Window.scrollbars')
  @DocsEditable()
  final BarProp scrollbars;

  /**
   * The current window.
   *
   * ## Other resources
   *
   * * [Window.self]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.self) from MDN.
   */
  @DomName('Window.self')
  @DocsEditable()
  WindowBase get self => _convertNativeToDart_Window(this._get_self);
  @JSName('self')
  /**
   * The current window.
   *
   * ## Other resources
   *
   * * [Window.self]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.self) from MDN.
   */
  @DomName('Window.self')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_self;

  /**
   * Storage for this window that is cleared when this session ends.
   *
   * ## Other resources
   *
   * * [DOM storage guide]
   * (https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage) from
   * MDN.
   * * [The past, present & future of local storage for web applications]
   * (http://diveintohtml5.info/storage.html) from Dive Into HTML5.
   * * [Local storage specification]
   * (http://www.w3.org/TR/webstorage/#dom-sessionstorage) from W3C.
   */
  @DomName('Window.sessionStorage')
  @DocsEditable()
  final Storage sessionStorage;

  /**
   * Access to speech synthesis in the browser.
   *
   * ## Other resources
   *
   * * [Web speech specification]
   * (https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section)
   * from W3C.
   */
  @DomName('Window.speechSynthesis')
  @DocsEditable()
  // https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section
  @Experimental()
  final SpeechSynthesis speechSynthesis;

  /// *Deprecated*.
  @DomName('Window.status')
  @DocsEditable()
  String status;

  /**
   * This window's status bar.
   *
   * ## Other resources
   *
   * * [Browser interface elements]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
   * from WHATWG.
   */
  @DomName('Window.statusbar')
  @DocsEditable()
  final BarProp statusbar;

  /**
   * Access to CSS media queries.
   *
   * ## Other resources
   *
   * * [StyleMedia class reference]
   * (https://developer.apple.com/library/safari/documentation/SafariDOMAdditions/Reference/StyleMedia/StyleMedia/StyleMedia.html)
   * from Safari Developer Library.
   */
  @DomName('Window.styleMedia')
  @DocsEditable()
  // http://developer.apple.com/library/safari/#documentation/SafariDOMAdditions/Reference/StyleMedia/StyleMedia/StyleMedia.html
  @Experimental() // nonstandard
  final StyleMedia styleMedia;

  /**
   * This window's tool bar.
   *
   * ## Other resources
   *
   * * [Browser interface elements]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
   * from WHATWG.
   */
  @DomName('Window.toolbar')
  @DocsEditable()
  final BarProp toolbar;

  @DomName('Window.top')
  @DocsEditable()
  WindowBase get top => _convertNativeToDart_Window(this._get_top);
  @JSName('top')
  @DomName('Window.top')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_top;

  /**
   * The current window.
   *
   * ## Other resources
   *
   * * [Window.window]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.window) from MDN.
   */
  @DomName('Window.window')
  @DocsEditable()
  WindowBase get window => _convertNativeToDart_Window(this._get_window);
  @JSName('window')
  /**
   * The current window.
   *
   * ## Other resources
   *
   * * [Window.window]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.window) from MDN.
   */
  @DomName('Window.window')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_window;

  @DomName('Window.__getter__')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  WindowBase __getter__(index_OR_name) {
    if ((index_OR_name is int || index_OR_name == null)) {
      return _convertNativeToDart_Window(__getter___1(index_OR_name));
    }
    if ((index_OR_name is String || index_OR_name == null)) {
      return _convertNativeToDart_Window(__getter___2(index_OR_name));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  @JSName('__getter__')
  @DomName('Window.__getter__')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  __getter___1(int index) native;
  @JSName('__getter__')
  @DomName('Window.__getter__')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  __getter___2(String name) native;

  /**
   * Displays a modal alert to the user.
   *
   * ## Other resources
   *
   * * [User prompts]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#user-prompts)
   * from WHATWG.
   */
  @DomName('Window.alert')
  @DocsEditable()
  void alert(String message) native;

  @DomName('Window.close')
  @DocsEditable()
  void close() native;

  /**
   * Displays a modal OK/Cancel prompt to the user.
   *
   * ## Other resources
   *
   * * [User prompts]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#user-prompts)
   * from WHATWG.
   */
  @DomName('Window.confirm')
  @DocsEditable()
  bool confirm(String message) native;

  /**
   * Finds text in this window.
   *
   * ## Other resources
   *
   * * [Window.find]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.find) from MDN.
   */
  @DomName('Window.find')
  @DocsEditable()
  @Experimental() // non-standard
  bool find(String string, bool caseSensitive, bool backwards, bool wrap, bool wholeWord, bool searchInFrames, bool showDialog) native;

  @JSName('getComputedStyle')
  @DomName('Window.getComputedStyle')
  @DocsEditable()
  CssStyleDeclaration _getComputedStyle(Element element, String pseudoElement) native;

  @JSName('getMatchedCSSRules')
  /**
   * Returns all CSS rules that apply to the element's pseudo-element.
   */
  @DomName('Window.getMatchedCSSRules')
  @DocsEditable()
  @Experimental() // non-standard
  @Returns('_CssRuleList')
  @Creates('_CssRuleList')
  List<CssRule> getMatchedCssRules(Element element, String pseudoElement) native;

  /**
   * Returns the currently selected text.
   *
   * ## Other resources
   *
   * * [Window.getSelection]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.getSelection)
   * from MDN.
   */
  @DomName('Window.getSelection')
  @DocsEditable()
  Selection getSelection() native;

  /**
   * Returns a list of media queries for the given query string.
   *
   * ## Other resources
   *
   * * [Testing media queries]
   * (https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Testing_media_queries)
   * from MDN.
   * * [The MediaQueryList specification]
   * (http://www.w3.org/TR/cssom-view/#the-mediaquerylist-interface) from W3C.
   */
  @DomName('Window.matchMedia')
  @DocsEditable()
  MediaQueryList matchMedia(String query) native;

  /**
   * Moves this window.
   *
   * x and y can be negative.
   *
   * ## Other resources
   *
   * * [Window.moveBy]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.moveBy) from MDN.
   * * [Window.moveBy]
   * (http://dev.w3.org/csswg/cssom-view/#dom-window-moveby) from W3C.
   */
  @DomName('Window.moveBy')
  @DocsEditable()
  void moveBy(num x, num y) native;

  @JSName('moveTo')
  @DomName('Window.moveTo')
  @DocsEditable()
  void _moveTo(num x, num y) native;

  /// *Deprecated.*
  @DomName('Window.openDatabase')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.w3.org/TR/webdatabase/
  @Experimental() // deprecated
  @Creates('SqlDatabase')
  SqlDatabase openDatabase(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) native;

  @DomName('Window.postMessage')
  @DocsEditable()
  void postMessage(/*SerializedScriptValue*/ message, String targetOrigin, [List<MessagePort> messagePorts]) {
    if (messagePorts != null) {
      var message_1 = convertDartToNative_SerializedScriptValue(message);
      _postMessage_1(message_1, targetOrigin, messagePorts);
      return;
    }
    var message_2 = convertDartToNative_SerializedScriptValue(message);
    _postMessage_2(message_2, targetOrigin);
    return;
  }
  @JSName('postMessage')
  @DomName('Window.postMessage')
  @DocsEditable()
  void _postMessage_1(message, targetOrigin, List<MessagePort> messagePorts) native;
  @JSName('postMessage')
  @DomName('Window.postMessage')
  @DocsEditable()
  void _postMessage_2(message, targetOrigin) native;

  /**
   * Opens the print dialog for this window.
   *
   * ## Other resources
   *
   * * [Window.print]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.print) from MDN.
   */
  @DomName('Window.print')
  @DocsEditable()
  void print() native;

  /**
   * Resizes this window by an offset.
   *
   * ## Other resources
   *
   * * [Window resizeBy] (http://docs.webplatform.org/wiki/dom/methods/resizeBy)
   * from WebPlatform.org.
   */
  @DomName('Window.resizeBy')
  @DocsEditable()
  void resizeBy(num x, num y) native;

  /**
   * Resizes this window to a specific width and height.
   *
   * ## Other resources
   *
   * * [Window resizeTo] (http://docs.webplatform.org/wiki/dom/methods/resizeTo)
   * from WebPlatform.org.
   */
  @DomName('Window.resizeTo')
  @DocsEditable()
  void resizeTo(num width, num height) native;

  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scrollTo].
   *
   * ## Other resources
   *
   * * [Window scroll] (http://docs.webplatform.org/wiki/dom/methods/scroll)
   * from WebPlatform.org.
   */
  @DomName('Window.scroll')
  @DocsEditable()
  void scroll(int x, int y, [Map scrollOptions]) {
    if (scrollOptions != null) {
      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
      _scroll_1(x, y, scrollOptions_1);
      return;
    }
    _scroll_2(x, y);
    return;
  }
  @JSName('scroll')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scrollTo].
   *
   * ## Other resources
   *
   * * [Window scroll] (http://docs.webplatform.org/wiki/dom/methods/scroll)
   * from WebPlatform.org.
   */
  @DomName('Window.scroll')
  @DocsEditable()
  void _scroll_1(x, y, scrollOptions) native;
  @JSName('scroll')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scrollTo].
   *
   * ## Other resources
   *
   * * [Window scroll] (http://docs.webplatform.org/wiki/dom/methods/scroll)
   * from WebPlatform.org.
   */
  @DomName('Window.scroll')
  @DocsEditable()
  void _scroll_2(x, y) native;

  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window scrollBy] (http://docs.webplatform.org/wiki/dom/methods/scrollBy)
   * from WebPlatform.org.
   */
  @DomName('Window.scrollBy')
  @DocsEditable()
  void scrollBy(int x, int y, [Map scrollOptions]) {
    if (scrollOptions != null) {
      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
      _scrollBy_1(x, y, scrollOptions_1);
      return;
    }
    _scrollBy_2(x, y);
    return;
  }
  @JSName('scrollBy')
  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window scrollBy] (http://docs.webplatform.org/wiki/dom/methods/scrollBy)
   * from WebPlatform.org.
   */
  @DomName('Window.scrollBy')
  @DocsEditable()
  void _scrollBy_1(x, y, scrollOptions) native;
  @JSName('scrollBy')
  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window scrollBy] (http://docs.webplatform.org/wiki/dom/methods/scrollBy)
   * from WebPlatform.org.
   */
  @DomName('Window.scrollBy')
  @DocsEditable()
  void _scrollBy_2(x, y) native;

  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scroll].
   *
   * ## Other resources
   *
   * * [Window scrollTo] (http://docs.webplatform.org/wiki/dom/methods/scrollTo)
   * from WebPlatform.org.
   */
  @DomName('Window.scrollTo')
  @DocsEditable()
  void scrollTo(int x, int y, [Map scrollOptions]) {
    if (scrollOptions != null) {
      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
      _scrollTo_1(x, y, scrollOptions_1);
      return;
    }
    _scrollTo_2(x, y);
    return;
  }
  @JSName('scrollTo')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scroll].
   *
   * ## Other resources
   *
   * * [Window scrollTo] (http://docs.webplatform.org/wiki/dom/methods/scrollTo)
   * from WebPlatform.org.
   */
  @DomName('Window.scrollTo')
  @DocsEditable()
  void _scrollTo_1(x, y, scrollOptions) native;
  @JSName('scrollTo')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scroll].
   *
   * ## Other resources
   *
   * * [Window scrollTo] (http://docs.webplatform.org/wiki/dom/methods/scrollTo)
   * from WebPlatform.org.
   */
  @DomName('Window.scrollTo')
  @DocsEditable()
  void _scrollTo_2(x, y) native;

  /**
   * Opens a new page as a modal dialog.
   *
   * ## Other resources
   *
   * * [Dialogs implemented using separate documents]
   * (http://www.w3.org/html/wg/drafts/html/master/webappapis.html#dialogs-implemented-using-separate-documents)
   * from W3C.
   */
  @DomName('Window.showModalDialog')
  @DocsEditable()
  @Creates('Null')
  Object showModalDialog(String url, [Object dialogArgs, String featureArgs]) native;

  /**
   * Stops the window from loading.
   *
   * ## Other resources
   *
   * * [The Window object]
   * (http://www.w3.org/html/wg/drafts/html/master/browsers.html#the-window-object)
   * from W3C.
   */
  @DomName('Window.stop')
  @DocsEditable()
  void stop() native;

  @DomName('Window.toString')
  @DocsEditable()
  String toString() native;

  @JSName('webkitConvertPointFromNodeToPage')
  @DomName('Window.webkitConvertPointFromNodeToPage')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://developer.apple.com/library/safari/#documentation/DataManagement/Reference/DOMWindowAdditionsReference/DOMWindowAdditions/DOMWindowAdditions.html
  _DomPoint _convertPointFromNodeToPage(Node node, _DomPoint p) native;

  @JSName('webkitConvertPointFromPageToNode')
  @DomName('Window.webkitConvertPointFromPageToNode')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://developer.apple.com/library/safari/#documentation/DataManagement/Reference/DOMWindowAdditionsReference/DOMWindowAdditions/DOMWindowAdditions.html
  _DomPoint _convertPointFromPageToNode(Node node, _DomPoint p) native;

  @JSName('webkitRequestFileSystem')
  @DomName('Window.webkitRequestFileSystem')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @Experimental()
  // http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem
  void __requestFileSystem(int type, int size, _FileSystemCallback successCallback, [_ErrorCallback errorCallback]) native;

  @JSName('webkitRequestFileSystem')
  @DomName('Window.webkitRequestFileSystem')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @Experimental()
  // http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem
  Future<FileSystem> _requestFileSystem(int type, int size) {
    var completer = new Completer<FileSystem>();
    __requestFileSystem(type, size,
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  @JSName('webkitResolveLocalFileSystemURL')
  /**
   * Asynchronously retrieves a local filesystem entry.
   *
   * ## Other resources
   *
   * * [Obtaining access to file system entry points]
   * (http://www.w3.org/TR/file-system-api/#obtaining-access-to-file-system-entry-points)
   * from W3C.
   */
  @DomName('Window.webkitResolveLocalFileSystemURL')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @Experimental()
  // http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem
  void _resolveLocalFileSystemUrl(String url, _EntryCallback successCallback, [_ErrorCallback errorCallback]) native;

  @JSName('webkitResolveLocalFileSystemURL')
  /**
   * Asynchronously retrieves a local filesystem entry.
   *
   * ## Other resources
   *
   * * [Obtaining access to file system entry points]
   * (http://www.w3.org/TR/file-system-api/#obtaining-access-to-file-system-entry-points)
   * from W3C.
   */
  @DomName('Window.webkitResolveLocalFileSystemURL')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @Experimental()
  // http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem
  Future<Entry> resolveLocalFileSystemUrl(String url) {
    var completer = new Completer<Entry>();
    _resolveLocalFileSystemUrl(url,
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  // From WindowBase64

  @DomName('Window.atob')
  @DocsEditable()
  String atob(String string) native;

  @DomName('Window.btoa')
  @DocsEditable()
  String btoa(String string) native;

  // From WindowTimers

  @JSName('clearInterval')
  @DomName('Window.clearInterval')
  @DocsEditable()
  void _clearInterval(int handle) native;

  @JSName('clearTimeout')
  @DomName('Window.clearTimeout')
  @DocsEditable()
  void _clearTimeout(int handle) native;

  @JSName('setInterval')
  @DomName('Window.setInterval')
  @DocsEditable()
  int _setInterval(Object handler, int timeout) native;

  @JSName('setTimeout')
  @DomName('Window.setTimeout')
  @DocsEditable()
  int _setTimeout(Object handler, int timeout) native;

  /// Stream of `contentloaded` events handled by this [Window].
  @DomName('Window.onDOMContentLoaded')
  @DocsEditable()
  Stream<Event> get onContentLoaded => contentLoadedEvent.forTarget(this);

  /// Stream of `abort` events handled by this [Window].
  @DomName('Window.onabort')
  @DocsEditable()
  Stream<Event> get onAbort => Element.abortEvent.forTarget(this);

  /// Stream of `blur` events handled by this [Window].
  @DomName('Window.onblur')
  @DocsEditable()
  Stream<Event> get onBlur => Element.blurEvent.forTarget(this);

  /// Stream of `change` events handled by this [Window].
  @DomName('Window.onchange')
  @DocsEditable()
  Stream<Event> get onChange => Element.changeEvent.forTarget(this);

  /// Stream of `click` events handled by this [Window].
  @DomName('Window.onclick')
  @DocsEditable()
  Stream<MouseEvent> get onClick => Element.clickEvent.forTarget(this);

  /// Stream of `contextmenu` events handled by this [Window].
  @DomName('Window.oncontextmenu')
  @DocsEditable()
  Stream<MouseEvent> get onContextMenu => Element.contextMenuEvent.forTarget(this);

  /// Stream of `doubleclick` events handled by this [Window].
  @DomName('Window.ondblclick')
  @DocsEditable()
  Stream<Event> get onDoubleClick => Element.doubleClickEvent.forTarget(this);

  /// Stream of `devicemotion` events handled by this [Window].
  @DomName('Window.ondevicemotion')
  @DocsEditable()
  // http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
  @Experimental()
  Stream<DeviceMotionEvent> get onDeviceMotion => deviceMotionEvent.forTarget(this);

  /// Stream of `deviceorientation` events handled by this [Window].
  @DomName('Window.ondeviceorientation')
  @DocsEditable()
  // http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
  @Experimental()
  Stream<DeviceOrientationEvent> get onDeviceOrientation => deviceOrientationEvent.forTarget(this);

  /// Stream of `drag` events handled by this [Window].
  @DomName('Window.ondrag')
  @DocsEditable()
  Stream<MouseEvent> get onDrag => Element.dragEvent.forTarget(this);

  /// Stream of `dragend` events handled by this [Window].
  @DomName('Window.ondragend')
  @DocsEditable()
  Stream<MouseEvent> get onDragEnd => Element.dragEndEvent.forTarget(this);

  /// Stream of `dragenter` events handled by this [Window].
  @DomName('Window.ondragenter')
  @DocsEditable()
  Stream<MouseEvent> get onDragEnter => Element.dragEnterEvent.forTarget(this);

  /// Stream of `dragleave` events handled by this [Window].
  @DomName('Window.ondragleave')
  @DocsEditable()
  Stream<MouseEvent> get onDragLeave => Element.dragLeaveEvent.forTarget(this);

  /// Stream of `dragover` events handled by this [Window].
  @DomName('Window.ondragover')
  @DocsEditable()
  Stream<MouseEvent> get onDragOver => Element.dragOverEvent.forTarget(this);

  /// Stream of `dragstart` events handled by this [Window].
  @DomName('Window.ondragstart')
  @DocsEditable()
  Stream<MouseEvent> get onDragStart => Element.dragStartEvent.forTarget(this);

  /// Stream of `drop` events handled by this [Window].
  @DomName('Window.ondrop')
  @DocsEditable()
  Stream<MouseEvent> get onDrop => Element.dropEvent.forTarget(this);

  /// Stream of `error` events handled by this [Window].
  @DomName('Window.onerror')
  @DocsEditable()
  Stream<Event> get onError => Element.errorEvent.forTarget(this);

  /// Stream of `focus` events handled by this [Window].
  @DomName('Window.onfocus')
  @DocsEditable()
  Stream<Event> get onFocus => Element.focusEvent.forTarget(this);

  /// Stream of `hashchange` events handled by this [Window].
  @DomName('Window.onhashchange')
  @DocsEditable()
  Stream<Event> get onHashChange => hashChangeEvent.forTarget(this);

  /// Stream of `input` events handled by this [Window].
  @DomName('Window.oninput')
  @DocsEditable()
  Stream<Event> get onInput => Element.inputEvent.forTarget(this);

  /// Stream of `invalid` events handled by this [Window].
  @DomName('Window.oninvalid')
  @DocsEditable()
  Stream<Event> get onInvalid => Element.invalidEvent.forTarget(this);

  /// Stream of `keydown` events handled by this [Window].
  @DomName('Window.onkeydown')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyDown => Element.keyDownEvent.forTarget(this);

  /// Stream of `keypress` events handled by this [Window].
  @DomName('Window.onkeypress')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyPress => Element.keyPressEvent.forTarget(this);

  /// Stream of `keyup` events handled by this [Window].
  @DomName('Window.onkeyup')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyUp => Element.keyUpEvent.forTarget(this);

  /// Stream of `load` events handled by this [Window].
  @DomName('Window.onload')
  @DocsEditable()
  Stream<Event> get onLoad => Element.loadEvent.forTarget(this);

  /// Stream of `message` events handled by this [Window].
  @DomName('Window.onmessage')
  @DocsEditable()
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  /// Stream of `mousedown` events handled by this [Window].
  @DomName('Window.onmousedown')
  @DocsEditable()
  Stream<MouseEvent> get onMouseDown => Element.mouseDownEvent.forTarget(this);

  /// Stream of `mouseenter` events handled by this [Window].
  @DomName('Window.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseEnter => Element.mouseEnterEvent.forTarget(this);

  /// Stream of `mouseleave` events handled by this [Window].
  @DomName('Window.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseLeave => Element.mouseLeaveEvent.forTarget(this);

  /// Stream of `mousemove` events handled by this [Window].
  @DomName('Window.onmousemove')
  @DocsEditable()
  Stream<MouseEvent> get onMouseMove => Element.mouseMoveEvent.forTarget(this);

  /// Stream of `mouseout` events handled by this [Window].
  @DomName('Window.onmouseout')
  @DocsEditable()
  Stream<MouseEvent> get onMouseOut => Element.mouseOutEvent.forTarget(this);

  /// Stream of `mouseover` events handled by this [Window].
  @DomName('Window.onmouseover')
  @DocsEditable()
  Stream<MouseEvent> get onMouseOver => Element.mouseOverEvent.forTarget(this);

  /// Stream of `mouseup` events handled by this [Window].
  @DomName('Window.onmouseup')
  @DocsEditable()
  Stream<MouseEvent> get onMouseUp => Element.mouseUpEvent.forTarget(this);

  /// Stream of `mousewheel` events handled by this [Window].
  @DomName('Window.onmousewheel')
  @DocsEditable()
  Stream<WheelEvent> get onMouseWheel => Element.mouseWheelEvent.forTarget(this);

  /// Stream of `offline` events handled by this [Window].
  @DomName('Window.onoffline')
  @DocsEditable()
  Stream<Event> get onOffline => offlineEvent.forTarget(this);

  /// Stream of `online` events handled by this [Window].
  @DomName('Window.ononline')
  @DocsEditable()
  Stream<Event> get onOnline => onlineEvent.forTarget(this);

  /// Stream of `pagehide` events handled by this [Window].
  @DomName('Window.onpagehide')
  @DocsEditable()
  Stream<Event> get onPageHide => pageHideEvent.forTarget(this);

  /// Stream of `pageshow` events handled by this [Window].
  @DomName('Window.onpageshow')
  @DocsEditable()
  Stream<Event> get onPageShow => pageShowEvent.forTarget(this);

  /// Stream of `popstate` events handled by this [Window].
  @DomName('Window.onpopstate')
  @DocsEditable()
  Stream<PopStateEvent> get onPopState => popStateEvent.forTarget(this);

  /// Stream of `reset` events handled by this [Window].
  @DomName('Window.onreset')
  @DocsEditable()
  Stream<Event> get onReset => Element.resetEvent.forTarget(this);

  /// Stream of `resize` events handled by this [Window].
  @DomName('Window.onresize')
  @DocsEditable()
  Stream<Event> get onResize => Element.resizeEvent.forTarget(this);

  /// Stream of `scroll` events handled by this [Window].
  @DomName('Window.onscroll')
  @DocsEditable()
  Stream<Event> get onScroll => Element.scrollEvent.forTarget(this);

  /// Stream of `search` events handled by this [Window].
  @DomName('Window.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  Stream<Event> get onSearch => Element.searchEvent.forTarget(this);

  /// Stream of `select` events handled by this [Window].
  @DomName('Window.onselect')
  @DocsEditable()
  Stream<Event> get onSelect => Element.selectEvent.forTarget(this);

  /// Stream of `storage` events handled by this [Window].
  @DomName('Window.onstorage')
  @DocsEditable()
  Stream<StorageEvent> get onStorage => storageEvent.forTarget(this);

  /// Stream of `submit` events handled by this [Window].
  @DomName('Window.onsubmit')
  @DocsEditable()
  Stream<Event> get onSubmit => Element.submitEvent.forTarget(this);

  /// Stream of `touchcancel` events handled by this [Window].
  @DomName('Window.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchCancel => Element.touchCancelEvent.forTarget(this);

  /// Stream of `touchend` events handled by this [Window].
  @DomName('Window.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchEnd => Element.touchEndEvent.forTarget(this);

  /// Stream of `touchmove` events handled by this [Window].
  @DomName('Window.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchMove => Element.touchMoveEvent.forTarget(this);

  /// Stream of `touchstart` events handled by this [Window].
  @DomName('Window.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchStart => Element.touchStartEvent.forTarget(this);

  /// Stream of `transitionend` events handled by this [Window].
  @DomName('Window.ontransitionend')
  @DocsEditable()
  Stream<TransitionEvent> get onTransitionEnd => Element.transitionEndEvent.forTarget(this);

  /// Stream of `unload` events handled by this [Window].
  @DomName('Window.onunload')
  @DocsEditable()
  Stream<Event> get onUnload => unloadEvent.forTarget(this);

  /// Stream of `animationend` events handled by this [Window].
  @DomName('Window.onwebkitAnimationEnd')
  @DocsEditable()
  @Experimental()
  Stream<AnimationEvent> get onAnimationEnd => animationEndEvent.forTarget(this);

  /// Stream of `animationiteration` events handled by this [Window].
  @DomName('Window.onwebkitAnimationIteration')
  @DocsEditable()
  @Experimental()
  Stream<AnimationEvent> get onAnimationIteration => animationIterationEvent.forTarget(this);

  /// Stream of `animationstart` events handled by this [Window].
  @DomName('Window.onwebkitAnimationStart')
  @DocsEditable()
  @Experimental()
  Stream<AnimationEvent> get onAnimationStart => animationStartEvent.forTarget(this);


  /**
   * Static factory designed to expose `beforeunload` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.beforeunloadEvent')
  static const EventStreamProvider<BeforeUnloadEvent> beforeUnloadEvent =
      const _BeforeUnloadEventStreamProvider('beforeunload');

  /// Stream of `beforeunload` events handled by this [Window].
  @DomName('Window.onbeforeunload')
  Stream<Event> get onBeforeUnload => beforeUnloadEvent.forTarget(this);

  /**
   * Moves this window to a specific position.
   *
   * x and y can be negative.
   *
   * ## Other resources
   *
   * * [Window.moveTo]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.moveTo) from MDN.
   * * [Window.moveTo]
   * (http://dev.w3.org/csswg/cssom-view/#dom-window-moveto) from W3C.
   */
  void moveTo(Point p) {
    _moveTo(p.x, p.y);
  }

  /**
   * The distance this window has been scrolled horizontally.
   *
   * ## Other resources
   *
   * * [The Screen interface specification]
   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
   * * [scrollX]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX) from MDN.
   */
  int get scrollX => JS('bool', '("scrollX" in #)', this) ? JS('int',
      '#.scrollX', this) : document.documentElement.scrollLeft;

  /**
   * The distance this window has been scrolled vertically.
   *
   * ## Other resources
   *
   * * [The Screen interface specification]
   * (http://www.w3.org/TR/cssom-view/#screen) from W3C.
   * * [scrollY]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY) from MDN.
   */
  int get scrollY => JS('bool', '("scrollY" in #)', this) ? JS('int',
      '#.scrollY', this) : document.documentElement.scrollTop;
}

class _BeforeUnloadEvent extends _WrappedEvent implements BeforeUnloadEvent {
  String _returnValue;

  _BeforeUnloadEvent(Event base): super(base);

  String get returnValue => _returnValue;

  void set returnValue(String value) {
    _returnValue = value;
    // FF and IE use the value as the return value, Chrome will return this from
    // the event callback function.
    if (JS('bool', '("returnValue" in #)', wrapped)) {
      JS('void', '#.returnValue = #', wrapped, value);
    }
  }
}

class _BeforeUnloadEventStreamProvider implements
    EventStreamProvider<BeforeUnloadEvent> {
  final String _eventType;

  const _BeforeUnloadEventStreamProvider(this._eventType);

  Stream<BeforeUnloadEvent> forTarget(EventTarget e, {bool useCapture: false}) {
    var stream = new _EventStream(e, _eventType, useCapture);
    var controller = new StreamController(sync: true);

    stream.listen((event) {
      var wrapped = new _BeforeUnloadEvent(event);
      controller.add(wrapped);
      return wrapped.returnValue;
    });

    return controller.stream;
  }

  String getEventType(EventTarget target) {
    return _eventType;
  }

  ElementStream<BeforeUnloadEvent> forElement(Element e, {bool useCapture: false}) {
    return new _ElementEventStreamImpl(e, _eventType, useCapture);
  }

  ElementStream<BeforeUnloadEvent> _forElementList(ElementList e,
      {bool useCapture: false}) {
    return new _ElementListEventStreamImpl(e, _eventType, useCapture);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('WindowBase64')
@Experimental() // untriaged
abstract class WindowBase64 extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory WindowBase64._() { throw new UnsupportedError("Not supported"); }

  String atob(String string);

  String btoa(String string);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('WindowEventHandlers')
@Experimental() // untriaged
abstract class WindowEventHandlers extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory WindowEventHandlers._() { throw new UnsupportedError("Not supported"); }

  @DomName('WindowEventHandlers.hashchangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> hashChangeEvent = const EventStreamProvider<Event>('hashchange');

  @DomName('WindowEventHandlers.messageEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');

  @DomName('WindowEventHandlers.offlineEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> offlineEvent = const EventStreamProvider<Event>('offline');

  @DomName('WindowEventHandlers.onlineEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> onlineEvent = const EventStreamProvider<Event>('online');

  @DomName('WindowEventHandlers.popstateEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<PopStateEvent> popStateEvent = const EventStreamProvider<PopStateEvent>('popstate');

  @DomName('WindowEventHandlers.storageEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<StorageEvent> storageEvent = const EventStreamProvider<StorageEvent>('storage');

  @DomName('WindowEventHandlers.unloadEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> unloadEvent = const EventStreamProvider<Event>('unload');

  @DomName('WindowEventHandlers.onhashchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onHashChange => hashChangeEvent.forTarget(this);

  @DomName('WindowEventHandlers.onmessage')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  @DomName('WindowEventHandlers.onoffline')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onOffline => offlineEvent.forTarget(this);

  @DomName('WindowEventHandlers.ononline')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onOnline => onlineEvent.forTarget(this);

  @DomName('WindowEventHandlers.onpopstate')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<PopStateEvent> get onPopState => popStateEvent.forTarget(this);

  @DomName('WindowEventHandlers.onstorage')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<StorageEvent> get onStorage => storageEvent.forTarget(this);

  @DomName('WindowEventHandlers.onunload')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onUnload => unloadEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('Worker')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
// http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#worker
@Experimental() // stable
class Worker extends EventTarget implements AbstractWorker native "Worker" {
  // To suppress missing implicit constructor warnings.
  factory Worker._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [Worker].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Worker.errorEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [Worker].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Worker.messageEvent')
  @DocsEditable()
  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');

  @DomName('Worker.Worker')
  @DocsEditable()
  factory Worker(String scriptUrl) {
    return Worker._create_1(scriptUrl);
  }
  static Worker _create_1(scriptUrl) => JS('Worker', 'new Worker(#)', scriptUrl);

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '(typeof window.Worker != "undefined")');

  @DomName('Worker.postMessage')
  @DocsEditable()
  void postMessage(/*SerializedScriptValue*/ message, [List<MessagePort> messagePorts]) native;

  @DomName('Worker.terminate')
  @DocsEditable()
  void terminate() native;

  /// Stream of `error` events handled by this [Worker].
  @DomName('Worker.onerror')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `message` events handled by this [Worker].
  @DomName('Worker.onmessage')
  @DocsEditable()
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('WorkerConsole')
@Experimental() // untriaged
class WorkerConsole extends ConsoleBase native "WorkerConsole" {
  // To suppress missing implicit constructor warnings.
  factory WorkerConsole._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('WorkerCrypto')
@Experimental() // untriaged
class WorkerCrypto extends Interceptor native "WorkerCrypto" {
  // To suppress missing implicit constructor warnings.
  factory WorkerCrypto._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('WorkerGlobalScope')
@Experimental() // untriaged
class WorkerGlobalScope extends EventTarget implements _WindowTimers, WindowBase64 native "WorkerGlobalScope" {
  // To suppress missing implicit constructor warnings.
  factory WorkerGlobalScope._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [WorkerGlobalScope].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('WorkerGlobalScope.errorEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  @DomName('WorkerGlobalScope.PERSISTENT')
  @DocsEditable()
  @Experimental() // untriaged
  static const int PERSISTENT = 1;

  @DomName('WorkerGlobalScope.TEMPORARY')
  @DocsEditable()
  @Experimental() // untriaged
  static const int TEMPORARY = 0;

  @DomName('WorkerGlobalScope.console')
  @DocsEditable()
  @Experimental() // untriaged
  final WorkerConsole console;

  @DomName('WorkerGlobalScope.crypto')
  @DocsEditable()
  @Experimental() // untriaged
  final WorkerCrypto crypto;

  @DomName('WorkerGlobalScope.indexedDB')
  @DocsEditable()
  @Experimental() // untriaged
  final IdbFactory indexedDB;

  @DomName('WorkerGlobalScope.location')
  @DocsEditable()
  @Experimental() // untriaged
  final _WorkerLocation location;

  @DomName('WorkerGlobalScope.navigator')
  @DocsEditable()
  @Experimental() // untriaged
  final _WorkerNavigator navigator;

  @DomName('WorkerGlobalScope.performance')
  @DocsEditable()
  @Experimental() // untriaged
  final WorkerPerformance performance;

  @DomName('WorkerGlobalScope.self')
  @DocsEditable()
  @Experimental() // untriaged
  final WorkerGlobalScope self;

  @DomName('WorkerGlobalScope.close')
  @DocsEditable()
  @Experimental() // untriaged
  void close() native;

  @DomName('WorkerGlobalScope.openDatabase')
  @DocsEditable()
  @Experimental() // untriaged
  SqlDatabase openDatabase(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) native;

  @DomName('WorkerGlobalScope.openDatabaseSync')
  @DocsEditable()
  @Experimental() // untriaged
  _DatabaseSync openDatabaseSync(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) native;

  @JSName('webkitRequestFileSystem')
  @DomName('WorkerGlobalScope.webkitRequestFileSystem')
  @DocsEditable()
  @Experimental() // untriaged
  void _webkitRequestFileSystem(int type, int size, [_FileSystemCallback successCallback, _ErrorCallback errorCallback]) native;

  @JSName('webkitRequestFileSystem')
  @DomName('WorkerGlobalScope.webkitRequestFileSystem')
  @DocsEditable()
  @Experimental() // untriaged
  Future<FileSystem> webkitRequestFileSystem(int type, int size) {
    var completer = new Completer<FileSystem>();
    _webkitRequestFileSystem(type, size,
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  @JSName('webkitRequestFileSystemSync')
  @DomName('WorkerGlobalScope.webkitRequestFileSystemSync')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // untriaged
  _DOMFileSystemSync requestFileSystemSync(int type, int size) native;

  @JSName('webkitResolveLocalFileSystemSyncURL')
  @DomName('WorkerGlobalScope.webkitResolveLocalFileSystemSyncURL')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // untriaged
  _EntrySync resolveLocalFileSystemSyncUrl(String url) native;

  @JSName('webkitResolveLocalFileSystemURL')
  @DomName('WorkerGlobalScope.webkitResolveLocalFileSystemURL')
  @DocsEditable()
  @Experimental() // untriaged
  void _webkitResolveLocalFileSystemUrl(String url, _EntryCallback successCallback, [_ErrorCallback errorCallback]) native;

  @JSName('webkitResolveLocalFileSystemURL')
  @DomName('WorkerGlobalScope.webkitResolveLocalFileSystemURL')
  @DocsEditable()
  @Experimental() // untriaged
  Future<Entry> webkitResolveLocalFileSystemUrl(String url) {
    var completer = new Completer<Entry>();
    _webkitResolveLocalFileSystemUrl(url,
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  // From WindowBase64

  @DomName('WorkerGlobalScope.atob')
  @DocsEditable()
  @Experimental() // untriaged
  String atob(String string) native;

  @DomName('WorkerGlobalScope.btoa')
  @DocsEditable()
  @Experimental() // untriaged
  String btoa(String string) native;

  // From WindowTimers

  @JSName('clearInterval')
  @DomName('WorkerGlobalScope.clearInterval')
  @DocsEditable()
  @Experimental() // untriaged
  void _clearInterval(int handle) native;

  @JSName('clearTimeout')
  @DomName('WorkerGlobalScope.clearTimeout')
  @DocsEditable()
  @Experimental() // untriaged
  void _clearTimeout(int handle) native;

  @JSName('setInterval')
  @DomName('WorkerGlobalScope.setInterval')
  @DocsEditable()
  @Experimental() // untriaged
  int _setInterval(Object handler, int timeout) native;

  @JSName('setTimeout')
  @DomName('WorkerGlobalScope.setTimeout')
  @DocsEditable()
  @Experimental() // untriaged
  int _setTimeout(Object handler, int timeout) native;

  /// Stream of `error` events handled by this [WorkerGlobalScope].
  @DomName('WorkerGlobalScope.onerror')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onError => errorEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('WorkerPerformance')
@Experimental() // untriaged
class WorkerPerformance extends Interceptor native "WorkerPerformance" {
  // To suppress missing implicit constructor warnings.
  factory WorkerPerformance._() { throw new UnsupportedError("Not supported"); }

  @DomName('WorkerPerformance.now')
  @DocsEditable()
  @Experimental() // untriaged
  double now() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('XPathEvaluator')
// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathEvaluator
@deprecated // experimental
class XPathEvaluator extends Interceptor native "XPathEvaluator" {
  // To suppress missing implicit constructor warnings.
  factory XPathEvaluator._() { throw new UnsupportedError("Not supported"); }

  @DomName('XPathEvaluator.XPathEvaluator')
  @DocsEditable()
  factory XPathEvaluator() {
    return XPathEvaluator._create_1();
  }
  static XPathEvaluator _create_1() => JS('XPathEvaluator', 'new XPathEvaluator()');

  @DomName('XPathEvaluator.createExpression')
  @DocsEditable()
  XPathExpression createExpression(String expression, XPathNSResolver resolver) native;

  @DomName('XPathEvaluator.createNSResolver')
  @DocsEditable()
  XPathNSResolver createNSResolver(Node nodeResolver) native;

  @DomName('XPathEvaluator.evaluate')
  @DocsEditable()
  XPathResult evaluate(String expression, Node contextNode, XPathNSResolver resolver, int type, XPathResult inResult) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('XPathExpression')
// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathExpression
@deprecated // experimental
class XPathExpression extends Interceptor native "XPathExpression" {
  // To suppress missing implicit constructor warnings.
  factory XPathExpression._() { throw new UnsupportedError("Not supported"); }

  @DomName('XPathExpression.evaluate')
  @DocsEditable()
  XPathResult evaluate(Node contextNode, int type, XPathResult inResult) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('XPathNSResolver')
// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathNSResolver
@deprecated // experimental
class XPathNSResolver extends Interceptor native "XPathNSResolver" {
  // To suppress missing implicit constructor warnings.
  factory XPathNSResolver._() { throw new UnsupportedError("Not supported"); }

  @JSName('lookupNamespaceURI')
  @DomName('XPathNSResolver.lookupNamespaceURI')
  @DocsEditable()
  String lookupNamespaceUri(String prefix) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('XPathResult')
// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathResult
@deprecated // experimental
class XPathResult extends Interceptor native "XPathResult" {
  // To suppress missing implicit constructor warnings.
  factory XPathResult._() { throw new UnsupportedError("Not supported"); }

  @DomName('XPathResult.ANY_TYPE')
  @DocsEditable()
  static const int ANY_TYPE = 0;

  @DomName('XPathResult.ANY_UNORDERED_NODE_TYPE')
  @DocsEditable()
  static const int ANY_UNORDERED_NODE_TYPE = 8;

  @DomName('XPathResult.BOOLEAN_TYPE')
  @DocsEditable()
  static const int BOOLEAN_TYPE = 3;

  @DomName('XPathResult.FIRST_ORDERED_NODE_TYPE')
  @DocsEditable()
  static const int FIRST_ORDERED_NODE_TYPE = 9;

  @DomName('XPathResult.NUMBER_TYPE')
  @DocsEditable()
  static const int NUMBER_TYPE = 1;

  @DomName('XPathResult.ORDERED_NODE_ITERATOR_TYPE')
  @DocsEditable()
  static const int ORDERED_NODE_ITERATOR_TYPE = 5;

  @DomName('XPathResult.ORDERED_NODE_SNAPSHOT_TYPE')
  @DocsEditable()
  static const int ORDERED_NODE_SNAPSHOT_TYPE = 7;

  @DomName('XPathResult.STRING_TYPE')
  @DocsEditable()
  static const int STRING_TYPE = 2;

  @DomName('XPathResult.UNORDERED_NODE_ITERATOR_TYPE')
  @DocsEditable()
  static const int UNORDERED_NODE_ITERATOR_TYPE = 4;

  @DomName('XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE')
  @DocsEditable()
  static const int UNORDERED_NODE_SNAPSHOT_TYPE = 6;

  @DomName('XPathResult.booleanValue')
  @DocsEditable()
  final bool booleanValue;

  @DomName('XPathResult.invalidIteratorState')
  @DocsEditable()
  final bool invalidIteratorState;

  @DomName('XPathResult.numberValue')
  @DocsEditable()
  final double numberValue;

  @DomName('XPathResult.resultType')
  @DocsEditable()
  final int resultType;

  @DomName('XPathResult.singleNodeValue')
  @DocsEditable()
  final Node singleNodeValue;

  @DomName('XPathResult.snapshotLength')
  @DocsEditable()
  final int snapshotLength;

  @DomName('XPathResult.stringValue')
  @DocsEditable()
  final String stringValue;

  @DomName('XPathResult.iterateNext')
  @DocsEditable()
  Node iterateNext() native;

  @DomName('XPathResult.snapshotItem')
  @DocsEditable()
  Node snapshotItem(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('XMLDocument')
@Experimental() // untriaged
class XmlDocument extends Document native "XMLDocument" {
  // To suppress missing implicit constructor warnings.
  factory XmlDocument._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('XMLSerializer')
// http://domparsing.spec.whatwg.org/#the-xmlserializer-interface
@deprecated // stable
class XmlSerializer extends Interceptor native "XMLSerializer" {
  // To suppress missing implicit constructor warnings.
  factory XmlSerializer._() { throw new UnsupportedError("Not supported"); }

  @DomName('XMLSerializer.XMLSerializer')
  @DocsEditable()
  factory XmlSerializer() {
    return XmlSerializer._create_1();
  }
  static XmlSerializer _create_1() => JS('XmlSerializer', 'new XMLSerializer()');

  @DomName('XMLSerializer.serializeToString')
  @DocsEditable()
  String serializeToString(Node node) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('XSLTProcessor')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@deprecated // nonstandard
class XsltProcessor extends Interceptor native "XSLTProcessor" {
  // To suppress missing implicit constructor warnings.
  factory XsltProcessor._() { throw new UnsupportedError("Not supported"); }

  @DomName('XSLTProcessor.XSLTProcessor')
  @DocsEditable()
  factory XsltProcessor() {
    return XsltProcessor._create_1();
  }
  static XsltProcessor _create_1() => JS('XsltProcessor', 'new XSLTProcessor()');

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.XSLTProcessor)');

  @DomName('XSLTProcessor.clearParameters')
  @DocsEditable()
  void clearParameters() native;

  @DomName('XSLTProcessor.getParameter')
  @DocsEditable()
  String getParameter(String namespaceURI, String localName) native;

  @DomName('XSLTProcessor.importStylesheet')
  @DocsEditable()
  void importStylesheet(Node stylesheet) native;

  @DomName('XSLTProcessor.removeParameter')
  @DocsEditable()
  void removeParameter(String namespaceURI, String localName) native;

  @DomName('XSLTProcessor.reset')
  @DocsEditable()
  void reset() native;

  @DomName('XSLTProcessor.setParameter')
  @DocsEditable()
  void setParameter(String namespaceURI, String localName, String value) native;

  @DomName('XSLTProcessor.transformToDocument')
  @DocsEditable()
  Document transformToDocument(Node source) native;

  @DomName('XSLTProcessor.transformToFragment')
  @DocsEditable()
  DocumentFragment transformToFragment(Node source, Document docVal) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('Attr')
class _Attr extends Node native "Attr" {
  // To suppress missing implicit constructor warnings.
  factory _Attr._() { throw new UnsupportedError("Not supported"); }

  // Use implementation from Node.
  // final String _localName;

  @DomName('Attr.name')
  @DocsEditable()
  final String name;

  // Use implementation from Node.
  // final String _namespaceUri;

  @DomName('Attr.value')
  @DocsEditable()
  String value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('CSSPrimitiveValue')
// http://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface
@deprecated // deprecated
abstract class _CSSPrimitiveValue extends _CSSValue native "CSSPrimitiveValue" {
  // To suppress missing implicit constructor warnings.
  factory _CSSPrimitiveValue._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('CSSUnknownRule')
// http://dev.w3.org/csswg/cssom/#the-cssstylesheet-interface
@deprecated // deprecated
abstract class _CSSUnknownRule extends CssRule native "CSSUnknownRule" {
  // To suppress missing implicit constructor warnings.
  factory _CSSUnknownRule._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('CSSValue')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
abstract class _CSSValue extends Interceptor native "CSSValue" {
  // To suppress missing implicit constructor warnings.
  factory _CSSValue._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('ClientRect')
class _ClientRect extends Interceptor implements Rectangle native "ClientRect,DOMRect" {

  // NOTE! All code below should be common with RectangleBase.
   String toString() {
    return 'Rectangle ($left, $top) $width x $height';
  }

  bool operator ==(other) {
    if (other is !Rectangle) return false;
    return left == other.left && top == other.top && width == other.width &&
        height == other.height;
  }

  int get hashCode => _JenkinsSmiHash.hash4(left.hashCode, top.hashCode,
      width.hashCode, height.hashCode);

  /**
   * Computes the intersection of `this` and [other].
   *
   * The intersection of two axis-aligned rectangles, if any, is always another
   * axis-aligned rectangle.
   *
   * Returns the intersection of this and `other`, or null if they don't
   * intersect.
   */
  Rectangle intersection(Rectangle other) {
    var x0 = max(left, other.left);
    var x1 = min(left + width, other.left + other.width);

    if (x0 <= x1) {
      var y0 = max(top, other.top);
      var y1 = min(top + height, other.top + other.height);

      if (y0 <= y1) {
        return new Rectangle(x0, y0, x1 - x0, y1 - y0);
      }
    }
    return null;
  }


  /**
   * Returns true if `this` intersects [other].
   */
  bool intersects(Rectangle<num> other) {
    return (left <= other.left + other.width &&
        other.left <= left + width &&
        top <= other.top + other.height &&
        other.top <= top + height);
  }

  /**
   * Returns a new rectangle which completely contains `this` and [other].
   */
  Rectangle boundingBox(Rectangle other) {
    var right = max(this.left + this.width, other.left + other.width);
    var bottom = max(this.top + this.height, other.top + other.height);

    var left = min(this.left, other.left);
    var top = min(this.top, other.top);

    return new Rectangle(left, top, right - left, bottom - top);
  }

  /**
   * Tests whether `this` entirely contains [another].
   */
  bool containsRectangle(Rectangle<num> another) {
    return left <= another.left &&
           left + width >= another.left + another.width &&
           top <= another.top &&
           top + height >= another.top + another.height;
  }

  /**
   * Tests whether [another] is inside or along the edges of `this`.
   */
  bool containsPoint(Point<num> another) {
    return another.x >= left &&
           another.x <= left + width &&
           another.y >= top &&
           another.y <= top + height;
  }

  Point get topLeft => new Point(this.left, this.top);
  Point get topRight => new Point(this.left + this.width, this.top);
  Point get bottomRight => new Point(this.left + this.width,
      this.top + this.height);
  Point get bottomLeft => new Point(this.left,
      this.top + this.height);

    // To suppress missing implicit constructor warnings.
  factory _ClientRect._() { throw new UnsupportedError("Not supported"); }

  @DomName('ClientRect.bottom')
  @DocsEditable()
  final double bottom;

  @DomName('ClientRect.height')
  @DocsEditable()
  final double height;

  @DomName('ClientRect.left')
  @DocsEditable()
  final double left;

  @DomName('ClientRect.right')
  @DocsEditable()
  final double right;

  @DomName('ClientRect.top')
  @DocsEditable()
  final double top;

  @DomName('ClientRect.width')
  @DocsEditable()
  final double width;
}

/**
 * This is the [Jenkins hash function][1] but using masking to keep
 * values in SMI range.
 *
 * [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function
 *
 * Use:
 * Hash each value with the hash of the previous value, then get the final
 * hash by calling finish.
 *
 *     var hash = 0;
 *     for (var value in values) {
 *       hash = JenkinsSmiHash.combine(hash, value.hashCode);
 *     }
 *     hash = JenkinsSmiHash.finish(hash);
 */
class _JenkinsSmiHash {
  // TODO(11617): This class should be optimized and standardized elsewhere.

  static int combine(int hash, int value) {
    hash = 0x1fffffff & (hash + value);
    hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
    return hash ^ (hash >> 6);
  }

  static int finish(int hash) {
    hash = 0x1fffffff & (hash + ((0x03ffffff & hash) <<  3));
    hash = hash ^ (hash >> 11);
    return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
  }

  static int hash2(a, b) => finish(combine(combine(0, a), b));

  static int hash4(a, b, c, d) =>
      finish(combine(combine(combine(combine(0, a), b), c), d));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('ClientRectList')
class _ClientRectList extends Interceptor with ListMixin<Rectangle>, ImmutableListMixin<Rectangle> implements List<Rectangle>, JavaScriptIndexingBehavior native "ClientRectList" {
  // To suppress missing implicit constructor warnings.
  factory _ClientRectList._() { throw new UnsupportedError("Not supported"); }

  @DomName('ClientRectList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  Rectangle operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("Rectangle", "#[#]", this, index);
  }
  void operator[]=(int index, Rectangle value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Rectangle> mixins.
  // Rectangle is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Rectangle get first {
    if (this.length > 0) {
      return JS('Rectangle', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Rectangle get last {
    int len = this.length;
    if (len > 0) {
      return JS('Rectangle', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Rectangle get single {
    int len = this.length;
    if (len == 1) {
      return JS('Rectangle', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Rectangle elementAt(int index) => this[index];
  // -- end List<Rectangle> mixins.

  @DomName('ClientRectList.item')
  @DocsEditable()
  Rectangle item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('Counter')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
abstract class _Counter extends Interceptor native "Counter" {
  // To suppress missing implicit constructor warnings.
  factory _Counter._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('CSSRuleList')
class _CssRuleList extends Interceptor with ListMixin<CssRule>, ImmutableListMixin<CssRule> implements JavaScriptIndexingBehavior, List<CssRule> native "CSSRuleList" {
  // To suppress missing implicit constructor warnings.
  factory _CssRuleList._() { throw new UnsupportedError("Not supported"); }

  @DomName('CSSRuleList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  CssRule operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("CssRule", "#[#]", this, index);
  }
  void operator[]=(int index, CssRule value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<CssRule> mixins.
  // CssRule is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  CssRule get first {
    if (this.length > 0) {
      return JS('CssRule', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  CssRule get last {
    int len = this.length;
    if (len > 0) {
      return JS('CssRule', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  CssRule get single {
    int len = this.length;
    if (len == 1) {
      return JS('CssRule', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  CssRule elementAt(int index) => this[index];
  // -- end List<CssRule> mixins.

  @DomName('CSSRuleList.item')
  @DocsEditable()
  CssRule item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('CSSValueList')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
class _CssValueList extends _CSSValue with ListMixin<_CSSValue>, ImmutableListMixin<_CSSValue> implements JavaScriptIndexingBehavior, List<_CSSValue> native "CSSValueList" {
  // To suppress missing implicit constructor warnings.
  factory _CssValueList._() { throw new UnsupportedError("Not supported"); }

  @DomName('CSSValueList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  _CSSValue operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("_CSSValue", "#[#]", this, index);
  }
  void operator[]=(int index, _CSSValue value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<_CSSValue> mixins.
  // _CSSValue is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  _CSSValue get first {
    if (this.length > 0) {
      return JS('_CSSValue', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  _CSSValue get last {
    int len = this.length;
    if (len > 0) {
      return JS('_CSSValue', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  _CSSValue get single {
    int len = this.length;
    if (len == 1) {
      return JS('_CSSValue', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  _CSSValue elementAt(int index) => this[index];
  // -- end List<_CSSValue> mixins.

  @DomName('CSSValueList.item')
  @DocsEditable()
  _CSSValue item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('DOMFileSystemSync')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://www.w3.org/TR/file-system-api/#the-filesystemsync-interface
abstract class _DOMFileSystemSync extends Interceptor native "DOMFileSystemSync" {
  // To suppress missing implicit constructor warnings.
  factory _DOMFileSystemSync._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('DatabaseSync')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
// http://www.w3.org/TR/webdatabase/#databasesync
@deprecated // deprecated
abstract class _DatabaseSync extends Interceptor native "DatabaseSync" {
  // To suppress missing implicit constructor warnings.
  factory _DatabaseSync._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('DirectoryEntrySync')
// http://www.w3.org/TR/file-system-api/#the-directoryentrysync-interface
@Experimental()
abstract class _DirectoryEntrySync extends _EntrySync native "DirectoryEntrySync" {
  // To suppress missing implicit constructor warnings.
  factory _DirectoryEntrySync._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('DirectoryReaderSync')
// http://www.w3.org/TR/file-system-api/#idl-def-DirectoryReaderSync
@Experimental()
abstract class _DirectoryReaderSync extends Interceptor native "DirectoryReaderSync" {
  // To suppress missing implicit constructor warnings.
  factory _DirectoryReaderSync._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('DocumentType')
// http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-412266927
@deprecated // stable
abstract class _DocumentType extends Node implements ChildNode native "DocumentType" {
  // To suppress missing implicit constructor warnings.
  factory _DocumentType._() { throw new UnsupportedError("Not supported"); }

  // From ChildNode
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('WebKitPoint')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
// http://developer.apple.com/library/safari/#documentation/DataManagement/Reference/DOMWindowAdditionsReference/DOMWindowAdditions/DOMWindowAdditions.html
@Experimental() // non-standard
class _DomPoint extends Interceptor native "WebKitPoint" {
  // To suppress missing implicit constructor warnings.
  factory _DomPoint._() { throw new UnsupportedError("Not supported"); }

  @DomName('WebKitPoint.WebKitPoint')
  @DocsEditable()
  factory _DomPoint(num x, num y) {
    return _DomPoint._create_1(x, y);
  }
  static _DomPoint _create_1(x, y) => JS('_DomPoint', 'new WebKitPoint(#,#)', x, y);

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.WebKitPoint)');

  @DomName('WebKitPoint.x')
  @DocsEditable()
  num x;

  @DomName('WebKitPoint.y')
  @DocsEditable()
  num y;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('EntrySync')
// http://www.w3.org/TR/file-system-api/#idl-def-EntrySync
@Experimental()
abstract class _EntrySync extends Interceptor native "EntrySync" {
  // To suppress missing implicit constructor warnings.
  factory _EntrySync._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('FileEntrySync')
// http://www.w3.org/TR/file-system-api/#the-fileentrysync-interface
@Experimental()
abstract class _FileEntrySync extends _EntrySync native "FileEntrySync" {
  // To suppress missing implicit constructor warnings.
  factory _FileEntrySync._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('FileReaderSync')
// http://www.w3.org/TR/FileAPI/#FileReaderSync
@Experimental()
abstract class _FileReaderSync extends Interceptor native "FileReaderSync" {
  // To suppress missing implicit constructor warnings.
  factory _FileReaderSync._() { throw new UnsupportedError("Not supported"); }

  @DomName('FileReaderSync.FileReaderSync')
  @DocsEditable()
  factory _FileReaderSync() {
    return _FileReaderSync._create_1();
  }
  static _FileReaderSync _create_1() => JS('_FileReaderSync', 'new FileReaderSync()');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('FileWriterSync')
// http://www.w3.org/TR/file-writer-api/#idl-def-FileWriterSync
@Experimental()
abstract class _FileWriterSync extends Interceptor native "FileWriterSync" {
  // To suppress missing implicit constructor warnings.
  factory _FileWriterSync._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('GamepadList')
// https://dvcs.w3.org/hg/gamepad/raw-file/default/gamepad.html
@Experimental()
class _GamepadList extends Interceptor with ListMixin<Gamepad>, ImmutableListMixin<Gamepad> implements JavaScriptIndexingBehavior, List<Gamepad> native "GamepadList" {
  // To suppress missing implicit constructor warnings.
  factory _GamepadList._() { throw new UnsupportedError("Not supported"); }

  @DomName('GamepadList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  Gamepad operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("Gamepad", "#[#]", this, index);
  }
  void operator[]=(int index, Gamepad value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Gamepad> mixins.
  // Gamepad is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Gamepad get first {
    if (this.length > 0) {
      return JS('Gamepad', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Gamepad get last {
    int len = this.length;
    if (len > 0) {
      return JS('Gamepad', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Gamepad get single {
    int len = this.length;
    if (len == 1) {
      return JS('Gamepad', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Gamepad elementAt(int index) => this[index];
  // -- end List<Gamepad> mixins.

  @DomName('GamepadList.item')
  @DocsEditable()
  Gamepad item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLAllCollection')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#dom-document-all
@deprecated // deprecated
abstract class _HTMLAllCollection extends Interceptor native "HTMLAllCollection" {
  // To suppress missing implicit constructor warnings.
  factory _HTMLAllCollection._() { throw new UnsupportedError("Not supported"); }

  @JSName('item')
  @DomName('HTMLAllCollection.item')
  @DocsEditable()
  Element _item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLAppletElement')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#the-applet-element
@deprecated // deprecated
abstract class _HTMLAppletElement extends HtmlElement native "HTMLAppletElement" {
  // To suppress missing implicit constructor warnings.
  factory _HTMLAppletElement._() { throw new UnsupportedError("Not supported"); }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLAppletElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLDirectoryElement')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#dir
@deprecated // deprecated
abstract class _HTMLDirectoryElement extends HtmlElement native "HTMLDirectoryElement" {
  // To suppress missing implicit constructor warnings.
  factory _HTMLDirectoryElement._() { throw new UnsupportedError("Not supported"); }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLDirectoryElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLFontElement')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#htmlfontelement
@deprecated // deprecated
abstract class _HTMLFontElement extends HtmlElement native "HTMLFontElement" {
  // To suppress missing implicit constructor warnings.
  factory _HTMLFontElement._() { throw new UnsupportedError("Not supported"); }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLFontElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLFrameElement')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#htmlframeelement
@deprecated // deprecated
abstract class _HTMLFrameElement extends HtmlElement native "HTMLFrameElement" {
  // To suppress missing implicit constructor warnings.
  factory _HTMLFrameElement._() { throw new UnsupportedError("Not supported"); }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLFrameElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLFrameSetElement')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#frameset
@deprecated // deprecated
abstract class _HTMLFrameSetElement extends HtmlElement implements WindowEventHandlers native "HTMLFrameSetElement" {
  // To suppress missing implicit constructor warnings.
  factory _HTMLFrameSetElement._() { throw new UnsupportedError("Not supported"); }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLFrameSetElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLMarqueeElement')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#the-marquee-element
@deprecated // deprecated
abstract class _HTMLMarqueeElement extends HtmlElement native "HTMLMarqueeElement" {
  // To suppress missing implicit constructor warnings.
  factory _HTMLMarqueeElement._() { throw new UnsupportedError("Not supported"); }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLMarqueeElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('MutationEvent')
// http://www.w3.org/TR/DOM-Level-3-Events/#events-mutationevents
@deprecated
abstract class _MutationEvent extends Event native "MutationEvent" {
  factory _MutationEvent(String type,
      {bool canBubble: false, bool cancelable: false, Node relatedNode,
      String prevValue, String newValue, String attrName, int attrChange: 0}) {

    var event = document._createEvent('MutationEvent');
    event._initMutationEvent(type, canBubble, cancelable, relatedNode,
        prevValue, newValue, attrName, attrChange);
    return event;
  }
  // To suppress missing implicit constructor warnings.
  factory _MutationEvent._() { throw new UnsupportedError("Not supported"); }

}



// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('NamedNodeMap')
// http://dom.spec.whatwg.org/#namednodemap
@deprecated // deprecated
class _NamedNodeMap extends Interceptor with ListMixin<Node>, ImmutableListMixin<Node> implements JavaScriptIndexingBehavior, List<Node> native "NamedNodeMap,MozNamedAttrMap" {
  // To suppress missing implicit constructor warnings.
  factory _NamedNodeMap._() { throw new UnsupportedError("Not supported"); }

  @DomName('NamedNodeMap.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  Node operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("Node", "#[#]", this, index);
  }
  void operator[]=(int index, Node value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Node> mixins.
  // Node is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Node get first {
    if (this.length > 0) {
      return JS('Node', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Node get last {
    int len = this.length;
    if (len > 0) {
      return JS('Node', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Node get single {
    int len = this.length;
    if (len == 1) {
      return JS('Node', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Node elementAt(int index) => this[index];
  // -- end List<Node> mixins.

  @DomName('NamedNodeMap.__getter__')
  @DocsEditable()
  Node __getter__(String name) native;

  @DomName('NamedNodeMap.getNamedItem')
  @DocsEditable()
  Node getNamedItem(String name) native;

  @DomName('NamedNodeMap.getNamedItemNS')
  @DocsEditable()
  Node getNamedItemNS(String namespaceURI, String localName) native;

  @DomName('NamedNodeMap.item')
  @DocsEditable()
  Node item(int index) native;

  @DomName('NamedNodeMap.removeNamedItem')
  @DocsEditable()
  Node removeNamedItem(String name) native;

  @DomName('NamedNodeMap.removeNamedItemNS')
  @DocsEditable()
  Node removeNamedItemNS(String namespaceURI, String localName) native;

  @DomName('NamedNodeMap.setNamedItem')
  @DocsEditable()
  Node setNamedItem(Node node) native;

  @DomName('NamedNodeMap.setNamedItemNS')
  @DocsEditable()
  Node setNamedItemNS(Node node) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('Notation')
// http://dom.spec.whatwg.org/#notation
@deprecated // deprecated
abstract class _Notation extends Node native "Notation" {
  // To suppress missing implicit constructor warnings.
  factory _Notation._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('NotificationCenter')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
// http://www.w3.org/TR/notifications/#showing-a-notification
@deprecated // deprecated
abstract class _NotificationCenter extends Interceptor native "NotificationCenter" {
  // To suppress missing implicit constructor warnings.
  factory _NotificationCenter._() { throw new UnsupportedError("Not supported"); }

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.webkitNotifications)');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('PagePopupController')
@deprecated // nonstandard
abstract class _PagePopupController extends Interceptor native "PagePopupController" {
  // To suppress missing implicit constructor warnings.
  factory _PagePopupController._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('RGBColor')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
abstract class _RGBColor extends Interceptor native "RGBColor" {
  // To suppress missing implicit constructor warnings.
  factory _RGBColor._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


// Omit RadioNodeList for dart2js.  The Dart Form and FieldSet APIs don't
// currently expose an API the returns RadioNodeList.  The only use of a
// RadioNodeList is to get the selected value and it will be cleaner to
// introduce a different API for that purpose.
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('Rect')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
abstract class _Rect extends Interceptor native "Rect" {
  // To suppress missing implicit constructor warnings.
  factory _Rect._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('ServiceWorker')
@Experimental() // untriaged
abstract class _ServiceWorker extends Interceptor native "ServiceWorker" {
  // To suppress missing implicit constructor warnings.
  factory _ServiceWorker._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('SpeechInputResultList')
// http://lists.w3.org/Archives/Public/public-xg-htmlspeech/2011Feb/att-0020/api-draft.html#speech_input_result_list_interface
@Experimental()
class _SpeechInputResultList extends Interceptor with ListMixin<SpeechInputResult>, ImmutableListMixin<SpeechInputResult> implements JavaScriptIndexingBehavior, List<SpeechInputResult> native "SpeechInputResultList" {
  // To suppress missing implicit constructor warnings.
  factory _SpeechInputResultList._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechInputResultList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  SpeechInputResult operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("SpeechInputResult", "#[#]", this, index);
  }
  void operator[]=(int index, SpeechInputResult value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<SpeechInputResult> mixins.
  // SpeechInputResult is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  SpeechInputResult get first {
    if (this.length > 0) {
      return JS('SpeechInputResult', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  SpeechInputResult get last {
    int len = this.length;
    if (len > 0) {
      return JS('SpeechInputResult', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  SpeechInputResult get single {
    int len = this.length;
    if (len == 1) {
      return JS('SpeechInputResult', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  SpeechInputResult elementAt(int index) => this[index];
  // -- end List<SpeechInputResult> mixins.

  @DomName('SpeechInputResultList.item')
  @DocsEditable()
  SpeechInputResult item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('SpeechRecognitionResultList')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechrecognitionresultlist
@Experimental()
class _SpeechRecognitionResultList extends Interceptor with ListMixin<SpeechRecognitionResult>, ImmutableListMixin<SpeechRecognitionResult> implements JavaScriptIndexingBehavior, List<SpeechRecognitionResult> native "SpeechRecognitionResultList" {
  // To suppress missing implicit constructor warnings.
  factory _SpeechRecognitionResultList._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechRecognitionResultList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  SpeechRecognitionResult operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("SpeechRecognitionResult", "#[#]", this, index);
  }
  void operator[]=(int index, SpeechRecognitionResult value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<SpeechRecognitionResult> mixins.
  // SpeechRecognitionResult is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  SpeechRecognitionResult get first {
    if (this.length > 0) {
      return JS('SpeechRecognitionResult', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  SpeechRecognitionResult get last {
    int len = this.length;
    if (len > 0) {
      return JS('SpeechRecognitionResult', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  SpeechRecognitionResult get single {
    int len = this.length;
    if (len == 1) {
      return JS('SpeechRecognitionResult', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  SpeechRecognitionResult elementAt(int index) => this[index];
  // -- end List<SpeechRecognitionResult> mixins.

  @DomName('SpeechRecognitionResultList.item')
  @DocsEditable()
  SpeechRecognitionResult item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('StyleSheetList')
class _StyleSheetList extends Interceptor with ListMixin<StyleSheet>, ImmutableListMixin<StyleSheet> implements JavaScriptIndexingBehavior, List<StyleSheet> native "StyleSheetList" {
  // To suppress missing implicit constructor warnings.
  factory _StyleSheetList._() { throw new UnsupportedError("Not supported"); }

  @DomName('StyleSheetList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  StyleSheet operator[](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index,
        index, index, length))
      throw new RangeError.range(index, 0, length);
    return JS("StyleSheet", "#[#]", this, index);
  }
  void operator[]=(int index, StyleSheet value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<StyleSheet> mixins.
  // StyleSheet is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  StyleSheet get first {
    if (this.length > 0) {
      return JS('StyleSheet', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  StyleSheet get last {
    int len = this.length;
    if (len > 0) {
      return JS('StyleSheet', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  StyleSheet get single {
    int len = this.length;
    if (len == 1) {
      return JS('StyleSheet', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  StyleSheet elementAt(int index) => this[index];
  // -- end List<StyleSheet> mixins.

  @DomName('StyleSheetList.__getter__')
  @DocsEditable()
  CssStyleSheet __getter__(String name) native;

  @DomName('StyleSheetList.item')
  @DocsEditable()
  StyleSheet item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('SubtleCrypto')
@Experimental() // untriaged
abstract class _SubtleCrypto extends Interceptor native "SubtleCrypto" {
  // To suppress missing implicit constructor warnings.
  factory _SubtleCrypto._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('WebKitCSSFilterValue')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
abstract class _WebKitCSSFilterValue extends _CssValueList native "WebKitCSSFilterValue" {
  // To suppress missing implicit constructor warnings.
  factory _WebKitCSSFilterValue._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('WebKitCSSMatrix')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
abstract class _WebKitCSSMatrix extends Interceptor native "WebKitCSSMatrix" {
  // To suppress missing implicit constructor warnings.
  factory _WebKitCSSMatrix._() { throw new UnsupportedError("Not supported"); }

  @DomName('WebKitCSSMatrix.WebKitCSSMatrix')
  @DocsEditable()
  factory _WebKitCSSMatrix([String cssValue]) {
    if (cssValue != null) {
      return _WebKitCSSMatrix._create_1(cssValue);
    }
    return _WebKitCSSMatrix._create_2();
  }
  static _WebKitCSSMatrix _create_1(cssValue) => JS('_WebKitCSSMatrix', 'new WebKitCSSMatrix(#)', cssValue);
  static _WebKitCSSMatrix _create_2() => JS('_WebKitCSSMatrix', 'new WebKitCSSMatrix()');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('WebKitCSSTransformValue')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
abstract class _WebKitCSSTransformValue extends _CssValueList native "WebKitCSSTransformValue" {
  // To suppress missing implicit constructor warnings.
  factory _WebKitCSSTransformValue._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('WebKitMediaSource')
@Experimental() // untriaged
abstract class _WebKitMediaSource extends EventTarget native "WebKitMediaSource" {
  // To suppress missing implicit constructor warnings.
  factory _WebKitMediaSource._() { throw new UnsupportedError("Not supported"); }

  @DomName('WebKitMediaSource.WebKitMediaSource')
  @DocsEditable()
  factory _WebKitMediaSource() {
    return _WebKitMediaSource._create_1();
  }
  static _WebKitMediaSource _create_1() => JS('_WebKitMediaSource', 'new WebKitMediaSource()');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('WebKitNotification')
@Experimental() // untriaged
abstract class _WebKitNotification extends EventTarget native "WebKitNotification" {
  // To suppress missing implicit constructor warnings.
  factory _WebKitNotification._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('WebKitSourceBuffer')
@Experimental() // untriaged
abstract class _WebKitSourceBuffer extends Interceptor native "WebKitSourceBuffer" {
  // To suppress missing implicit constructor warnings.
  factory _WebKitSourceBuffer._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('WebKitSourceBufferList')
@Experimental() // untriaged
abstract class _WebKitSourceBufferList extends EventTarget native "WebKitSourceBufferList" {
  // To suppress missing implicit constructor warnings.
  factory _WebKitSourceBufferList._() { throw new UnsupportedError("Not supported"); }

  @JSName('item')
  @DomName('WebKitSourceBufferList.item')
  @DocsEditable()
  @Experimental() // untriaged
  _WebKitSourceBuffer _item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('WindowTimers')
@Experimental() // untriaged
abstract class _WindowTimers extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _WindowTimers._() { throw new UnsupportedError("Not supported"); }

  void _clearInterval(int handle);

  void _clearTimeout(int handle);

  int _setInterval(Object handler, int timeout);

  int _setTimeout(Object handler, int timeout);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('WorkerLocation')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#workerlocation
@Experimental()
abstract class _WorkerLocation extends Interceptor implements UrlUtilsReadOnly native "WorkerLocation" {
  // To suppress missing implicit constructor warnings.
  factory _WorkerLocation._() { throw new UnsupportedError("Not supported"); }

  // From URLUtilsReadOnly
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('WorkerNavigator')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#workernavigator
@Experimental()
abstract class _WorkerNavigator extends Interceptor implements NavigatorOnLine, NavigatorID native "WorkerNavigator" {
  // To suppress missing implicit constructor warnings.
  factory _WorkerNavigator._() { throw new UnsupportedError("Not supported"); }

  // From NavigatorID

  // From NavigatorOnLine
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('XMLHttpRequestProgressEvent')
@Experimental() // nonstandard
abstract class _XMLHttpRequestProgressEvent extends ProgressEvent native "XMLHttpRequestProgressEvent" {
  // To suppress missing implicit constructor warnings.
  factory _XMLHttpRequestProgressEvent._() { throw new UnsupportedError("Not supported"); }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


abstract class _AttributeMap implements Map<String, String> {
  final Element _element;

  _AttributeMap(this._element);

  void addAll(Map<String, String> other) {
    other.forEach((k, v) { this[k] = v; });
  }

  bool containsValue(String value) {
    for (var v in this.values) {
      if (value == v) {
        return true;
      }
    }
    return false;
  }

  String putIfAbsent(String key, String ifAbsent()) {
    if (!containsKey(key)) {
      this[key] = ifAbsent();
    }
    return this[key];
  }

  void clear() {
    for (var key in keys) {
      remove(key);
    }
  }

  void forEach(void f(String key, String value)) {
    for (var key in keys) {
      var value = this[key];
      f(key, value);
    }
  }

  Iterable<String> get keys {
    // TODO: generate a lazy collection instead.
    var attributes = _element._attributes;
    var keys = new List<String>();
    for (int i = 0, len = attributes.length; i < len; i++) {
      if (_matches(attributes[i])) {
        keys.add(attributes[i].name);
      }
    }
    return keys;
  }

  Iterable<String> get values {
    // TODO: generate a lazy collection instead.
    var attributes = _element._attributes;
    var values = new List<String>();
    for (int i = 0, len = attributes.length; i < len; i++) {
      if (_matches(attributes[i])) {
        values.add(attributes[i].value);
      }
    }
    return values;
  }

  /**
   * Returns true if there is no {key, value} pair in the map.
   */
  bool get isEmpty {
    return length == 0;
  }

  /**
   * Returns true if there is at least one {key, value} pair in the map.
   */
  bool get isNotEmpty => !isEmpty;

  /**
   * Checks to see if the node should be included in this map.
   */
  bool _matches(Node node);
}

/**
 * Wrapper to expose [Element.attributes] as a typed map.
 */
class _ElementAttributeMap extends _AttributeMap {

  _ElementAttributeMap(Element element): super(element);

  bool containsKey(String key) {
    return _element._hasAttribute(key);
  }

  String operator [](String key) {
    return _element.getAttribute(key);
  }

  void operator []=(String key, String value) {
    _element.setAttribute(key, value);
  }

  String remove(String key) {
    String value = _element.getAttribute(key);
    _element._removeAttribute(key);
    return value;
  }

  /**
   * The number of {key, value} pairs in the map.
   */
  int get length {
    return keys.length;
  }

  bool _matches(Node node) => node._namespaceUri == null;
}

/**
 * Wrapper to expose namespaced attributes as a typed map.
 */
class _NamespacedAttributeMap extends _AttributeMap {

  final String _namespace;

  _NamespacedAttributeMap(Element element, this._namespace): super(element);

  bool containsKey(String key) {
    return _element._hasAttributeNS(_namespace, key);
  }

  String operator [](String key) {
    return _element.getAttributeNS(_namespace, key);
  }

  void operator []=(String key, String value) {
    _element.setAttributeNS(_namespace, key, value);
  }

  String remove(String key) {
    String value = this[key];
    _element._removeAttributeNS(_namespace, key);
    return value;
  }

  /**
   * The number of {key, value} pairs in the map.
   */
  int get length {
    return keys.length;
  }

  bool _matches(Node node) => node._namespaceUri == _namespace;
}


/**
 * Provides a Map abstraction on top of data-* attributes, similar to the
 * dataSet in the old DOM.
 */
class _DataAttributeMap implements Map<String, String> {

  final Map<String, String> _attributes;

  _DataAttributeMap(this._attributes);

  // interface Map

  void addAll(Map<String, String> other) {
    other.forEach((k, v) { this[k] = v; });
  }

  // TODO: Use lazy iterator when it is available on Map.
  bool containsValue(String value) => values.any((v) => v == value);

  bool containsKey(String key) => _attributes.containsKey(_attr(key));

  String operator [](String key) => _attributes[_attr(key)];

  void operator []=(String key, String value) {
    _attributes[_attr(key)] = value;
  }

  String putIfAbsent(String key, String ifAbsent()) =>
    _attributes.putIfAbsent(_attr(key), ifAbsent);

  String remove(String key) => _attributes.remove(_attr(key));

  void clear() {
    // Needs to operate on a snapshot since we are mutating the collection.
    for (String key in keys) {
      remove(key);
    }
  }

  void forEach(void f(String key, String value)) {
    _attributes.forEach((String key, String value) {
      if (_matches(key)) {
        f(_strip(key), value);
      }
    });
  }

  Iterable<String> get keys {
    final keys = new List<String>();
    _attributes.forEach((String key, String value) {
      if (_matches(key)) {
        keys.add(_strip(key));
      }
    });
    return keys;
  }

  Iterable<String> get values {
    final values = new List<String>();
    _attributes.forEach((String key, String value) {
      if (_matches(key)) {
        values.add(value);
      }
    });
    return values;
  }

  int get length => keys.length;

  // TODO: Use lazy iterator when it is available on Map.
  bool get isEmpty => length == 0;

  bool get isNotEmpty => !isEmpty;

  // Helpers.
  String _attr(String key) => 'data-${_toHyphenedName(key)}';
  bool _matches(String key) => key.startsWith('data-');
  String _strip(String key) => _toCamelCase(key.substring(5));

  /**
   * Converts a string name with hyphens into an identifier, by removing hyphens
   * and capitalizing the following letter. Optionally [startUppercase] to
   * captialize the first letter.
   */
  String _toCamelCase(String hyphenedName, {bool startUppercase: false}) {
    var segments = hyphenedName.split('-');
    int start = startUppercase ? 0 : 1;
    for (int i = start; i < segments.length; i++) {
      var segment = segments[i];
      if (segment.length > 0) {
        // Character between 'a'..'z' mapped to 'A'..'Z'
        segments[i] = '${segment[0].toUpperCase()}${segment.substring(1)}';
      }
    }
    return segments.join('');
  }

  /** Reverse of [toCamelCase]. */
  String _toHyphenedName(String word) {
    var sb = new StringBuffer();
    for (int i = 0; i < word.length; i++) {
      var lower = word[i].toLowerCase();
      if (word[i] != lower && i > 0) sb.write('-');
      sb.write(lower);
    }
    return sb.toString();
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * An object that can be drawn to a 2D canvas rendering context.
 *
 * The image drawn to the canvas depends on the type of this object:
 *
 * * If this object is an [ImageElement], then this element's image is
 * drawn to the canvas. If this element is an animated image, then this
 * element's poster frame is drawn. If this element has no poster frame, then
 * the first frame of animation is drawn.
 *
 * * If this object is a [VideoElement], then the frame at this element's current
 * playback position is drawn to the canvas.
 *
 * * If this object is a [CanvasElement], then this element's bitmap is drawn to
 * the canvas.
 *
 * **Note:** Currently all versions of Internet Explorer do not support
 * drawing a video element to a canvas. You may also encounter problems drawing
 * a video to a canvas in Firefox if the source of the video is a data URL.
 *
 * ## See also
 *
 * * [CanvasRenderingContext2D.drawImage]
 * * [CanvasRenderingContext2D.drawImageToRect]
 * * [CanvasRenderingContext2D.drawImageScaled]
 * * [CanvasRenderingContext2D.drawImageScaledFromSource]
 *
 * ## Other resources
 *
 * * [Image sources for 2D rendering contexts]
 * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#image-sources-for-2d-rendering-contexts)
 * from WHATWG.
 * * [Drawing images]
 * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
 * from WHATWG.
 */
abstract class CanvasImageSource {}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * Top-level container for a browser tab or window.
 *
 * In a web browser, a [WindowBase] object represents any browser window. This
 * object contains the window's state and its relation to other
 * windows, such as which window opened this window.
 *
 * **Note:** This class represents any window, while [Window] is
 * used to access the properties and content of the current window or tab.
 *
 * ## See also
 *
 * * [Window]
 *
 * ## Other resources
 *
 * * [DOM Window](https://developer.mozilla.org/en-US/docs/DOM/window) from MDN.
 * * [Window](http://www.w3.org/TR/Window/) from the W3C.
 */
abstract class WindowBase implements EventTarget {
  // Fields.

  /**
   * The current location of this window.
   *
   *     Location currentLocation = window.location;
   *     print(currentLocation.href); // 'http://www.example.com:80/'
   */
  LocationBase get location;

  /**
   * The current session history for this window.
   *
   * ## Other resources
   *
   * * [Session history and navigation specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html)
   * from WHATWG.
   */
  HistoryBase get history;

  /**
   * Indicates whether this window has been closed.
   *
   *     print(window.closed); // 'false'
   *     window.close();
   *     print(window.closed); // 'true'
   */
  bool get closed;

  /**
   * A reference to the window that opened this one.
   *
   *     Window thisWindow = window;
   *     WindowBase otherWindow = thisWindow.open('http://www.example.com/', 'foo');
   *     print(otherWindow.opener == thisWindow); // 'true'
   */
  WindowBase get opener;

  /**
   * A reference to the parent of this window.
   *
   * If this [WindowBase] has no parent, [parent] will return a reference to
   * the [WindowBase] itself.
   *
   *     IFrameElement myIFrame = new IFrameElement();
   *     window.document.body.elements.add(myIFrame);
   *     print(myIframe.contentWindow.parent == window) // 'true'
   *
   *     print(window.parent == window) // 'true'
   */
  WindowBase get parent;

  /**
   * A reference to the topmost window in the window hierarchy.
   *
   * If this [WindowBase] is the topmost [WindowBase], [top] will return a
   * reference to the [WindowBase] itself.
   *
   *     // Add an IFrame to the current window.
   *     IFrameElement myIFrame = new IFrameElement();
   *     window.document.body.elements.add(myIFrame);
   *
   *     // Add an IFrame inside of the other IFrame.
   *     IFrameElement innerIFrame = new IFrameElement();
   *     myIFrame.elements.add(innerIFrame);
   *
   *     print(myIframe.contentWindow.top == window) // 'true'
   *     print(innerIFrame.contentWindow.top == window) // 'true'
   *
   *     print(window.top == window) // 'true'
   */
  WindowBase get top;

  // Methods.
  /**
   * Closes the window.
   *
   * This method should only succeed if the [WindowBase] object is
   * **script-closeable** and the window calling [close] is allowed to navigate
   * the window.
   *
   * A window is script-closeable if it is either a window
   * that was opened by another window, or if it is a window with only one
   * document in its history.
   *
   * A window might not be allowed to navigate, and therefore close, another
   * window due to browser security features.
   *
   *     var other = window.open('http://www.example.com', 'foo');
   *     // Closes other window, as it is script-closeable.
   *     other.close();
   *     print(other.closed()); // 'true'
   *
   *     window.location('http://www.mysite.com', 'foo');
   *     // Does not close this window, as the history has changed.
   *     window.close();
   *     print(window.closed()); // 'false'
   *
   * See also:
   *
   * * [Window close discussion](http://www.w3.org/TR/html5/browsers.html#dom-window-close) from the W3C
   */
  void close();

  /**
   * Sends a cross-origin message.
   *
   * ## Other resources
   *
   * * [window.postMessage]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage) from
   * MDN.
   * * [Cross-document messaging]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/web-messaging.html)
   * from WHATWG.
   */
  void postMessage(var message, String targetOrigin, [List messagePorts]);
}

abstract class LocationBase {
  void set href(String val);
}

abstract class HistoryBase {
  void back();
  void forward();
  void go(int distance);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/** A Set that stores the CSS class names for an element. */
abstract class CssClassSet implements Set<String> {

  /**
   * Adds the class [value] to the element if it is not on it, removes it if it
   * is.
   *
   * If [shouldAdd] is true, then we always add that [value] to the element. If
   * [shouldAdd] is false then we always remove [value] from the element.
   */
  bool toggle(String value, [bool shouldAdd]);

  /**
   * Returns [:true:] if classes cannot be added or removed from this
   * [:CssClassSet:].
   */
  bool get frozen;

  /**
   * Determine if this element contains the class [value].
   *
   * This is the Dart equivalent of jQuery's
   * [hasClass](http://api.jquery.com/hasClass/).
   */
  bool contains(String value);

  /**
   * Add the class [value] to element.
   *
   * This is the Dart equivalent of jQuery's
   * [addClass](http://api.jquery.com/addClass/).
   *
   * If this corresponds to one element. Returns true if [value] was added to
   * the set, otherwise false.
   *
   * If this corresponds to many elements, null is always returned.
   */
  bool add(String value);

  /**
   * Remove the class [value] from element, and return true on successful
   * removal.
   *
   * This is the Dart equivalent of jQuery's
   * [removeClass](http://api.jquery.com/removeClass/).
   */
  bool remove(Object value);

  /**
   * Add all classes specified in [iterable] to element.
   *
   * This is the Dart equivalent of jQuery's
   * [addClass](http://api.jquery.com/addClass/).
   */
  void addAll(Iterable<String> iterable);

  /**
   * Remove all classes specified in [iterable] from element.
   *
   * This is the Dart equivalent of jQuery's
   * [removeClass](http://api.jquery.com/removeClass/).
   */
  void removeAll(Iterable<String> iterable);

  /**
   * Toggles all classes specified in [iterable] on element.
   *
   * Iterate through [iterable]'s items, and add it if it is not on it, or
   * remove it if it is. This is the Dart equivalent of jQuery's
   * [toggleClass](http://api.jquery.com/toggleClass/).
   * If [shouldAdd] is true, then we always add all the classes in [iterable]
   * element. If [shouldAdd] is false then we always remove all the classes in
   * [iterable] from the element.
   */
  void toggleAll(Iterable<String> iterable, [bool shouldAdd]);
}

/**
 * A set (union) of the CSS classes that are present in a set of elements.
 * Implemented separately from _ElementCssClassSet for performance.
 */
class _MultiElementCssClassSet extends CssClassSetImpl {
  final Iterable<Element> _elementIterable;
  Iterable<_ElementCssClassSet> _elementCssClassSetIterable;

  _MultiElementCssClassSet(this._elementIterable) {
    _elementCssClassSetIterable = new List.from(_elementIterable).map(
        (e) => new _ElementCssClassSet(e));
  }

  Set<String> readClasses() {
    var s = new LinkedHashSet<String>();
    _elementCssClassSetIterable.forEach((e) => s.addAll(e.readClasses()));
    return s;
  }

  void writeClasses(Set<String> s) {
    var classes = new List.from(s).join(' ');
    for (Element e in _elementIterable) {
      e.className = classes;
    }
  }

  /**
   * Helper method used to modify the set of css classes on this element.
   *
   *   f - callback with:
   *   s - a Set of all the css class name currently on this element.
   *
   *   After f returns, the modified set is written to the
   *       className property of this element.
   */
  modify( f(Set<String> s)) {
    _elementCssClassSetIterable.forEach((e) => e.modify(f));
  }

  /**
   * Adds the class [value] to the element if it is not on it, removes it if it
   * is.
   */
  bool toggle(String value, [bool shouldAdd]) =>
      _modifyWithReturnValue((e) => e.toggle(value, shouldAdd));

  /**
   * Remove the class [value] from element, and return true on successful
   * removal.
   *
   * This is the Dart equivalent of jQuery's
   * [removeClass](http://api.jquery.com/removeClass/).
   */
  bool remove(Object value) => _modifyWithReturnValue((e) => e.remove(value));

  bool _modifyWithReturnValue(f) => _elementCssClassSetIterable.fold(
      false, (prevValue, element) => f(element) || prevValue);
}

class _ElementCssClassSet extends CssClassSetImpl {

  final Element _element;

  _ElementCssClassSet(this._element);

  Set<String> readClasses() {
    var s = new LinkedHashSet<String>();
    var classname = _element.className;

    for (String name in classname.split(' ')) {
      String trimmed = name.trim();
      if (!trimmed.isEmpty) {
        s.add(trimmed);
      }
    }
    return s;
  }

  void writeClasses(Set<String> s) {
    List list = new List.from(s);
    _element.className = s.join(' ');
  }
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * A rectangle representing all the content of the element in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _ContentCssRect extends CssRect {

  _ContentCssRect(element) : super(element);

  num get height => _element.offsetHeight +
      _addOrSubtractToBoxModel(_HEIGHT, _CONTENT);

  num get width => _element.offsetWidth +
      _addOrSubtractToBoxModel(_WIDTH, _CONTENT);

  /**
   * Set the height to `newHeight`.
   *
   * newHeight can be either a [num] representing the height in pixels or a
   * [Dimension] object. Values of newHeight that are less than zero are
   * converted to effectively setting the height to 0. This is equivalent to the
   * `height` function in jQuery and the calculated `height` CSS value,
   * converted to a num in pixels.
   */
  void set height(newHeight) {
    if (newHeight is Dimension) {
      if (newHeight.value < 0) newHeight = new Dimension.px(0);
      _element.style.height = newHeight.toString();
    } else {
      if (newHeight < 0) newHeight = 0;
      _element.style.height = '${newHeight}px';
    }
  }

  /**
   * Set the current computed width in pixels of this element.
   *
   * newWidth can be either a [num] representing the width in pixels or a
   * [Dimension] object. This is equivalent to the `width` function in jQuery
   * and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels.
   */
  void set width(newWidth) {
    if (newWidth is Dimension) {
      if (newWidth.value < 0) newWidth = new Dimension.px(0);
      _element.style.width = newWidth.toString();
    } else {
      if (newWidth < 0) newWidth = 0;
      _element.style.width = '${newWidth}px';
    }
  }

  num get left => _element.getBoundingClientRect().left -
      _addOrSubtractToBoxModel(['left'], _CONTENT);
  num get top => _element.getBoundingClientRect().top -
      _addOrSubtractToBoxModel(['top'], _CONTENT);
}

/**
 * A list of element content rectangles in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _ContentCssListRect extends _ContentCssRect {
  List<Element> _elementList;

  _ContentCssListRect(elementList) : super(elementList.first) {
    _elementList = elementList;
  }

  /**
   * Set the height to `newHeight`.
   *
   * Values of newHeight that are less than zero are converted to effectively
   * setting the height to 0. This is equivalent to the `height`
   * function in jQuery and the calculated `height` CSS value, converted to a
   * num in pixels.
   */
  void set height(newHeight) {
    _elementList.forEach((e) => e.contentEdge.height = newHeight);
  }

  /**
   * Set the current computed width in pixels of this element.
   *
   * This is equivalent to the `width` function in jQuery and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels.
   */
  void set width(newWidth) {
    _elementList.forEach((e) => e.contentEdge.width = newWidth);
  }
}

/**
 * A rectangle representing the dimensions of the space occupied by the
 * element's content + padding in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _PaddingCssRect extends CssRect {
  _PaddingCssRect(element) : super(element);
  num get height => _element.offsetHeight +
      _addOrSubtractToBoxModel(_HEIGHT, _PADDING);
  num get width => _element.offsetWidth +
      _addOrSubtractToBoxModel(_WIDTH, _PADDING);

  num get left => _element.getBoundingClientRect().left -
      _addOrSubtractToBoxModel(['left'], _PADDING);
  num get top => _element.getBoundingClientRect().top -
      _addOrSubtractToBoxModel(['top'], _PADDING);
}

/**
 * A rectangle representing the dimensions of the space occupied by the
 * element's content + padding + border in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _BorderCssRect extends CssRect {
  _BorderCssRect(element) : super(element);
  num get height => _element.offsetHeight;
  num get width => _element.offsetWidth;

  num get left => _element.getBoundingClientRect().left;
  num get top => _element.getBoundingClientRect().top;
}

/**
 * A rectangle representing the dimensions of the space occupied by the
 * element's content + padding + border + margin in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _MarginCssRect extends CssRect {
  _MarginCssRect(element) : super(element);
  num get height => _element.offsetHeight +
      _addOrSubtractToBoxModel(_HEIGHT, _MARGIN);
  num get width =>
      _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _MARGIN);

  num get left => _element.getBoundingClientRect().left -
      _addOrSubtractToBoxModel(['left'], _MARGIN);
  num get top => _element.getBoundingClientRect().top -
      _addOrSubtractToBoxModel(['top'], _MARGIN);
}

/**
 * A class for representing CSS dimensions.
 *
 * In contrast to the more general purpose [Rectangle] class, this class's
 * values are mutable, so one can change the height of an element
 * programmatically.
 *
 * _Important_ _note_: use of these methods will perform CSS calculations that
 * can trigger a browser reflow. Therefore, use of these properties _during_ an
 * animation frame is discouraged. See also:
 * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
 */
abstract class CssRect extends MutableRectangle<num> {
  Element _element;

  CssRect(this._element) : super(0, 0, 0, 0);

  num get left;

  num get top;

  /**
   * The height of this rectangle.
   *
   * This is equivalent to the `height` function in jQuery and the calculated
   * `height` CSS value, converted to a dimensionless num in pixels. Unlike
   * [getBoundingClientRect], `height` will return the same numerical width if
   * the element is hidden or not.
   */
  num get height;

  /**
   * The width of this rectangle.
   *
   * This is equivalent to the `width` function in jQuery and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels. Unlike
   * [getBoundingClientRect], `width` will return the same numerical width if
   * the element is hidden or not.
   */
  num get width;

  /**
   * Set the height to `newHeight`.
   *
   * newHeight can be either a [num] representing the height in pixels or a
   * [Dimension] object. Values of newHeight that are less than zero are
   * converted to effectively setting the height to 0. This is equivalent to the
   * `height` function in jQuery and the calculated `height` CSS value,
   * converted to a num in pixels.
   *
   * Note that only the content height can actually be set via this method.
   */
  void set height(newHeight) {
    throw new UnsupportedError("Can only set height for content rect.");
  }

  /**
   * Set the current computed width in pixels of this element.
   *
   * newWidth can be either a [num] representing the width in pixels or a
   * [Dimension] object. This is equivalent to the `width` function in jQuery
   * and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels.
   *
   * Note that only the content width can be set via this method.
   */
  void set width(newWidth) {
    throw new UnsupportedError("Can only set width for content rect.");
  }

  /**
   * Return a value that is used to modify the initial height or width
   * measurement of an element. Depending on the value (ideally an enum) passed
   * to augmentingMeasurement, we may need to add or subtract margin, padding,
   * or border values, depending on the measurement we're trying to obtain.
   */
  num _addOrSubtractToBoxModel(List<String> dimensions,
      String augmentingMeasurement) {
    // getComputedStyle always returns pixel values (hence, computed), so we're
    // always dealing with pixels in this method.
    var styles = _element.getComputedStyle();

    var val = 0;

    for (String measurement in dimensions) {
      // The border-box and default box model both exclude margin in the regular
      // height/width calculation, so add it if we want it for this measurement.
      if (augmentingMeasurement == _MARGIN) {
        val += new Dimension.css(styles.getPropertyValue(
            '$augmentingMeasurement-$measurement')).value;
      }

      // The border-box includes padding and border, so remove it if we want
      // just the content itself.
      if (augmentingMeasurement == _CONTENT) {
      	val -= new Dimension.css(
            styles.getPropertyValue('${_PADDING}-$measurement')).value;
      }

      // At this point, we don't wan't to augment with border or margin,
      // so remove border.
      if (augmentingMeasurement != _MARGIN) {
	      val -= new Dimension.css(styles.getPropertyValue(
            'border-${measurement}-width')).value;
      }
    }
    return val;
  }
}

final _HEIGHT = ['top', 'bottom'];
final _WIDTH = ['right', 'left'];
final _CONTENT = 'content';
final _PADDING = 'padding';
final _MARGIN = 'margin';

/**
 * Class representing a
 * [length measurement](https://developer.mozilla.org/en-US/docs/Web/CSS/length)
 * in CSS.
 */
@Experimental()
class Dimension {
  num _value;
  String _unit;

  /** Set this CSS Dimension to a percentage `value`. */
  Dimension.percent(this._value) : _unit = '%';

  /** Set this CSS Dimension to a pixel `value`. */
  Dimension.px(this._value) : _unit = 'px';

  /** Set this CSS Dimension to a pica `value`. */
  Dimension.pc(this._value) : _unit = 'pc';

  /** Set this CSS Dimension to a point `value`. */
  Dimension.pt(this._value) : _unit = 'pt';

  /** Set this CSS Dimension to an inch `value`. */
  Dimension.inch(this._value) : _unit = 'in';

  /** Set this CSS Dimension to a centimeter `value`. */
  Dimension.cm(this._value) : _unit = 'cm';

  /** Set this CSS Dimension to a millimeter `value`. */
  Dimension.mm(this._value) : _unit = 'mm';

  /**
   * Set this CSS Dimension to the specified number of ems.
   *
   * 1em is equal to the current font size. (So 2ems is equal to double the font
   * size). This is useful for producing website layouts that scale nicely with
   * the user's desired font size.
   */
  Dimension.em(this._value) : _unit = 'em';

  /**
   * Set this CSS Dimension to the specified number of x-heights.
   *
   * One ex is equal to the the x-height of a font's baseline to its mean line,
   * generally the height of the letter "x" in the font, which is usually about
   * half the font-size.
   */
  Dimension.ex(this._value) : _unit = 'ex';

  /**
   * Construct a Dimension object from the valid, simple CSS string `cssValue`
   * that represents a distance measurement.
   *
   * This constructor is intended as a convenience method for working with
   * simplistic CSS length measurements. Non-numeric values such as `auto` or
   * `inherit` or invalid CSS will cause this constructor to throw a
   * FormatError.
   */
  Dimension.css(String cssValue) {
    if (cssValue == '') cssValue = '0px';
    if (cssValue.endsWith('%')) {
      _unit = '%';
    } else {
      _unit = cssValue.substring(cssValue.length - 2);
    }
    if (cssValue.contains('.')) {
      _value = double.parse(cssValue.substring(0,
          cssValue.length - _unit.length));
    } else {
      _value = int.parse(cssValue.substring(0, cssValue.length - _unit.length));
    }
  }

  /** Print out the CSS String representation of this value. */
  String toString() {
    return '${_value}${_unit}';
  }

  /** Return a unitless, numerical value of this CSS value. */
  num get value => this._value;
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


typedef EventListener(Event event);
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * A factory to expose DOM events as Streams.
 */
class EventStreamProvider<T extends Event> {
  final String _eventType;

  const EventStreamProvider(this._eventType);

  /**
   * Gets a [Stream] for this event type, on the specified target.
   *
   * This will always return a broadcast stream so multiple listeners can be
   * used simultaneously.
   *
   * This may be used to capture DOM events:
   *
   *     Element.keyDownEvent.forTarget(element, useCapture: true).listen(...);
   *
   *     // Alternate method:
   *     Element.keyDownEvent.forTarget(element).capture(...);
   *
   * Or for listening to an event which will bubble through the DOM tree:
   *
   *     MediaElement.pauseEvent.forTarget(document.body).listen(...);
   *
   * See also:
   *
   * [addEventListener](http://docs.webplatform.org/wiki/dom/methods/addEventListener)
   */
  Stream<T> forTarget(EventTarget e, {bool useCapture: false}) =>
    new _EventStream(e, _eventType, useCapture);

  /**
   * Gets an [ElementEventStream] for this event type, on the specified element.
   *
   * This will always return a broadcast stream so multiple listeners can be
   * used simultaneously.
   *
   * This may be used to capture DOM events:
   *
   *     Element.keyDownEvent.forElement(element, useCapture: true).listen(...);
   *
   *     // Alternate method:
   *     Element.keyDownEvent.forElement(element).capture(...);
   *
   * Or for listening to an event which will bubble through the DOM tree:
   *
   *     MediaElement.pauseEvent.forElement(document.body).listen(...);
   *
   * See also:
   *
   * [addEventListener](http://docs.webplatform.org/wiki/dom/methods/addEventListener)
   */
  ElementStream<T> forElement(Element e, {bool useCapture: false}) {
    return new _ElementEventStreamImpl(e, _eventType, useCapture);
  }

  /**
   * Gets an [ElementEventStream] for this event type, on the list of elements.
   *
   * This will always return a broadcast stream so multiple listeners can be
   * used simultaneously.
   *
   * This may be used to capture DOM events:
   *
   *     Element.keyDownEvent._forElementList(element, useCapture: true).listen(...);
   *
   * See also:
   *
   * [addEventListener](http://docs.webplatform.org/wiki/dom/methods/addEventListener)
   */
  ElementStream<T> _forElementList(ElementList e, {bool useCapture: false}) {
    return new _ElementListEventStreamImpl(e, _eventType, useCapture);
  }

  /**
   * Gets the type of the event which this would listen for on the specified
   * event target.
   *
   * The target is necessary because some browsers may use different event names
   * for the same purpose and the target allows differentiating browser support.
   */
  String getEventType(EventTarget target) {
    return _eventType;
  }
}

/** A specialized Stream available to [Element]s to enable event delegation. */
abstract class ElementStream<T extends Event> implements Stream<T> {
  /**
   * Return a stream that only fires when the particular event fires for
   * elements matching the specified CSS selector.
   *
   * This is the Dart equivalent to jQuery's
   * [delegate](http://api.jquery.com/delegate/).
   */
  Stream<T> matches(String selector);

  /**
   * Adds a capturing subscription to this stream.
   *
   * If the target of the event is a descendant of the element from which this
   * stream derives then [onData] is called before the event propagates down to
   * the target. This is the opposite of bubbling behavior, where the event
   * is first processed for the event target and then bubbles upward.
   *
   * ## Other resources
   *
   * * [Event Capture]
   * (http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture)
   * from the W3C DOM Events specification.
   */
  StreamSubscription<T> capture(void onData(T event));
}

/**
 * Adapter for exposing DOM events as Dart streams.
 */
class _EventStream<T extends Event> extends Stream<T> {
  final EventTarget _target;
  final String _eventType;
  final bool _useCapture;

  _EventStream(this._target, this._eventType, this._useCapture);

  // DOM events are inherently multi-subscribers.
  Stream<T> asBroadcastStream({void onListen(StreamSubscription subscription),
                               void onCancel(StreamSubscription subscription)})
      => this;
  bool get isBroadcast => true;

  StreamSubscription<T> listen(void onData(T event),
      { Function onError,
        void onDone(),
        bool cancelOnError}) {

    return new _EventStreamSubscription<T>(
        this._target, this._eventType, onData, this._useCapture);
  }
}

/**
 * Adapter for exposing DOM Element events as streams, while also allowing
 * event delegation.
 */
class _ElementEventStreamImpl<T extends Event> extends _EventStream<T>
    implements ElementStream<T> {
  _ElementEventStreamImpl(target, eventType, useCapture) :
      super(target, eventType, useCapture);

  Stream<T> matches(String selector) => this.where(
      (event) => event.target.matchesWithAncestors(selector)).map((e) {
        e._selector = selector;
        return e;
      });

  StreamSubscription<T> capture(void onData(T event)) =>
    new _EventStreamSubscription<T>(
        this._target, this._eventType, onData, true);
}

/**
 * Adapter for exposing events on a collection of DOM Elements as streams,
 * while also allowing event delegation.
 */
class _ElementListEventStreamImpl<T extends Event> extends Stream<T>
    implements ElementStream<T> {
  final Iterable<Element> _targetList;
  final bool _useCapture;
  final String _eventType;

  _ElementListEventStreamImpl(
      this._targetList, this._eventType, this._useCapture);

  Stream<T> matches(String selector) => this.where(
      (event) => event.target.matchesWithAncestors(selector)).map((e) {
        e._selector = selector;
        return e;
      });

  // Delegate all regular Stream behavior to a wrapped Stream.
  StreamSubscription<T> listen(void onData(T event),
      { Function onError,
        void onDone(),
        bool cancelOnError}) {
    var pool = new _StreamPool.broadcast();
    for (var target in _targetList) {
      pool.add(new _EventStream(target, _eventType, _useCapture));
    }
    return pool.stream.listen(onData, onError: onError, onDone: onDone,
          cancelOnError: cancelOnError);
  }

  StreamSubscription<T> capture(void onData(T event)) {
    var pool = new _StreamPool.broadcast();
    for (var target in _targetList) {
      pool.add(new _EventStream(target, _eventType, true));
    }
    return pool.stream.listen(onData);
  }

  Stream<T> asBroadcastStream({void onListen(StreamSubscription subscription),
                               void onCancel(StreamSubscription subscription)})
      => this;
  bool get isBroadcast => true;
}

class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> {
  int _pauseCount = 0;
  EventTarget _target;
  final String _eventType;
  var _onData;
  final bool _useCapture;

  _EventStreamSubscription(this._target, this._eventType, onData,
      this._useCapture) : _onData = _wrapZone(onData) {
    _tryResume();
  }

  Future cancel() {
    if (_canceled) return null;

    _unlisten();
    // Clear out the target to indicate this is complete.
    _target = null;
    _onData = null;
    return null;
  }

  bool get _canceled => _target == null;

  void onData(void handleData(T event)) {
    if (_canceled) {
      throw new StateError("Subscription has been canceled.");
    }
    // Remove current event listener.
    _unlisten();

    _onData = _wrapZone(handleData);
    _tryResume();
  }

  /// Has no effect.
  void onError(Function handleError) {}

  /// Has no effect.
  void onDone(void handleDone()) {}

  void pause([Future resumeSignal]) {
    if (_canceled) return;
    ++_pauseCount;
    _unlisten();

    if (resumeSignal != null) {
      resumeSignal.whenComplete(resume);
    }
  }

  bool get isPaused => _pauseCount > 0;

  void resume() {
    if (_canceled || !isPaused) return;
    --_pauseCount;
    _tryResume();
  }

  void _tryResume() {
    if (_onData != null && !isPaused) {
      _target.addEventListener(_eventType, _onData, _useCapture);
    }
  }

  void _unlisten() {
    if (_onData != null) {
      _target.removeEventListener(_eventType, _onData, _useCapture);
    }
  }

  Future asFuture([var futureValue]) {
    // We just need a future that will never succeed or fail.
    Completer completer = new Completer();
    return completer.future;
  }
}

/**
 * A stream of custom events, which enables the user to "fire" (add) their own
 * custom events to a stream.
 */
abstract class CustomStream<T extends Event> implements Stream<T> {
  /**
   * Add the following custom event to the stream for dispatching to interested
   * listeners.
   */
  void add(T event);
}

class _CustomEventStreamImpl<T extends Event> extends Stream<T>
    implements CustomStream<T> {
  StreamController<T> _streamController;
  /** The type of event this stream is providing (e.g. "keydown"). */
  String _type;

  _CustomEventStreamImpl(String type) {
    _type = type;
    _streamController = new StreamController.broadcast(sync: true);
  }

  // Delegate all regular Stream behavior to our wrapped Stream.
  StreamSubscription<T> listen(void onData(T event),
      { Function onError,
        void onDone(),
        bool cancelOnError}) {
    return _streamController.stream.listen(onData, onError: onError,
        onDone: onDone, cancelOnError: cancelOnError);
  }

  Stream<T> asBroadcastStream({void onListen(StreamSubscription subscription),
                               void onCancel(StreamSubscription subscription)})
      => _streamController.stream;

  bool get isBroadcast => true;

  void add(T event) {
    if (event.type == _type) _streamController.add(event);
  }
}

class _CustomKeyEventStreamImpl extends _CustomEventStreamImpl<KeyEvent>
    implements CustomStream<KeyEvent> {
  _CustomKeyEventStreamImpl(String type) : super(type);

  void add(KeyEvent event) {
    if (event.type == _type) {
      event.currentTarget.dispatchEvent(event._parent);
      _streamController.add(event);
    }
  }
}

/**
 * A pool of streams whose events are unified and emitted through a central
 * stream.
 */
// TODO (efortuna): Remove this when Issue 12218 is addressed.
class _StreamPool<T> {
  StreamController<T> _controller;

  /// Subscriptions to the streams that make up the pool.
  var _subscriptions = new Map<Stream<T>, StreamSubscription<T>>();

  /**
   * Creates a new stream pool where [stream] can be listened to more than
   * once.
   *
   * Any events from buffered streams in the pool will be emitted immediately,
   * regardless of whether [stream] has any subscribers.
   */
  _StreamPool.broadcast() {
    _controller = new StreamController<T>.broadcast(sync: true,
        onCancel: close);
  }

  /**
   * The stream through which all events from streams in the pool are emitted.
   */
  Stream<T> get stream => _controller.stream;

  /**
   * Adds [stream] as a member of this pool.
   *
   * Any events from [stream] will be emitted through [this.stream]. If
   * [stream] is sync, they'll be emitted synchronously; if [stream] is async,
   * they'll be emitted asynchronously.
   */
  void add(Stream<T> stream) {
    if (_subscriptions.containsKey(stream)) return;
    _subscriptions[stream] = stream.listen(_controller.add,
        onError: _controller.addError,
        onDone: () => remove(stream));
  }

  /** Removes [stream] as a member of this pool. */
  void remove(Stream<T> stream) {
    var subscription = _subscriptions.remove(stream);
    if (subscription != null) subscription.cancel();
  }

  /** Removes all streams from this pool and closes [stream]. */
  void close() {
    for (var subscription in _subscriptions.values) {
      subscription.cancel();
    }
    _subscriptions.clear();
    _controller.close();
  }
}

/**
 * A factory to expose DOM events as streams, where the DOM event name has to
 * be determined on the fly (for example, mouse wheel events).
 */
class _CustomEventStreamProvider<T extends Event>
    implements EventStreamProvider<T> {

  final _eventTypeGetter;
  const _CustomEventStreamProvider(this._eventTypeGetter);

  Stream<T> forTarget(EventTarget e, {bool useCapture: false}) {
    return new _EventStream(e, _eventTypeGetter(e), useCapture);
  }

  ElementStream<T> forElement(Element e, {bool useCapture: false}) {
    return new _ElementEventStreamImpl(e, _eventTypeGetter(e), useCapture);
  }

  ElementStream<T> _forElementList(ElementList e,
      {bool useCapture: false}) {
    return new _ElementListEventStreamImpl(e, _eventTypeGetter(e), useCapture);
  }

  String getEventType(EventTarget target) {
    return _eventTypeGetter(target);
  }

  String get _eventType =>
      throw new UnsupportedError('Access type through getEventType method.');
}
// DO NOT EDIT- this file is generated from running tool/generator.sh.

// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * A Dart DOM validator generated from Caja whitelists.
 *
 * This contains a whitelist of known HTML tagNames and attributes and will only
 * accept known good values.
 *
 * See also:
 *
 * * <https://code.google.com/p/google-caja/wiki/CajaWhitelists>
 */
class _Html5NodeValidator implements NodeValidator {

  static final Set<String> _allowedElements = new Set.from([
    'A',
    'ABBR',
    'ACRONYM',
    'ADDRESS',
    'AREA',
    'ARTICLE',
    'ASIDE',
    'AUDIO',
    'B',
    'BDI',
    'BDO',
    'BIG',
    'BLOCKQUOTE',
    'BR',
    'BUTTON',
    'CANVAS',
    'CAPTION',
    'CENTER',
    'CITE',
    'CODE',
    'COL',
    'COLGROUP',
    'COMMAND',
    'DATA',
    'DATALIST',
    'DD',
    'DEL',
    'DETAILS',
    'DFN',
    'DIR',
    'DIV',
    'DL',
    'DT',
    'EM',
    'FIELDSET',
    'FIGCAPTION',
    'FIGURE',
    'FONT',
    'FOOTER',
    'FORM',
    'H1',
    'H2',
    'H3',
    'H4',
    'H5',
    'H6',
    'HEADER',
    'HGROUP',
    'HR',
    'I',
    'IFRAME',
    'IMG',
    'INPUT',
    'INS',
    'KBD',
    'LABEL',
    'LEGEND',
    'LI',
    'MAP',
    'MARK',
    'MENU',
    'METER',
    'NAV',
    'NOBR',
    'OL',
    'OPTGROUP',
    'OPTION',
    'OUTPUT',
    'P',
    'PRE',
    'PROGRESS',
    'Q',
    'S',
    'SAMP',
    'SECTION',
    'SELECT',
    'SMALL',
    'SOURCE',
    'SPAN',
    'STRIKE',
    'STRONG',
    'SUB',
    'SUMMARY',
    'SUP',
    'TABLE',
    'TBODY',
    'TD',
    'TEXTAREA',
    'TFOOT',
    'TH',
    'THEAD',
    'TIME',
    'TR',
    'TRACK',
    'TT',
    'U',
    'UL',
    'VAR',
    'VIDEO',
    'WBR',
  ]);

  static const _standardAttributes = const <String>[
    '*::class',
    '*::dir',
    '*::draggable',
    '*::hidden',
    '*::id',
    '*::inert',
    '*::itemprop',
    '*::itemref',
    '*::itemscope',
    '*::lang',
    '*::spellcheck',
    '*::title',
    '*::translate',
    'A::accesskey',
    'A::coords',
    'A::hreflang',
    'A::name',
    'A::shape',
    'A::tabindex',
    'A::target',
    'A::type',
    'AREA::accesskey',
    'AREA::alt',
    'AREA::coords',
    'AREA::nohref',
    'AREA::shape',
    'AREA::tabindex',
    'AREA::target',
    'AUDIO::controls',
    'AUDIO::loop',
    'AUDIO::mediagroup',
    'AUDIO::muted',
    'AUDIO::preload',
    'BDO::dir',
    'BODY::alink',
    'BODY::bgcolor',
    'BODY::link',
    'BODY::text',
    'BODY::vlink',
    'BR::clear',
    'BUTTON::accesskey',
    'BUTTON::disabled',
    'BUTTON::name',
    'BUTTON::tabindex',
    'BUTTON::type',
    'BUTTON::value',
    'CANVAS::height',
    'CANVAS::width',
    'CAPTION::align',
    'COL::align',
    'COL::char',
    'COL::charoff',
    'COL::span',
    'COL::valign',
    'COL::width',
    'COLGROUP::align',
    'COLGROUP::char',
    'COLGROUP::charoff',
    'COLGROUP::span',
    'COLGROUP::valign',
    'COLGROUP::width',
    'COMMAND::checked',
    'COMMAND::command',
    'COMMAND::disabled',
    'COMMAND::label',
    'COMMAND::radiogroup',
    'COMMAND::type',
    'DATA::value',
    'DEL::datetime',
    'DETAILS::open',
    'DIR::compact',
    'DIV::align',
    'DL::compact',
    'FIELDSET::disabled',
    'FONT::color',
    'FONT::face',
    'FONT::size',
    'FORM::accept',
    'FORM::autocomplete',
    'FORM::enctype',
    'FORM::method',
    'FORM::name',
    'FORM::novalidate',
    'FORM::target',
    'FRAME::name',
    'H1::align',
    'H2::align',
    'H3::align',
    'H4::align',
    'H5::align',
    'H6::align',
    'HR::align',
    'HR::noshade',
    'HR::size',
    'HR::width',
    'HTML::version',
    'IFRAME::align',
    'IFRAME::frameborder',
    'IFRAME::height',
    'IFRAME::marginheight',
    'IFRAME::marginwidth',
    'IFRAME::width',
    'IMG::align',
    'IMG::alt',
    'IMG::border',
    'IMG::height',
    'IMG::hspace',
    'IMG::ismap',
    'IMG::name',
    'IMG::usemap',
    'IMG::vspace',
    'IMG::width',
    'INPUT::accept',
    'INPUT::accesskey',
    'INPUT::align',
    'INPUT::alt',
    'INPUT::autocomplete',
    'INPUT::checked',
    'INPUT::disabled',
    'INPUT::inputmode',
    'INPUT::ismap',
    'INPUT::list',
    'INPUT::max',
    'INPUT::maxlength',
    'INPUT::min',
    'INPUT::multiple',
    'INPUT::name',
    'INPUT::placeholder',
    'INPUT::readonly',
    'INPUT::required',
    'INPUT::size',
    'INPUT::step',
    'INPUT::tabindex',
    'INPUT::type',
    'INPUT::usemap',
    'INPUT::value',
    'INS::datetime',
    'KEYGEN::disabled',
    'KEYGEN::keytype',
    'KEYGEN::name',
    'LABEL::accesskey',
    'LABEL::for',
    'LEGEND::accesskey',
    'LEGEND::align',
    'LI::type',
    'LI::value',
    'LINK::sizes',
    'MAP::name',
    'MENU::compact',
    'MENU::label',
    'MENU::type',
    'METER::high',
    'METER::low',
    'METER::max',
    'METER::min',
    'METER::value',
    'OBJECT::typemustmatch',
    'OL::compact',
    'OL::reversed',
    'OL::start',
    'OL::type',
    'OPTGROUP::disabled',
    'OPTGROUP::label',
    'OPTION::disabled',
    'OPTION::label',
    'OPTION::selected',
    'OPTION::value',
    'OUTPUT::for',
    'OUTPUT::name',
    'P::align',
    'PRE::width',
    'PROGRESS::max',
    'PROGRESS::min',
    'PROGRESS::value',
    'SELECT::autocomplete',
    'SELECT::disabled',
    'SELECT::multiple',
    'SELECT::name',
    'SELECT::required',
    'SELECT::size',
    'SELECT::tabindex',
    'SOURCE::type',
    'TABLE::align',
    'TABLE::bgcolor',
    'TABLE::border',
    'TABLE::cellpadding',
    'TABLE::cellspacing',
    'TABLE::frame',
    'TABLE::rules',
    'TABLE::summary',
    'TABLE::width',
    'TBODY::align',
    'TBODY::char',
    'TBODY::charoff',
    'TBODY::valign',
    'TD::abbr',
    'TD::align',
    'TD::axis',
    'TD::bgcolor',
    'TD::char',
    'TD::charoff',
    'TD::colspan',
    'TD::headers',
    'TD::height',
    'TD::nowrap',
    'TD::rowspan',
    'TD::scope',
    'TD::valign',
    'TD::width',
    'TEXTAREA::accesskey',
    'TEXTAREA::autocomplete',
    'TEXTAREA::cols',
    'TEXTAREA::disabled',
    'TEXTAREA::inputmode',
    'TEXTAREA::name',
    'TEXTAREA::placeholder',
    'TEXTAREA::readonly',
    'TEXTAREA::required',
    'TEXTAREA::rows',
    'TEXTAREA::tabindex',
    'TEXTAREA::wrap',
    'TFOOT::align',
    'TFOOT::char',
    'TFOOT::charoff',
    'TFOOT::valign',
    'TH::abbr',
    'TH::align',
    'TH::axis',
    'TH::bgcolor',
    'TH::char',
    'TH::charoff',
    'TH::colspan',
    'TH::headers',
    'TH::height',
    'TH::nowrap',
    'TH::rowspan',
    'TH::scope',
    'TH::valign',
    'TH::width',
    'THEAD::align',
    'THEAD::char',
    'THEAD::charoff',
    'THEAD::valign',
    'TR::align',
    'TR::bgcolor',
    'TR::char',
    'TR::charoff',
    'TR::valign',
    'TRACK::default',
    'TRACK::kind',
    'TRACK::label',
    'TRACK::srclang',
    'UL::compact',
    'UL::type',
    'VIDEO::controls',
    'VIDEO::height',
    'VIDEO::loop',
    'VIDEO::mediagroup',
    'VIDEO::muted',
    'VIDEO::preload',
    'VIDEO::width',
  ];

  static const _uriAttributes = const <String>[
    'A::href',
    'AREA::href',
    'BLOCKQUOTE::cite',
    'BODY::background',
    'COMMAND::icon',
    'DEL::cite',
    'FORM::action',
    'IMG::src',
    'INPUT::src',
    'INS::cite',
    'Q::cite',
    'VIDEO::poster',
  ];

  final UriPolicy uriPolicy;

  static final Map<String, Function> _attributeValidators = {};

  /**
   * All known URI attributes will be validated against the UriPolicy, if
   * [uriPolicy] is null then a default UriPolicy will be used.
   */
  _Html5NodeValidator({UriPolicy uriPolicy})
      :uriPolicy = uriPolicy != null ? uriPolicy : new UriPolicy() {

    if (_attributeValidators.isEmpty) {
      for (var attr in _standardAttributes) {
        _attributeValidators[attr] = _standardAttributeValidator;
      }

      for (var attr in _uriAttributes) {
        _attributeValidators[attr] = _uriAttributeValidator;
      }
    }
  }

  bool allowsElement(Element element) {
    return _allowedElements.contains(element.tagName);
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    var tagName = element.tagName;
    var validator = _attributeValidators['$tagName::$attributeName'];
    if (validator == null) {
      validator = _attributeValidators['*::$attributeName'];
    }
    if (validator == null) {
      return false;
    }
    return validator(element, attributeName, value, this);
  }

  static bool _standardAttributeValidator(Element element, String attributeName,
      String value, _Html5NodeValidator context) {
    return true;
  }

  static bool _uriAttributeValidator(Element element, String attributeName,
      String value, _Html5NodeValidator context) {
    return context.uriPolicy.allowsUri(value);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


abstract class ImmutableListMixin<E> implements List<E> {
  // From Iterable<$E>:
  Iterator<E> get iterator {
    // Note: NodeLists are not fixed size. And most probably length shouldn't
    // be cached in both iterator _and_ forEach method. For now caching it
    // for consistency.
    return new FixedSizeListIterator<E>(this);
  }

  // From Collection<E>:
  void add(E value) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  void addAll(Iterable<E> iterable) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  // From List<E>:
  void sort([int compare(E a, E b)]) {
    throw new UnsupportedError("Cannot sort immutable List.");
  }

  void shuffle([Random random]) {
    throw new UnsupportedError("Cannot shuffle immutable List.");
  }

  void insert(int index, E element) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  void insertAll(int index, Iterable<E> iterable) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  void setAll(int index, Iterable<E> iterable) {
    throw new UnsupportedError("Cannot modify an immutable List.");
  }

  E removeAt(int pos) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  E removeLast() {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  bool remove(Object object) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  void removeWhere(bool test(E element)) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  void retainWhere(bool test(E element)) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
    throw new UnsupportedError("Cannot setRange on immutable List.");
  }

  void removeRange(int start, int end) {
    throw new UnsupportedError("Cannot removeRange on immutable List.");
  }

  void replaceRange(int start, int end, Iterable<E> iterable) {
    throw new UnsupportedError("Cannot modify an immutable List.");
  }

  void fillRange(int start, int end, [E fillValue]) {
    throw new UnsupportedError("Cannot modify an immutable List.");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * Defines the keycode values for keys that are returned by
 * KeyboardEvent.keyCode.
 *
 * Important note: There is substantial divergence in how different browsers
 * handle keycodes and their variants in different locales/keyboard layouts. We
 * provide these constants to help make code processing keys more readable.
 */
abstract class KeyCode {
  // These constant names were borrowed from Closure's Keycode enumeration
  // class.
  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keycodes.js.source.html
  static const int WIN_KEY_FF_LINUX = 0;
  static const int MAC_ENTER = 3;
  static const int BACKSPACE = 8;
  static const int TAB = 9;
  /** NUM_CENTER is also NUMLOCK for FF and Safari on Mac. */
  static const int NUM_CENTER = 12;
  static const int ENTER = 13;
  static const int SHIFT = 16;
  static const int CTRL = 17;
  static const int ALT = 18;
  static const int PAUSE = 19;
  static const int CAPS_LOCK = 20;
  static const int ESC = 27;
  static const int SPACE = 32;
  static const int PAGE_UP = 33;
  static const int PAGE_DOWN = 34;
  static const int END = 35;
  static const int HOME = 36;
  static const int LEFT = 37;
  static const int UP = 38;
  static const int RIGHT = 39;
  static const int DOWN = 40;
  static const int NUM_NORTH_EAST = 33;
  static const int NUM_SOUTH_EAST = 34;
  static const int NUM_SOUTH_WEST = 35;
  static const int NUM_NORTH_WEST = 36;
  static const int NUM_WEST = 37;
  static const int NUM_NORTH = 38;
  static const int NUM_EAST = 39;
  static const int NUM_SOUTH = 40;
  static const int PRINT_SCREEN = 44;
  static const int INSERT = 45;
  static const int NUM_INSERT = 45;
  static const int DELETE = 46;
  static const int NUM_DELETE = 46;
  static const int ZERO = 48;
  static const int ONE = 49;
  static const int TWO = 50;
  static const int THREE = 51;
  static const int FOUR = 52;
  static const int FIVE = 53;
  static const int SIX = 54;
  static const int SEVEN = 55;
  static const int EIGHT = 56;
  static const int NINE = 57;
  static const int FF_SEMICOLON = 59;
  static const int FF_EQUALS = 61;
  /**
   * CAUTION: The question mark is for US-keyboard layouts. It varies
   * for other locales and keyboard layouts.
   */
  static const int QUESTION_MARK = 63;
  static const int A = 65;
  static const int B = 66;
  static const int C = 67;
  static const int D = 68;
  static const int E = 69;
  static const int F = 70;
  static const int G = 71;
  static const int H = 72;
  static const int I = 73;
  static const int J = 74;
  static const int K = 75;
  static const int L = 76;
  static const int M = 77;
  static const int N = 78;
  static const int O = 79;
  static const int P = 80;
  static const int Q = 81;
  static const int R = 82;
  static const int S = 83;
  static const int T = 84;
  static const int U = 85;
  static const int V = 86;
  static const int W = 87;
  static const int X = 88;
  static const int Y = 89;
  static const int Z = 90;
  static const int META = 91;
  static const int WIN_KEY_LEFT = 91;
  static const int WIN_KEY_RIGHT = 92;
  static const int CONTEXT_MENU = 93;
  static const int NUM_ZERO = 96;
  static const int NUM_ONE = 97;
  static const int NUM_TWO = 98;
  static const int NUM_THREE = 99;
  static const int NUM_FOUR = 100;
  static const int NUM_FIVE = 101;
  static const int NUM_SIX = 102;
  static const int NUM_SEVEN = 103;
  static const int NUM_EIGHT = 104;
  static const int NUM_NINE = 105;
  static const int NUM_MULTIPLY = 106;
  static const int NUM_PLUS = 107;
  static const int NUM_MINUS = 109;
  static const int NUM_PERIOD = 110;
  static const int NUM_DIVISION = 111;
  static const int F1 = 112;
  static const int F2 = 113;
  static const int F3 = 114;
  static const int F4 = 115;
  static const int F5 = 116;
  static const int F6 = 117;
  static const int F7 = 118;
  static const int F8 = 119;
  static const int F9 = 120;
  static const int F10 = 121;
  static const int F11 = 122;
  static const int F12 = 123;
  static const int NUMLOCK = 144;
  static const int SCROLL_LOCK = 145;

  // OS-specific media keys like volume controls and browser controls.
  static const int FIRST_MEDIA_KEY = 166;
  static const int LAST_MEDIA_KEY = 183;

  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int SEMICOLON = 186;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int DASH = 189;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int EQUALS = 187;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int COMMA = 188;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int PERIOD = 190;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int SLASH = 191;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int APOSTROPHE = 192;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int TILDE = 192;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int SINGLE_QUOTE = 222;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int OPEN_SQUARE_BRACKET = 219;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int BACKSLASH = 220;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int CLOSE_SQUARE_BRACKET = 221;
  static const int WIN_KEY = 224;
  static const int MAC_FF_META = 224;
  static const int WIN_IME = 229;

  /** A sentinel value if the keycode could not be determined. */
  static const int UNKNOWN = -1;

  /**
   * Returns true if the keyCode produces a (US keyboard) character.
   * Note: This does not (yet) cover characters on non-US keyboards (Russian,
   * Hebrew, etc.).
   */
  static bool isCharacterKey(int keyCode) {
    if ((keyCode >= ZERO && keyCode <= NINE) ||
        (keyCode >= NUM_ZERO && keyCode <= NUM_MULTIPLY) ||
        (keyCode >= A && keyCode <= Z)) {
      return true;
    }

    // Safari sends zero key code for non-latin characters.
    if (Device.isWebKit && keyCode == 0) {
      return true;
    }

    return (keyCode == SPACE || keyCode == QUESTION_MARK || keyCode == NUM_PLUS
        || keyCode == NUM_MINUS || keyCode == NUM_PERIOD ||
        keyCode == NUM_DIVISION || keyCode == SEMICOLON ||
        keyCode == FF_SEMICOLON || keyCode == DASH || keyCode == EQUALS ||
        keyCode == FF_EQUALS || keyCode == COMMA || keyCode == PERIOD ||
        keyCode == SLASH || keyCode == APOSTROPHE || keyCode == SINGLE_QUOTE ||
        keyCode == OPEN_SQUARE_BRACKET || keyCode == BACKSLASH ||
        keyCode == CLOSE_SQUARE_BRACKET);
  }

  /**
   * Experimental helper function for converting keyCodes to keyNames for the
   * keyIdentifier attribute still used in browsers not updated with current
   * spec. This is an imperfect conversion! It will need to be refined, but
   * hopefully it can just completely go away once all the browsers update to
   * follow the DOM3 spec.
   */
  static String _convertKeyCodeToKeyName(int keyCode) {
    switch(keyCode) {
      case KeyCode.ALT: return _KeyName.ALT;
      case KeyCode.BACKSPACE: return _KeyName.BACKSPACE;
      case KeyCode.CAPS_LOCK: return _KeyName.CAPS_LOCK;
      case KeyCode.CTRL: return _KeyName.CONTROL;
      case KeyCode.DELETE: return _KeyName.DEL;
      case KeyCode.DOWN: return _KeyName.DOWN;
      case KeyCode.END: return _KeyName.END;
      case KeyCode.ENTER: return _KeyName.ENTER;
      case KeyCode.ESC: return _KeyName.ESC;
      case KeyCode.F1: return _KeyName.F1;
      case KeyCode.F2: return _KeyName.F2;
      case KeyCode.F3: return _KeyName.F3;
      case KeyCode.F4: return _KeyName.F4;
      case KeyCode.F5: return _KeyName.F5;
      case KeyCode.F6: return _KeyName.F6;
      case KeyCode.F7: return _KeyName.F7;
      case KeyCode.F8: return _KeyName.F8;
      case KeyCode.F9: return _KeyName.F9;
      case KeyCode.F10: return _KeyName.F10;
      case KeyCode.F11: return _KeyName.F11;
      case KeyCode.F12: return _KeyName.F12;
      case KeyCode.HOME: return _KeyName.HOME;
      case KeyCode.INSERT: return _KeyName.INSERT;
      case KeyCode.LEFT: return _KeyName.LEFT;
      case KeyCode.META: return _KeyName.META;
      case KeyCode.NUMLOCK: return _KeyName.NUM_LOCK;
      case KeyCode.PAGE_DOWN: return _KeyName.PAGE_DOWN;
      case KeyCode.PAGE_UP: return _KeyName.PAGE_UP;
      case KeyCode.PAUSE: return _KeyName.PAUSE;
      case KeyCode.PRINT_SCREEN: return _KeyName.PRINT_SCREEN;
      case KeyCode.RIGHT: return _KeyName.RIGHT;
      case KeyCode.SCROLL_LOCK: return _KeyName.SCROLL;
      case KeyCode.SHIFT: return _KeyName.SHIFT;
      case KeyCode.SPACE: return _KeyName.SPACEBAR;
      case KeyCode.TAB: return _KeyName.TAB;
      case KeyCode.UP: return _KeyName.UP;
      case KeyCode.WIN_IME:
      case KeyCode.WIN_KEY:
      case KeyCode.WIN_KEY_LEFT:
      case KeyCode.WIN_KEY_RIGHT:
        return _KeyName.WIN;
      default: return _KeyName.UNIDENTIFIED;
    }
    return _KeyName.UNIDENTIFIED;
  }
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * Defines the standard key locations returned by
 * KeyboardEvent.getKeyLocation.
 */
abstract class KeyLocation {

  /**
   * The event key is not distinguished as the left or right version
   * of the key, and did not originate from the numeric keypad (or did not
   * originate with a virtual key corresponding to the numeric keypad).
   */
  static const int STANDARD = 0;

  /**
   * The event key is in the left key location.
   */
  static const int LEFT = 1;

  /**
   * The event key is in the right key location.
   */
  static const int RIGHT = 2;

  /**
   * The event key originated on the numeric keypad or with a virtual key
   * corresponding to the numeric keypad.
   */
  static const int NUMPAD = 3;

  /**
   * The event key originated on a mobile device, either on a physical
   * keypad or a virtual keyboard.
   */
  static const int MOBILE = 4;

  /**
   * The event key originated on a game controller or a joystick on a mobile
   * device.
   */
  static const int JOYSTICK = 5;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * Defines the standard keyboard identifier names for keys that are returned
 * by KeyboardEvent.getKeyboardIdentifier when the key does not have a direct
 * unicode mapping.
 */
abstract class _KeyName {

  /** The Accept (Commit, OK) key */
  static const String ACCEPT = "Accept";

  /** The Add key */
  static const String ADD = "Add";

  /** The Again key */
  static const String AGAIN = "Again";

  /** The All Candidates key */
  static const String ALL_CANDIDATES = "AllCandidates";

  /** The Alphanumeric key */
  static const String ALPHANUMERIC = "Alphanumeric";

  /** The Alt (Menu) key */
  static const String ALT = "Alt";

  /** The Alt-Graph key */
  static const String ALT_GRAPH = "AltGraph";

  /** The Application key */
  static const String APPS = "Apps";

  /** The ATTN key */
  static const String ATTN = "Attn";

  /** The Browser Back key */
  static const String BROWSER_BACK = "BrowserBack";

  /** The Browser Favorites key */
  static const String BROWSER_FAVORTIES = "BrowserFavorites";

  /** The Browser Forward key */
  static const String BROWSER_FORWARD = "BrowserForward";

  /** The Browser Home key */
  static const String BROWSER_NAME = "BrowserHome";

  /** The Browser Refresh key */
  static const String BROWSER_REFRESH = "BrowserRefresh";

  /** The Browser Search key */
  static const String BROWSER_SEARCH = "BrowserSearch";

  /** The Browser Stop key */
  static const String BROWSER_STOP = "BrowserStop";

  /** The Camera key */
  static const String CAMERA = "Camera";

  /** The Caps Lock (Capital) key */
  static const String CAPS_LOCK = "CapsLock";

  /** The Clear key */
  static const String CLEAR = "Clear";

  /** The Code Input key */
  static const String CODE_INPUT = "CodeInput";

  /** The Compose key */
  static const String COMPOSE = "Compose";

  /** The Control (Ctrl) key */
  static const String CONTROL = "Control";

  /** The Crsel key */
  static const String CRSEL = "Crsel";

  /** The Convert key */
  static const String CONVERT = "Convert";

  /** The Copy key */
  static const String COPY = "Copy";

  /** The Cut key */
  static const String CUT = "Cut";

  /** The Decimal key */
  static const String DECIMAL = "Decimal";

  /** The Divide key */
  static const String DIVIDE = "Divide";

  /** The Down Arrow key */
  static const String DOWN = "Down";

  /** The diagonal Down-Left Arrow key */
  static const String DOWN_LEFT = "DownLeft";

  /** The diagonal Down-Right Arrow key */
  static const String DOWN_RIGHT = "DownRight";

  /** The Eject key */
  static const String EJECT = "Eject";

  /** The End key */
  static const String END = "End";

  /**
   * The Enter key. Note: This key value must also be used for the Return
   *  (Macintosh numpad) key
   */
  static const String ENTER = "Enter";

  /** The Erase EOF key */
  static const String ERASE_EOF= "EraseEof";

  /** The Execute key */
  static const String EXECUTE = "Execute";

  /** The Exsel key */
  static const String EXSEL = "Exsel";

  /** The Function switch key */
  static const String FN = "Fn";

  /** The F1 key */
  static const String F1 = "F1";

  /** The F2 key */
  static const String F2 = "F2";

  /** The F3 key */
  static const String F3 = "F3";

  /** The F4 key */
  static const String F4 = "F4";

  /** The F5 key */
  static const String F5 = "F5";

  /** The F6 key */
  static const String F6 = "F6";

  /** The F7 key */
  static const String F7 = "F7";

  /** The F8 key */
  static const String F8 = "F8";

  /** The F9 key */
  static const String F9 = "F9";

  /** The F10 key */
  static const String F10 = "F10";

  /** The F11 key */
  static const String F11 = "F11";

  /** The F12 key */
  static const String F12 = "F12";

  /** The F13 key */
  static const String F13 = "F13";

  /** The F14 key */
  static const String F14 = "F14";

  /** The F15 key */
  static const String F15 = "F15";

  /** The F16 key */
  static const String F16 = "F16";

  /** The F17 key */
  static const String F17 = "F17";

  /** The F18 key */
  static const String F18 = "F18";

  /** The F19 key */
  static const String F19 = "F19";

  /** The F20 key */
  static const String F20 = "F20";

  /** The F21 key */
  static const String F21 = "F21";

  /** The F22 key */
  static const String F22 = "F22";

  /** The F23 key */
  static const String F23 = "F23";

  /** The F24 key */
  static const String F24 = "F24";

  /** The Final Mode (Final) key used on some asian keyboards */
  static const String FINAL_MODE = "FinalMode";

  /** The Find key */
  static const String FIND = "Find";

  /** The Full-Width Characters key */
  static const String FULL_WIDTH = "FullWidth";

  /** The Half-Width Characters key */
  static const String HALF_WIDTH = "HalfWidth";

  /** The Hangul (Korean characters) Mode key */
  static const String HANGUL_MODE = "HangulMode";

  /** The Hanja (Korean characters) Mode key */
  static const String HANJA_MODE = "HanjaMode";

  /** The Help key */
  static const String HELP = "Help";

  /** The Hiragana (Japanese Kana characters) key */
  static const String HIRAGANA = "Hiragana";

  /** The Home key */
  static const String HOME = "Home";

  /** The Insert (Ins) key */
  static const String INSERT = "Insert";

  /** The Japanese-Hiragana key */
  static const String JAPANESE_HIRAGANA = "JapaneseHiragana";

  /** The Japanese-Katakana key */
  static const String JAPANESE_KATAKANA = "JapaneseKatakana";

  /** The Japanese-Romaji key */
  static const String JAPANESE_ROMAJI = "JapaneseRomaji";

  /** The Junja Mode key */
  static const String JUNJA_MODE = "JunjaMode";

  /** The Kana Mode (Kana Lock) key */
  static const String KANA_MODE = "KanaMode";

  /**
   * The Kanji (Japanese name for ideographic characters of Chinese origin)
   * Mode key
   */
  static const String KANJI_MODE = "KanjiMode";

  /** The Katakana (Japanese Kana characters) key */
  static const String KATAKANA = "Katakana";

  /** The Start Application One key */
  static const String LAUNCH_APPLICATION_1 = "LaunchApplication1";

  /** The Start Application Two key */
  static const String LAUNCH_APPLICATION_2 = "LaunchApplication2";

  /** The Start Mail key */
  static const String LAUNCH_MAIL = "LaunchMail";

  /** The Left Arrow key */
  static const String LEFT = "Left";

  /** The Menu key */
  static const String MENU = "Menu";

  /**
   * The Meta key. Note: This key value shall be also used for the Apple
   * Command key
   */
  static const String META = "Meta";

  /** The Media Next Track key */
  static const String MEDIA_NEXT_TRACK = "MediaNextTrack";

  /** The Media Play Pause key */
  static const String MEDIA_PAUSE_PLAY = "MediaPlayPause";

  /** The Media Previous Track key */
  static const String MEDIA_PREVIOUS_TRACK = "MediaPreviousTrack";

  /** The Media Stop key */
  static const String MEDIA_STOP = "MediaStop";

  /** The Mode Change key */
  static const String MODE_CHANGE = "ModeChange";

  /** The Next Candidate function key */
  static const String NEXT_CANDIDATE = "NextCandidate";

  /** The Nonconvert (Don't Convert) key */
  static const String NON_CONVERT = "Nonconvert";

  /** The Number Lock key */
  static const String NUM_LOCK = "NumLock";

  /** The Page Down (Next) key */
  static const String PAGE_DOWN = "PageDown";

  /** The Page Up key */
  static const String PAGE_UP = "PageUp";

  /** The Paste key */
  static const String PASTE = "Paste";

  /** The Pause key */
  static const String PAUSE = "Pause";

  /** The Play key */
  static const String PLAY = "Play";

  /**
   * The Power key. Note: Some devices may not expose this key to the
   * operating environment
   */
  static const String POWER = "Power";

  /** The Previous Candidate function key */
  static const String PREVIOUS_CANDIDATE = "PreviousCandidate";

  /** The Print Screen (PrintScrn, SnapShot) key */
  static const String PRINT_SCREEN = "PrintScreen";

  /** The Process key */
  static const String PROCESS = "Process";

  /** The Props key */
  static const String PROPS = "Props";

  /** The Right Arrow key */
  static const String RIGHT = "Right";

  /** The Roman Characters function key */
  static const String ROMAN_CHARACTERS = "RomanCharacters";

  /** The Scroll Lock key */
  static const String SCROLL = "Scroll";

  /** The Select key */
  static const String SELECT = "Select";

  /** The Select Media key */
  static const String SELECT_MEDIA = "SelectMedia";

  /** The Separator key */
  static const String SEPARATOR = "Separator";

  /** The Shift key */
  static const String SHIFT = "Shift";

  /** The Soft1 key */
  static const String SOFT_1 = "Soft1";

  /** The Soft2 key */
  static const String SOFT_2 = "Soft2";

  /** The Soft3 key */
  static const String SOFT_3 = "Soft3";

  /** The Soft4 key */
  static const String SOFT_4 = "Soft4";

  /** The Stop key */
  static const String STOP = "Stop";

  /** The Subtract key */
  static const String SUBTRACT = "Subtract";

  /** The Symbol Lock key */
  static const String SYMBOL_LOCK = "SymbolLock";

  /** The Up Arrow key */
  static const String UP = "Up";

  /** The diagonal Up-Left Arrow key */
  static const String UP_LEFT = "UpLeft";

  /** The diagonal Up-Right Arrow key */
  static const String UP_RIGHT = "UpRight";

  /** The Undo key */
  static const String UNDO = "Undo";

  /** The Volume Down key */
  static const String VOLUME_DOWN = "VolumeDown";

  /** The Volume Mute key */
  static const String VOLUMN_MUTE = "VolumeMute";

  /** The Volume Up key */
  static const String VOLUMN_UP = "VolumeUp";

  /** The Windows Logo key */
  static const String WIN = "Win";

  /** The Zoom key */
  static const String ZOOM = "Zoom";

  /**
   * The Backspace (Back) key. Note: This key value shall be also used for the
   * key labeled 'delete' MacOS keyboards when not modified by the 'Fn' key
   */
  static const String BACKSPACE = "Backspace";

  /** The Horizontal Tabulation (Tab) key */
  static const String TAB = "Tab";

  /** The Cancel key */
  static const String CANCEL = "Cancel";

  /** The Escape (Esc) key */
  static const String ESC = "Esc";

  /** The Space (Spacebar) key:   */
  static const String SPACEBAR = "Spacebar";

  /**
   * The Delete (Del) Key. Note: This key value shall be also used for the key
   * labeled 'delete' MacOS keyboards when modified by the 'Fn' key
   */
  static const String DEL = "Del";

  /** The Combining Grave Accent (Greek Varia, Dead Grave) key */
  static const String DEAD_GRAVE = "DeadGrave";

  /**
   * The Combining Acute Accent (Stress Mark, Greek Oxia, Tonos, Dead Eacute)
   * key
   */
  static const String DEAD_EACUTE = "DeadEacute";

  /** The Combining Circumflex Accent (Hat, Dead Circumflex) key */
  static const String DEAD_CIRCUMFLEX = "DeadCircumflex";

  /** The Combining Tilde (Dead Tilde) key */
  static const String DEAD_TILDE = "DeadTilde";

  /** The Combining Macron (Long, Dead Macron) key */
  static const String DEAD_MACRON = "DeadMacron";

  /** The Combining Breve (Short, Dead Breve) key */
  static const String DEAD_BREVE = "DeadBreve";

  /** The Combining Dot Above (Derivative, Dead Above Dot) key */
  static const String DEAD_ABOVE_DOT = "DeadAboveDot";

  /**
   * The Combining Diaeresis (Double Dot Abode, Umlaut, Greek Dialytika,
   * Double Derivative, Dead Diaeresis) key
   */
  static const String DEAD_UMLAUT = "DeadUmlaut";

  /** The Combining Ring Above (Dead Above Ring) key */
  static const String DEAD_ABOVE_RING = "DeadAboveRing";

  /** The Combining Double Acute Accent (Dead Doubleacute) key */
  static const String DEAD_DOUBLEACUTE = "DeadDoubleacute";

  /** The Combining Caron (Hacek, V Above, Dead Caron) key */
  static const String DEAD_CARON = "DeadCaron";

  /** The Combining Cedilla (Dead Cedilla) key */
  static const String DEAD_CEDILLA = "DeadCedilla";

  /** The Combining Ogonek (Nasal Hook, Dead Ogonek) key */
  static const String DEAD_OGONEK = "DeadOgonek";

  /**
   * The Combining Greek Ypogegrammeni (Greek Non-Spacing Iota Below, Iota
   * Subscript, Dead Iota) key
   */
  static const String DEAD_IOTA = "DeadIota";

  /**
   * The Combining Katakana-Hiragana Voiced Sound Mark (Dead Voiced Sound) key
   */
  static const String DEAD_VOICED_SOUND = "DeadVoicedSound";

  /**
   * The Combining Katakana-Hiragana Semi-Voiced Sound Mark (Dead Semivoiced
   * Sound) key
   */
  static const String DEC_SEMIVOICED_SOUND= "DeadSemivoicedSound";

  /**
   * Key value used when an implementation is unable to identify another key
   * value, due to either hardware, platform, or software constraints
   */
  static const String UNIDENTIFIED = "Unidentified";
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * Internal class that does the actual calculations to determine keyCode and
 * charCode for keydown, keypress, and keyup events for all browsers.
 */
class _KeyboardEventHandler extends EventStreamProvider<KeyEvent> {
  // This code inspired by Closure's KeyHandling library.
  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keyhandler.js.source.html

  /**
   * The set of keys that have been pressed down without seeing their
   * corresponding keyup event.
   */
  final List<KeyboardEvent> _keyDownList = <KeyboardEvent>[];

  /** The type of KeyEvent we are tracking (keyup, keydown, keypress). */
  final String _type;

  /** The element we are watching for events to happen on. */
  final EventTarget _target;

  // The distance to shift from upper case alphabet Roman letters to lower case.
  static final int _ROMAN_ALPHABET_OFFSET = "a".codeUnits[0] - "A".codeUnits[0];

  /** Custom Stream (Controller) to produce KeyEvents for the stream. */
  _CustomKeyEventStreamImpl _stream;

  static const _EVENT_TYPE = 'KeyEvent';

  /**
   * An enumeration of key identifiers currently part of the W3C draft for DOM3
   * and their mappings to keyCodes.
   * http://www.w3.org/TR/DOM-Level-3-Events/keyset.html#KeySet-Set
   */
  static const Map<String, int> _keyIdentifier = const {
    'Up': KeyCode.UP,
    'Down': KeyCode.DOWN,
    'Left': KeyCode.LEFT,
    'Right': KeyCode.RIGHT,
    'Enter': KeyCode.ENTER,
    'F1': KeyCode.F1,
    'F2': KeyCode.F2,
    'F3': KeyCode.F3,
    'F4': KeyCode.F4,
    'F5': KeyCode.F5,
    'F6': KeyCode.F6,
    'F7': KeyCode.F7,
    'F8': KeyCode.F8,
    'F9': KeyCode.F9,
    'F10': KeyCode.F10,
    'F11': KeyCode.F11,
    'F12': KeyCode.F12,
    'U+007F': KeyCode.DELETE,
    'Home': KeyCode.HOME,
    'End': KeyCode.END,
    'PageUp': KeyCode.PAGE_UP,
    'PageDown': KeyCode.PAGE_DOWN,
    'Insert': KeyCode.INSERT
  };

  /** Return a stream for KeyEvents for the specified target. */
  // Note: this actually functions like a factory constructor.
  CustomStream<KeyEvent> forTarget(EventTarget e, {bool useCapture: false}) {
    var handler = new _KeyboardEventHandler.initializeAllEventListeners(
        _type, e);
    return handler._stream;
  }

  /**
   * General constructor, performs basic initialization for our improved
   * KeyboardEvent controller.
   */
  _KeyboardEventHandler(this._type): super(_EVENT_TYPE),
      _stream = new _CustomKeyEventStreamImpl('event'), _target = null;

  /**
   * Hook up all event listeners under the covers so we can estimate keycodes
   * and charcodes when they are not provided.
   */
  _KeyboardEventHandler.initializeAllEventListeners(this._type, this._target) :
      super(_EVENT_TYPE) {
    Element.keyDownEvent.forTarget(_target, useCapture: true).listen(
        processKeyDown);
    Element.keyPressEvent.forTarget(_target, useCapture: true).listen(
        processKeyPress);
    Element.keyUpEvent.forTarget(_target, useCapture: true).listen(
        processKeyUp);
    _stream = new _CustomKeyEventStreamImpl(_type);
  }

  /** Determine if caps lock is one of the currently depressed keys. */
  bool get _capsLockOn =>
      _keyDownList.any((var element) => element.keyCode == KeyCode.CAPS_LOCK);

  /**
   * Given the previously recorded keydown key codes, see if we can determine
   * the keycode of this keypress [event]. (Generally browsers only provide
   * charCode information for keypress events, but with a little
   * reverse-engineering, we can also determine the keyCode.) Returns
   * KeyCode.UNKNOWN if the keycode could not be determined.
   */
  int _determineKeyCodeForKeypress(KeyboardEvent event) {
    // Note: This function is a work in progress. We'll expand this function
    // once we get more information about other keyboards.
    for (var prevEvent in _keyDownList) {
      if (prevEvent._shadowCharCode == event.charCode) {
        return prevEvent.keyCode;
      }
      if ((event.shiftKey || _capsLockOn) && event.charCode >= "A".codeUnits[0]
          && event.charCode <= "Z".codeUnits[0] && event.charCode +
          _ROMAN_ALPHABET_OFFSET == prevEvent._shadowCharCode) {
        return prevEvent.keyCode;
      }
    }
    return KeyCode.UNKNOWN;
  }

  /**
   * Given the charater code returned from a keyDown [event], try to ascertain
   * and return the corresponding charCode for the character that was pressed.
   * This information is not shown to the user, but used to help polyfill
   * keypress events.
   */
  int _findCharCodeKeyDown(KeyboardEvent event) {
    if (event.keyLocation == 3) { // Numpad keys.
      switch (event.keyCode) {
        case KeyCode.NUM_ZERO:
          // Even though this function returns _charCodes_, for some cases the
          // KeyCode == the charCode we want, in which case we use the keycode
          // constant for readability.
          return KeyCode.ZERO;
        case KeyCode.NUM_ONE:
          return KeyCode.ONE;
        case KeyCode.NUM_TWO:
          return KeyCode.TWO;
        case KeyCode.NUM_THREE:
          return KeyCode.THREE;
        case KeyCode.NUM_FOUR:
          return KeyCode.FOUR;
        case KeyCode.NUM_FIVE:
          return KeyCode.FIVE;
        case KeyCode.NUM_SIX:
          return KeyCode.SIX;
        case KeyCode.NUM_SEVEN:
          return KeyCode.SEVEN;
        case KeyCode.NUM_EIGHT:
          return KeyCode.EIGHT;
        case KeyCode.NUM_NINE:
          return KeyCode.NINE;
        case KeyCode.NUM_MULTIPLY:
          return 42; // Char code for *
        case KeyCode.NUM_PLUS:
          return 43; // +
        case KeyCode.NUM_MINUS:
          return 45; // -
        case KeyCode.NUM_PERIOD:
          return 46; // .
        case KeyCode.NUM_DIVISION:
          return 47; // /
      }
    } else if (event.keyCode >= 65 && event.keyCode <= 90) {
      // Set the "char code" for key down as the lower case letter. Again, this
      // will not show up for the user, but will be helpful in estimating
      // keyCode locations and other information during the keyPress event.
      return event.keyCode + _ROMAN_ALPHABET_OFFSET;
    }
    switch(event.keyCode) {
      case KeyCode.SEMICOLON:
        return KeyCode.FF_SEMICOLON;
      case KeyCode.EQUALS:
        return KeyCode.FF_EQUALS;
      case KeyCode.COMMA:
        return 44; // Ascii value for ,
      case KeyCode.DASH:
        return 45; // -
      case KeyCode.PERIOD:
        return 46; // .
      case KeyCode.SLASH:
        return 47; // /
      case KeyCode.APOSTROPHE:
        return 96; // `
      case KeyCode.OPEN_SQUARE_BRACKET:
        return 91; // [
      case KeyCode.BACKSLASH:
        return 92; // \
      case KeyCode.CLOSE_SQUARE_BRACKET:
        return 93; // ]
      case KeyCode.SINGLE_QUOTE:
        return 39; // '
    }
    return event.keyCode;
  }

  /**
   * Returns true if the key fires a keypress event in the current browser.
   */
  bool _firesKeyPressEvent(KeyEvent event) {
    if (!Device.isIE && !Device.isWebKit) {
      return true;
    }

    if (Device.userAgent.contains('Mac') && event.altKey) {
      return KeyCode.isCharacterKey(event.keyCode);
    }

    // Alt but not AltGr which is represented as Alt+Ctrl.
    if (event.altKey && !event.ctrlKey) {
      return false;
    }

    // Saves Ctrl or Alt + key for IE and WebKit, which won't fire keypress.
    if (!event.shiftKey &&
        (_keyDownList.last.keyCode == KeyCode.CTRL ||
         _keyDownList.last.keyCode == KeyCode.ALT ||
         Device.userAgent.contains('Mac') &&
         _keyDownList.last.keyCode == KeyCode.META)) {
      return false;
    }

    // Some keys with Ctrl/Shift do not issue keypress in WebKit.
    if (Device.isWebKit && event.ctrlKey && event.shiftKey && (
        event.keyCode == KeyCode.BACKSLASH ||
        event.keyCode == KeyCode.OPEN_SQUARE_BRACKET ||
        event.keyCode == KeyCode.CLOSE_SQUARE_BRACKET ||
        event.keyCode == KeyCode.TILDE ||
        event.keyCode == KeyCode.SEMICOLON || event.keyCode == KeyCode.DASH ||
        event.keyCode == KeyCode.EQUALS || event.keyCode == KeyCode.COMMA ||
        event.keyCode == KeyCode.PERIOD || event.keyCode == KeyCode.SLASH ||
        event.keyCode == KeyCode.APOSTROPHE ||
        event.keyCode == KeyCode.SINGLE_QUOTE)) {
      return false;
    }

    switch (event.keyCode) {
      case KeyCode.ENTER:
        // IE9 does not fire keypress on ENTER.
        return !Device.isIE;
      case KeyCode.ESC:
        return !Device.isWebKit;
    }

    return KeyCode.isCharacterKey(event.keyCode);
  }

  /**
   * Normalize the keycodes to the IE KeyCodes (this is what Chrome, IE, and
   * Opera all use).
   */
  int _normalizeKeyCodes(KeyboardEvent event) {
    // Note: This may change once we get input about non-US keyboards.
    if (Device.isFirefox) {
      switch(event.keyCode) {
        case KeyCode.FF_EQUALS:
          return KeyCode.EQUALS;
        case KeyCode.FF_SEMICOLON:
          return KeyCode.SEMICOLON;
        case KeyCode.MAC_FF_META:
          return KeyCode.META;
        case KeyCode.WIN_KEY_FF_LINUX:
          return KeyCode.WIN_KEY;
      }
    }
    return event.keyCode;
  }

  /** Handle keydown events. */
  void processKeyDown(KeyboardEvent e) {
    // Ctrl-Tab and Alt-Tab can cause the focus to be moved to another window
    // before we've caught a key-up event.  If the last-key was one of these
    // we reset the state.
    if (_keyDownList.length > 0 &&
        (_keyDownList.last.keyCode == KeyCode.CTRL && !e.ctrlKey ||
         _keyDownList.last.keyCode == KeyCode.ALT && !e.altKey ||
         Device.userAgent.contains('Mac') &&
         _keyDownList.last.keyCode == KeyCode.META && !e.metaKey)) {
      _keyDownList.clear();
    }

    var event = new KeyEvent.wrap(e);
    event._shadowKeyCode = _normalizeKeyCodes(event);
    // Technically a "keydown" event doesn't have a charCode. This is
    // calculated nonetheless to provide us with more information in giving
    // as much information as possible on keypress about keycode and also
    // charCode.
    event._shadowCharCode = _findCharCodeKeyDown(event);
    if (_keyDownList.length > 0 && event.keyCode != _keyDownList.last.keyCode &&
        !_firesKeyPressEvent(event)) {
      // Some browsers have quirks not firing keypress events where all other
      // browsers do. This makes them more consistent.
      processKeyPress(e);
    }
    _keyDownList.add(event);
    _stream.add(event);
  }

  /** Handle keypress events. */
  void processKeyPress(KeyboardEvent event) {
    var e = new KeyEvent.wrap(event);
    // IE reports the character code in the keyCode field for keypress events.
    // There are two exceptions however, Enter and Escape.
    if (Device.isIE) {
      if (e.keyCode == KeyCode.ENTER || e.keyCode == KeyCode.ESC) {
        e._shadowCharCode = 0;
      } else {
        e._shadowCharCode = e.keyCode;
      }
    } else if (Device.isOpera) {
      // Opera reports the character code in the keyCode field.
      e._shadowCharCode = KeyCode.isCharacterKey(e.keyCode) ? e.keyCode : 0;
    }
    // Now we guestimate about what the keycode is that was actually
    // pressed, given previous keydown information.
    e._shadowKeyCode = _determineKeyCodeForKeypress(e);

    // Correct the key value for certain browser-specific quirks.
    if (e._shadowKeyIdentifier != null &&
        _keyIdentifier.containsKey(e._shadowKeyIdentifier)) {
      // This is needed for Safari Windows because it currently doesn't give a
      // keyCode/which for non printable keys.
      e._shadowKeyCode = _keyIdentifier[e._shadowKeyIdentifier];
    }
    e._shadowAltKey = _keyDownList.any((var element) => element.altKey);
    _stream.add(e);
  }

  /** Handle keyup events. */
  void processKeyUp(KeyboardEvent event) {
    var e = new KeyEvent.wrap(event);
    KeyboardEvent toRemove = null;
    for (var key in _keyDownList) {
      if (key.keyCode == e.keyCode) {
        toRemove = key;
      }
    }
    if (toRemove != null) {
      _keyDownList.removeWhere((element) => element == toRemove);
    } else if (_keyDownList.length > 0) {
      // This happens when we've reached some international keyboard case we
      // haven't accounted for or we haven't correctly eliminated all browser
      // inconsistencies. Filing bugs on when this is reached is welcome!
      _keyDownList.removeLast();
    }
    _stream.add(e);
  }
}


/**
 * Records KeyboardEvents that occur on a particular element, and provides a
 * stream of outgoing KeyEvents with cross-browser consistent keyCode and
 * charCode values despite the fact that a multitude of browsers that have
 * varying keyboard default behavior.
 *
 * Example usage:
 *
 *     KeyboardEventStream.onKeyDown(document.body).listen(
 *         keydownHandlerTest);
 *
 * This class is very much a work in progress, and we'd love to get information
 * on how we can make this class work with as many international keyboards as
 * possible. Bugs welcome!
 */
class KeyboardEventStream {

  /** Named constructor to produce a stream for onKeyPress events. */
  static CustomStream<KeyEvent> onKeyPress(EventTarget target) =>
      new _KeyboardEventHandler('keypress').forTarget(target);

  /** Named constructor to produce a stream for onKeyUp events. */
  static CustomStream<KeyEvent> onKeyUp(EventTarget target) =>
      new _KeyboardEventHandler('keyup').forTarget(target);

  /** Named constructor to produce a stream for onKeyDown events. */
  static CustomStream<KeyEvent> onKeyDown(EventTarget target) =>
      new _KeyboardEventHandler('keydown').forTarget(target);
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.



/**
 * Class which helps construct standard node validation policies.
 *
 * By default this will not accept anything, but the 'allow*' functions can be
 * used to expand what types of elements or attributes are allowed.
 *
 * All allow functions are additive- elements will be accepted if they are
 * accepted by any specific rule.
 *
 * It is important to remember that sanitization is not just intended to prevent
 * cross-site scripting attacks, but also to prevent information from being
 * displayed in unexpected ways. For example something displaying basic
 * formatted text may not expect `<video>` tags to appear. In this case an
 * empty NodeValidatorBuilder with just [allowTextElements] might be
 * appropriate.
 */
class NodeValidatorBuilder implements NodeValidator {

  final List<NodeValidator> _validators = <NodeValidator>[];

  NodeValidatorBuilder() {
  }

  /**
   * Creates a new NodeValidatorBuilder which accepts common constructs.
   *
   * By default this will accept HTML5 elements and attributes with the default
   * [UriPolicy] and templating elements.
   *
   * Notable syntax which is filtered:
   *
   * * Only known-good HTML5 elements and attributes are allowed.
   * * All URLs must be same-origin, use [allowNavigation] and [allowImages] to
   * specify additional URI policies.
   * * Inline-styles are not allowed.
   * * Custom element tags are disallowed, use [allowCustomElement].
   * * Custom tags extensions are disallowed, use [allowTagExtension].
   * * SVG Elements are not allowed, use [allowSvg].
   *
   * For scenarios where the HTML should only contain formatted text
   * [allowTextElements] is more appropriate.
   *
   * Use [allowSvg] to allow SVG elements.
   */
  NodeValidatorBuilder.common() {
    allowHtml5();
    allowTemplating();
  }

  /**
   * Allows navigation elements- Form and Anchor tags, along with common
   * attributes.
   *
   * The UriPolicy can be used to restrict the locations the navigation elements
   * are allowed to direct to. By default this will use the default [UriPolicy].
   */
  void allowNavigation([UriPolicy uriPolicy]) {
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }
    add(new _SimpleNodeValidator.allowNavigation(uriPolicy));
  }

  /**
   * Allows image elements.
   *
   * The UriPolicy can be used to restrict the locations the images may be
   * loaded from. By default this will use the default [UriPolicy].
   */
  void allowImages([UriPolicy uriPolicy]) {
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }
    add(new _SimpleNodeValidator.allowImages(uriPolicy));
  }

  /**
   * Allow basic text elements.
   *
   * This allows a subset of HTML5 elements, specifically just these tags and
   * no attributes.
   *
   * * B
   * * BLOCKQUOTE
   * * BR
   * * EM
   * * H1
   * * H2
   * * H3
   * * H4
   * * H5
   * * H6
   * * HR
   * * I
   * * LI
   * * OL
   * * P
   * * SPAN
   * * UL
   */
  void allowTextElements() {
    add(new _SimpleNodeValidator.allowTextElements());
  }

  /**
   * Allow inline styles on elements.
   *
   * If [tagName] is not specified then this allows inline styles on all
   * elements. Otherwise tagName limits the styles to the specified elements.
   */
  void allowInlineStyles({String tagName}) {
    if (tagName == null) {
      tagName = '*';
    } else {
      tagName = tagName.toUpperCase();
    }
    add(new _SimpleNodeValidator(null, allowedAttributes: ['$tagName::style']));
  }

  /**
   * Allow common safe HTML5 elements and attributes.
   *
   * This list is based off of the Caja whitelists at:
   * https://code.google.com/p/google-caja/wiki/CajaWhitelists.
   *
   * Common things which are not allowed are script elements, style attributes
   * and any script handlers.
   */
  void allowHtml5({UriPolicy uriPolicy}) {
    add(new _Html5NodeValidator(uriPolicy: uriPolicy));
  }

  /**
   * Allow SVG elements and attributes except for known bad ones.
   */
  void allowSvg() {
    add(new _SvgNodeValidator());
  }

  /**
   * Allow custom elements with the specified tag name and specified attributes.
   *
   * This will allow the elements as custom tags (such as <x-foo></x-foo>),
   * but will not allow tag extensions. Use [allowTagExtension] to allow
   * tag extensions.
   */
  void allowCustomElement(String tagName,
      {UriPolicy uriPolicy,
      Iterable<String> attributes,
      Iterable<String> uriAttributes}) {

    var tagNameUpper = tagName.toUpperCase();
    var attrs;
    if (attributes != null) {
      attrs =
          attributes.map((name) => '$tagNameUpper::${name.toLowerCase()}');
    }
    var uriAttrs;
    if (uriAttributes != null) {
      uriAttrs =
          uriAttributes.map((name) => '$tagNameUpper::${name.toLowerCase()}');
    }
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }

    add(new _CustomElementNodeValidator(
        uriPolicy,
        [tagNameUpper],
        attrs,
        uriAttrs,
        false,
        true));
  }

  /**
   * Allow custom tag extensions with the specified type name and specified
   * attributes.
   *
   * This will allow tag extensions (such as <div is="x-foo"></div>),
   * but will not allow custom tags. Use [allowCustomElement] to allow
   * custom tags.
   */
  void allowTagExtension(String tagName, String baseName,
      {UriPolicy uriPolicy,
      Iterable<String> attributes,
      Iterable<String> uriAttributes}) {

    var baseNameUpper = baseName.toUpperCase();
    var tagNameUpper = tagName.toUpperCase();
    var attrs;
    if (attributes != null) {
      attrs =
          attributes.map((name) => '$baseNameUpper::${name.toLowerCase()}');
    }
    var uriAttrs;
    if (uriAttributes != null) {
      uriAttrs =
          uriAttributes.map((name) => '$baseNameUpper::${name.toLowerCase()}');
    }
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }

    add(new _CustomElementNodeValidator(
        uriPolicy,
        [tagNameUpper, baseNameUpper],
        attrs,
        uriAttrs,
        true,
        false));
  }

  void allowElement(String tagName, {UriPolicy uriPolicy,
    Iterable<String> attributes,
    Iterable<String> uriAttributes}) {

    allowCustomElement(tagName, uriPolicy: uriPolicy,
        attributes: attributes,
        uriAttributes: uriAttributes);
  }

  /**
   * Allow templating elements (such as <template> and template-related
   * attributes.
   *
   * This still requires other validators to allow regular attributes to be
   * bound (such as [allowHtml5]).
   */
  void allowTemplating() {
    add(new _TemplatingNodeValidator());
  }

  /**
   * Add an additional validator to the current list of validators.
   *
   * Elements and attributes will be accepted if they are accepted by any
   * validators.
   */
  void add(NodeValidator validator) {
    _validators.add(validator);
  }

  bool allowsElement(Element element) {
    return _validators.any((v) => v.allowsElement(element));
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    return _validators.any(
        (v) => v.allowsAttribute(element, attributeName, value));
  }
}

class _SimpleNodeValidator implements NodeValidator {
  final Set<String> allowedElements;
  final Set<String> allowedAttributes;
  final Set<String> allowedUriAttributes;
  final UriPolicy uriPolicy;

  factory _SimpleNodeValidator.allowNavigation(UriPolicy uriPolicy) {
    return new _SimpleNodeValidator(uriPolicy,
      allowedElements: [
        'A',
        'FORM'],
      allowedAttributes: [
        'A::accesskey',
        'A::coords',
        'A::hreflang',
        'A::name',
        'A::shape',
        'A::tabindex',
        'A::target',
        'A::type',
        'FORM::accept',
        'FORM::autocomplete',
        'FORM::enctype',
        'FORM::method',
        'FORM::name',
        'FORM::novalidate',
        'FORM::target',
      ],
      allowedUriAttributes: [
        'A::href',
        'FORM::action',
      ]);
  }

  factory _SimpleNodeValidator.allowImages(UriPolicy uriPolicy) {
    return new _SimpleNodeValidator(uriPolicy,
      allowedElements: [
        'IMG'
      ],
      allowedAttributes: [
        'IMG::align',
        'IMG::alt',
        'IMG::border',
        'IMG::height',
        'IMG::hspace',
        'IMG::ismap',
        'IMG::name',
        'IMG::usemap',
        'IMG::vspace',
        'IMG::width',
      ],
      allowedUriAttributes: [
        'IMG::src',
      ]);
  }

  factory _SimpleNodeValidator.allowTextElements() {
    return new _SimpleNodeValidator(null,
      allowedElements: [
        'B',
        'BLOCKQUOTE',
        'BR',
        'EM',
        'H1',
        'H2',
        'H3',
        'H4',
        'H5',
        'H6',
        'HR',
        'I',
        'LI',
        'OL',
        'P',
        'SPAN',
        'UL',
      ]);
  }

  /**
   * Elements must be uppercased tag names. For example `'IMG'`.
   * Attributes must be uppercased tag name followed by :: followed by
   * lowercase attribute name. For example `'IMG:src'`.
   */
  _SimpleNodeValidator(this.uriPolicy,
      {Iterable<String> allowedElements, Iterable<String> allowedAttributes,
      Iterable<String> allowedUriAttributes}):
      this.allowedElements = allowedElements != null ?
          new Set.from(allowedElements) : new Set(),
      this.allowedAttributes = allowedAttributes != null ?
          new Set.from(allowedAttributes) : new Set(),
      this.allowedUriAttributes = allowedUriAttributes != null ?
          new Set.from(allowedUriAttributes) : new Set();

  bool allowsElement(Element element) {
    return allowedElements.contains(element.tagName);
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    var tagName = element.tagName;
    if (allowedUriAttributes.contains('$tagName::$attributeName')) {
      return uriPolicy.allowsUri(value);
    } else if (allowedUriAttributes.contains('*::$attributeName')) {
      return uriPolicy.allowsUri(value);
    } else if (allowedAttributes.contains('$tagName::$attributeName')) {
      return true;
    } else if (allowedAttributes.contains('*::$attributeName')) {
      return true;
    } else if (allowedAttributes.contains('$tagName::*')) {
      return true;
    } else if (allowedAttributes.contains('*::*')) {
      return true;
    }
    return false;
  }
}

class _CustomElementNodeValidator extends _SimpleNodeValidator {
  final bool allowTypeExtension;
  final bool allowCustomTag;

  _CustomElementNodeValidator(UriPolicy uriPolicy,
      Iterable<String> allowedElements,
      Iterable<String> allowedAttributes,
      Iterable<String> allowedUriAttributes,
      bool allowTypeExtension,
      bool allowCustomTag):

      super(uriPolicy,
          allowedElements: allowedElements,
          allowedAttributes: allowedAttributes,
          allowedUriAttributes: allowedUriAttributes),
      this.allowTypeExtension = allowTypeExtension == true,
      this.allowCustomTag = allowCustomTag == true;

  bool allowsElement(Element element) {
    if (allowTypeExtension) {
      var isAttr = element.attributes['is'];
      if (isAttr != null) {
        return allowedElements.contains(isAttr.toUpperCase()) &&
          allowedElements.contains(element.tagName);
      }
    }
    return allowCustomTag && allowedElements.contains(element.tagName);
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
   if (allowsElement(element)) {
      if (allowTypeExtension && attributeName == 'is' &&
          allowedElements.contains(value.toUpperCase())) {
        return true;
      }
      return super.allowsAttribute(element, attributeName, value);
    }
    return false;
  }
}

class _TemplatingNodeValidator extends _SimpleNodeValidator {
  static const _TEMPLATE_ATTRS =
      const <String>['bind', 'if', 'ref', 'repeat', 'syntax'];

  final Set<String> _templateAttrs;

  _TemplatingNodeValidator():
      super(null,
          allowedElements: [
            'TEMPLATE'
          ],
          allowedAttributes: _TEMPLATE_ATTRS.map((attr) => 'TEMPLATE::$attr')),
      _templateAttrs = new Set<String>.from(_TEMPLATE_ATTRS) {
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (super.allowsAttribute(element, attributeName, value)) {
      return true;
    }

    if (attributeName == 'template' && value == "") {
      return true;
    }

    if (element.attributes['template'] == "" ) {
      return _templateAttrs.contains(attributeName);
    }
    return false;
  }
}


class _SvgNodeValidator implements NodeValidator {
  bool allowsElement(Element element) {
    if (element is svg.ScriptElement) {
      return false;
    }
    if (element is svg.SvgElement) {
      return true;
    }
    return false;
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (attributeName == 'is' || attributeName.startsWith('on')) {
      return false;
    }
    return allowsElement(element);
  }
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * Contains the set of standard values returned by HTMLDocument.getReadyState.
 */
abstract class ReadyState {
  /**
   * Indicates the document is still loading and parsing.
   */
  static const String LOADING = "loading";

  /**
   * Indicates the document is finished parsing but is still loading
   * subresources.
   */
  static const String INTERACTIVE = "interactive";

  /**
   * Indicates the document and all subresources have been loaded.
   */
  static const String COMPLETE = "complete";
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * A list which just wraps another list, for either intercepting list calls or
 * retyping the list (for example, from List<A> to List<B> where B extends A).
 */
class _WrappedList<E extends Node> extends ListBase<E>
    implements NodeListWrapper {
  final List _list;

  _WrappedList(this._list);

  // Iterable APIs

  Iterator<E> get iterator => new _WrappedIterator(_list.iterator);

  int get length => _list.length;

  // Collection APIs

  void add(E element) { _list.add(element); }

  bool remove(Object element) => _list.remove(element);

  void clear() { _list.clear(); }

  // List APIs

  E operator [](int index) => _list[index];

  void operator []=(int index, E value) { _list[index] = value; }

  void set length(int newLength) { _list.length = newLength; }

  void sort([int compare(E a, E b)]) { _list.sort(compare); }

  int indexOf(Object element, [int start = 0]) => _list.indexOf(element, start);

  int lastIndexOf(Object element, [int start]) => _list.lastIndexOf(element, start);

  void insert(int index, E element) => _list.insert(index, element);

  E removeAt(int index) => _list.removeAt(index);

  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
    _list.setRange(start, end, iterable, skipCount);
  }

  void removeRange(int start, int end) { _list.removeRange(start, end); }

  void replaceRange(int start, int end, Iterable<E> iterable) {
    _list.replaceRange(start, end, iterable);
  }

  void fillRange(int start, int end, [E fillValue]) {
    _list.fillRange(start, end, fillValue);
  }

  List<Node> get rawList => _list;
}

/**
 * Iterator wrapper for _WrappedList.
 */
class _WrappedIterator<E> implements Iterator<E> {
  Iterator _iterator;

  _WrappedIterator(this._iterator);

  bool moveNext() {
    return _iterator.moveNext();
  }

  E get current => _iterator.current;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


class _HttpRequestUtils {

  // Helper for factory HttpRequest.get
  static HttpRequest get(String url,
                            onComplete(HttpRequest request),
                            bool withCredentials) {
    final request = new HttpRequest();
    request.open('GET', url, async: true);

    request.withCredentials = withCredentials;

    request.onReadyStateChange.listen((e) {
      if (request.readyState == HttpRequest.DONE) {
        onComplete(request);
      }
    });

    request.send();

    return request;
  }
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


// Iterator for arrays with fixed size.
class FixedSizeListIterator<T> implements Iterator<T> {
  final List<T> _array;
  final int _length;  // Cache array length for faster access.
  int _position;
  T _current;
  
  FixedSizeListIterator(List<T> array)
      : _array = array,
        _position = -1,
        _length = array.length;

  bool moveNext() {
    int nextPosition = _position + 1;
    if (nextPosition < _length) {
      _current = _array[nextPosition];
      _position = nextPosition;
      return true;
    }
    _current = null;
    _position = _length;
    return false;
  }

  T get current => _current;
}

// Iterator for arrays with variable size.
class _VariableSizeListIterator<T> implements Iterator<T> {
  final List<T> _array;
  int _position;
  T _current;

  _VariableSizeListIterator(List<T> array)
      : _array = array,
        _position = -1;

  bool moveNext() {
    int nextPosition = _position + 1;
    if (nextPosition < _array.length) {
      _current = _array[nextPosition];
      _position = nextPosition;
      return true;
    }
    _current = null;
    _position = _array.length;
    return false;
  }

  T get current => _current;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


// Conversions for Window.  These check if the window is the local
// window, and if it's not, wraps or unwraps it with a secure wrapper.
// We need to test for EventTarget here as well as it's a base type.
// We omit an unwrapper for Window as no methods take a non-local
// window as a parameter.


WindowBase _convertNativeToDart_Window(win) {
  if (win == null) return null;
  return _DOMWindowCrossFrame._createSafe(win);
}

EventTarget _convertNativeToDart_EventTarget(e) {
  if (e == null) {
    return null;
  }
  // Assume it's a Window if it contains the setInterval property.  It may be
  // from a different frame - without a patched prototype - so we cannot
  // rely on Dart type checking.
  if (JS('bool', r'"setInterval" in #', e)) {
    var window = _DOMWindowCrossFrame._createSafe(e);
    // If it's a native window.
    if (window is EventTarget) {
      return window;
    }
    return null;
  }
  else
    return e;
}

EventTarget _convertDartToNative_EventTarget(e) {
  if (e is _DOMWindowCrossFrame) {
    return e._window;
  } else {
    return e;
  }
}

_convertNativeToDart_XHR_Response(o) {
  if (o is Document) {
    return o;
  }
  return convertNativeToDart_SerializedScriptValue(o);
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


_callConstructor(constructor, interceptor) {
  return (receiver) {
    setNativeSubclassDispatchRecord(receiver, interceptor);

    // Mirrors uses the constructor property to cache lookups, so we need it to
    // be set correctly, including on IE where it is not automatically picked
    // up from the __proto__.
    JS('', '#.constructor = #.__proto__.constructor', receiver, receiver);
    return JS('', '#(#)', constructor, receiver);
  };
}

_callAttached(receiver) {
  return receiver.attached();
}

_callDetached(receiver) {
  return receiver.detached();
}
 _callAttributeChanged(receiver, name, oldValue, newValue) {
  return receiver.attributeChanged(name, oldValue, newValue);
}

_makeCallbackMethod(callback) {
  return JS('',
      '''((function(invokeCallback) {
             return function() {
               return invokeCallback(this);
             };
          })(#))''',
      convertDartClosureToJS(callback, 1));
}

_makeCallbackMethod3(callback) {
  return JS('',
      '''((function(invokeCallback) {
             return function(arg1, arg2, arg3) {
               return invokeCallback(this, arg1, arg2, arg3);
             };
          })(#))''',
      convertDartClosureToJS(callback, 4));
}

void _registerCustomElement(context, document, String tag, Type type,
    String extendsTagName) {
  // Function follows the same pattern as the following JavaScript code for
  // registering a custom element.
  //
  //    var proto = Object.create(HTMLElement.prototype, {
  //        createdCallback: {
  //          value: function() {
  //            window.console.log('here');
  //          }
  //        }
  //    });
  //    document.registerElement('x-foo', { prototype: proto });
  //    ...
  //    var e = document.createElement('x-foo');

  var interceptorClass = findInterceptorConstructorForType(type);
  if (interceptorClass == null) {
    throw new ArgumentError(type);
  }

  var interceptor = JS('=Object', '#.prototype', interceptorClass);

  var constructor = findConstructorForNativeSubclassType(type, 'created');
  if (constructor == null) {
    throw new ArgumentError("$type has no constructor called 'created'");
  }

  // Workaround for 13190- use an article element to ensure that HTMLElement's
  // interceptor is resolved correctly.
  getNativeInterceptor(new Element.tag('article'));

  String baseClassName = findDispatchTagForInterceptorClass(interceptorClass);
  if (baseClassName == null) {
    throw new ArgumentError(type);
  }

  if (extendsTagName == null) {
    if (baseClassName != 'HTMLElement') {
      throw new UnsupportedError('Class must provide extendsTag if base '
          'native class is not HtmlElement');
    }
  } else {
    if (!JS('bool', '(#.createElement(#) instanceof window[#])',
        document, extendsTagName, baseClassName)) {
      throw new UnsupportedError('extendsTag does not match base native class');
    }
  }

  var baseConstructor = JS('=Object', '#[#]', context, baseClassName);

  var properties = JS('=Object', '{}');

  JS('void', '#.createdCallback = #', properties,
      JS('=Object', '{value: #}',
          _makeCallbackMethod(_callConstructor(constructor, interceptor))));
  JS('void', '#.attachedCallback = #', properties,
      JS('=Object', '{value: #}', _makeCallbackMethod(_callAttached)));
  JS('void', '#.detachedCallback = #', properties,
      JS('=Object', '{value: #}', _makeCallbackMethod(_callDetached)));
  JS('void', '#.attributeChangedCallback = #', properties,
      JS('=Object', '{value: #}', _makeCallbackMethod3(_callAttributeChanged)));

  var baseProto = JS('=Object', '#.prototype', baseConstructor);
  var proto = JS('=Object', 'Object.create(#, #)', baseProto, properties);

  setNativeSubclassDispatchRecord(proto, interceptor);

  var options = JS('=Object', '{prototype: #}', proto);

  if (extendsTagName != null) {
    JS('=Object', '#.extends = #', options, extendsTagName);
  }

  JS('void', '#.registerElement(#, #)', document, tag, options);
}

//// Called by Element.created to do validation & initialization.
void _initializeCustomElement(Element e) {
  // TODO(blois): Add validation that this is only in response to an upgrade.
}

/// Dart2JS implementation of ElementUpgrader
class _JSElementUpgrader implements ElementUpgrader {
  var _interceptor;
  var _constructor;
  var _nativeType;

  _JSElementUpgrader(Document document, Type type, String extendsTag) {
    var interceptorClass = findInterceptorConstructorForType(type);
    if (interceptorClass == null) {
      throw new ArgumentError(type);
    }

    _constructor = findConstructorForNativeSubclassType(type, 'created');
    if (_constructor == null) {
      throw new ArgumentError("$type has no constructor called 'created'");
    }

    // Workaround for 13190- use an article element to ensure that HTMLElement's
    // interceptor is resolved correctly.
    getNativeInterceptor(new Element.tag('article'));

    var baseClassName = findDispatchTagForInterceptorClass(interceptorClass);
    if (baseClassName == null) {
      throw new ArgumentError(type);
    }

    if (extendsTag == null) {
      if (baseClassName != 'HTMLElement') {
        throw new UnsupportedError('Class must provide extendsTag if base '
            'native class is not HtmlElement');
      }
      _nativeType = HtmlElement;
    } else {
      var element = document.createElement(extendsTag);
      if (!JS('bool', '(# instanceof window[#])',
          element, baseClassName)) {
        throw new UnsupportedError(
            'extendsTag does not match base native class');
      }
      _nativeType = element.runtimeType;
    }

    _interceptor = JS('=Object', '#.prototype', interceptorClass);
  }

  Element upgrade(Element element) {
    // Only exact type matches are supported- cannot be a subclass.
    if (element.runtimeType != _nativeType) {
      throw new ArgumentError('element is not subclass of $_nativeType');
    }

    setNativeSubclassDispatchRecord(element, _interceptor);
    JS('', '#(#)', _constructor, element);
    return element;
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


// TODO(vsm): Unify with Dartium version.
class _DOMWindowCrossFrame implements WindowBase {
  // Private window.  Note, this is a window in another frame, so it
  // cannot be typed as "Window" as its prototype is not patched
  // properly.  Its fields and methods can only be accessed via JavaScript.
  final _window;

  // Fields.
  HistoryBase get history =>
    _HistoryCrossFrame._createSafe(JS('HistoryBase', '#.history', _window));
  LocationBase get location =>
    _LocationCrossFrame._createSafe(JS('LocationBase', '#.location', _window));

  // TODO(vsm): Add frames to navigate subframes.  See 2312.

  bool get closed => JS('bool', '#.closed', _window);

  WindowBase get opener => _createSafe(JS('WindowBase', '#.opener', _window));

  WindowBase get parent => _createSafe(JS('WindowBase', '#.parent', _window));

  WindowBase get top => _createSafe(JS('WindowBase', '#.top', _window));

  // Methods.
  void close() => JS('void', '#.close()', _window);

  void postMessage(var message, String targetOrigin, [List messagePorts = null]) {
    if (messagePorts == null) {
      JS('void', '#.postMessage(#,#)', _window,
          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
  bool dispatchEvent(Event event) => throw new UnsupportedError(
    'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  void removeEventListener(String type, EventListener listener,
      [bool useCapture]) => throw new UnsupportedError(
          'You can only attach EventListeners to your own window.');
}

class _LocationCrossFrame implements LocationBase {
  // Private location.  Note, this is a location object in another frame, so it
  // cannot be typed as "Location" as its prototype is not patched
  // properly.  Its fields and methods can only be accessed via JavaScript.
  var _location;

  void set href(String val) => _setHref(_location, val);
  static void _setHref(location, val) {
    JS('void', '#.href = #', location, val);
  }

  // Implementation support.
  _LocationCrossFrame(this._location);

  static LocationBase _createSafe(location) {
    if (identical(location, window.location)) {
      return location;
    } else {
      // TODO(vsm): Cache or implement equality.
      return new _LocationCrossFrame(location);
    }
  }
}

class _HistoryCrossFrame implements HistoryBase {
  // Private history.  Note, this is a history object in another frame, so it
  // cannot be typed as "History" as its prototype is not patched
  // properly.  Its fields and methods can only be accessed via JavaScript.
  var _history;

  void back() => JS('void', '#.back()', _history);

  void forward() => JS('void', '#.forward()', _history);

  void go(int distance) => JS('void', '#.go(#)', _history, distance);

  // Implementation support.
  _HistoryCrossFrame(this._history);

  static HistoryBase _createSafe(h) {
    if (identical(h, window.history)) {
      return h;
    } else {
      // TODO(vsm): Cache or implement equality.
      return new _HistoryCrossFrame(h);
    }
  }
}
/**
 * A custom KeyboardEvent that attempts to eliminate cross-browser
 * inconsistencies, and also provide both keyCode and charCode information
 * for all key events (when such information can be determined).
 *
 * KeyEvent tries to provide a higher level, more polished keyboard event
 * information on top of the "raw" [KeyboardEvent].
 *
 * The mechanics of using KeyEvents is a little different from the underlying
 * [KeyboardEvent]. To use KeyEvents, you need to create a stream and then add
 * KeyEvents to the stream, rather than using the [EventTarget.dispatchEvent].
 * Here's an example usage:
 *
 *     // Initialize a stream for the KeyEvents:
 *     var stream = KeyEvent.keyPressEvent.forTarget(document.body);
 *     // Start listening to the stream of KeyEvents.
 *     stream.listen((keyEvent) =>
 *         window.console.log('KeyPress event detected ${keyEvent.charCode}'));
 *     ...
 *     // Add a new KeyEvent of someone pressing the 'A' key to the stream so
 *     // listeners can know a KeyEvent happened.
 *     stream.add(new KeyEvent('keypress', keyCode: 65, charCode: 97));
 *
 * This class is very much a work in progress, and we'd love to get information
 * on how we can make this class work with as many international keyboards as
 * possible. Bugs welcome!
 */
@Experimental()
class KeyEvent extends _WrappedEvent implements KeyboardEvent {
  /** The parent KeyboardEvent that this KeyEvent is wrapping and "fixing". */
  KeyboardEvent _parent;

  /** The "fixed" value of whether the alt key is being pressed. */
  bool _shadowAltKey;

  /** Caculated value of what the estimated charCode is for this event. */
  int _shadowCharCode;

  /** Caculated value of what the estimated keyCode is for this event. */
  int _shadowKeyCode;

  /** Caculated value of what the estimated keyCode is for this event. */
  int get keyCode => _shadowKeyCode;

  /** Caculated value of what the estimated charCode is for this event. */
  int get charCode => this.type == 'keypress' ? _shadowCharCode : 0;

  /** Caculated value of whether the alt key is pressed is for this event. */
  bool get altKey => _shadowAltKey;

  /** Caculated value of what the estimated keyCode is for this event. */
  int get which => keyCode;

  /** Accessor to the underlying keyCode value is the parent event. */
  int get _realKeyCode => JS('int', '#.keyCode', _parent);

  /** Accessor to the underlying charCode value is the parent event. */
  int get _realCharCode => JS('int', '#.charCode', _parent);

  /** Accessor to the underlying altKey value is the parent event. */
  bool get _realAltKey => JS('bool', '#.altKey', _parent);

  /** Shadows on top of the parent's currentTarget. */
  EventTarget _currentTarget;

  /**
   * The value we want to use for this object's dispatch. Created here so it is
   * only invoked once.
   */
  static final _keyboardEventDispatchRecord = _makeRecord();

  /** Helper to statically create the dispatch record. */
  static _makeRecord() {
    var interceptor = JS_INTERCEPTOR_CONSTANT(KeyboardEvent);
    return makeLeafDispatchRecord(interceptor);
  }

  /** Construct a KeyEvent with [parent] as the event we're emulating. */
  KeyEvent.wrap(KeyboardEvent parent): super(parent) {
    _parent = parent;
    _shadowAltKey = _realAltKey;
    _shadowCharCode = _realCharCode;
    _shadowKeyCode = _realKeyCode;
    _currentTarget = _parent.currentTarget;
  }

  /** Programmatically create a new KeyEvent (and KeyboardEvent). */
  factory KeyEvent(String type,
      {Window view, bool canBubble: true, bool cancelable: true, int keyCode: 0,
      int charCode: 0, int keyLocation: 1, bool ctrlKey: false,
      bool altKey: false, bool shiftKey: false, bool metaKey: false,
      bool altGraphKey: false, EventTarget currentTarget}) {
    if (view == null) {
      view = window;
    }

    var eventObj;
    // In these two branches we create an underlying native KeyboardEvent, but
    // we set it with our specified values. Because we are doing custom setting
    // of certain values (charCode/keyCode, etc) only in this class (as opposed
    // to KeyboardEvent) and the way we set these custom values depends on the
    // type of underlying JS object, we do all the contruction for the
    // underlying KeyboardEvent here.
    if (canUseDispatchEvent) {
      // Currently works in everything but Internet Explorer.
      eventObj = new Event.eventType('Event', type,
          canBubble: canBubble, cancelable: cancelable);

      JS('void', '#.keyCode = #', eventObj, keyCode);
      JS('void', '#.which = #', eventObj, keyCode);
      JS('void', '#.charCode = #', eventObj, charCode);

      JS('void', '#.keyLocation = #', eventObj, keyLocation);
      JS('void', '#.ctrlKey = #', eventObj, ctrlKey);
      JS('void', '#.altKey = #', eventObj, altKey);
      JS('void', '#.shiftKey = #', eventObj, shiftKey);
      JS('void', '#.metaKey = #', eventObj, metaKey);
      JS('void', '#.altGraphKey = #', eventObj, altGraphKey);
    } else {
      // Currently this works on everything but Safari. Safari throws an
      // "Attempting to change access mechanism for an unconfigurable property"
      // TypeError when trying to do the Object.defineProperty hack, so we avoid
      // this branch if possible.
      // Also, if we want this branch to work in FF, we also need to modify
      // _initKeyboardEvent to also take charCode and keyCode values to
      // initialize initKeyEvent.

      eventObj = new Event.eventType('KeyboardEvent', type,
          canBubble: canBubble, cancelable: cancelable);

      // Chromium Hack
      JS('void', "Object.defineProperty(#, 'keyCode', {"
          "  get : function() { return this.keyCodeVal; } })",  eventObj);
      JS('void', "Object.defineProperty(#, 'which', {"
          "  get : function() { return this.keyCodeVal; } })",  eventObj);
      JS('void', "Object.defineProperty(#, 'charCode', {"
          "  get : function() { return this.charCodeVal; } })",  eventObj);

      var keyIdentifier = _convertToHexString(charCode, keyCode);
      eventObj._initKeyboardEvent(type, canBubble, cancelable, view,
          keyIdentifier, keyLocation, ctrlKey, altKey, shiftKey, metaKey,
          altGraphKey);
      JS('void', '#.keyCodeVal = #', eventObj, keyCode);
      JS('void', '#.charCodeVal = #', eventObj, charCode);
    }
    // Tell dart2js that it smells like a KeyboardEvent!
    setDispatchProperty(eventObj, _keyboardEventDispatchRecord);

    var keyEvent = new KeyEvent.wrap(eventObj);
    if (keyEvent._currentTarget == null) {
      keyEvent._currentTarget = currentTarget == null ? window : currentTarget;
    }
    return keyEvent;
  }

  // Currently known to work on all browsers but IE.
  static bool get canUseDispatchEvent =>
      JS('bool',
         '(typeof document.body.dispatchEvent == "function")'
         '&& document.body.dispatchEvent.length > 0');

  /** The currently registered target for this event. */
  EventTarget get currentTarget => _currentTarget;

  // This is an experimental method to be sure.
  static String _convertToHexString(int charCode, int keyCode) {
    if (charCode != -1) {
      var hex = charCode.toRadixString(16); // Convert to hexadecimal.
      StringBuffer sb = new StringBuffer('U+');
      for (int i = 0; i < 4 - hex.length; i++) sb.write('0');
      sb.write(hex);
      return sb.toString();
    } else {
      return KeyCode._convertKeyCodeToKeyName(keyCode);
    }
  }

  // TODO(efortuna): If KeyEvent is sufficiently successful that we want to make
  // it the default keyboard event handling, move these methods over to Element.
  /** Accessor to provide a stream of KeyEvents on the desired target. */
  static EventStreamProvider<KeyEvent> keyDownEvent =
      new _KeyboardEventHandler('keydown');
  /** Accessor to provide a stream of KeyEvents on the desired target. */
  static EventStreamProvider<KeyEvent> keyUpEvent =
      new _KeyboardEventHandler('keyup');
  /** Accessor to provide a stream of KeyEvents on the desired target. */
  static EventStreamProvider<KeyEvent> keyPressEvent =
      new _KeyboardEventHandler('keypress');

  /** True if the altGraphKey is pressed during this event. */
  bool get altGraphKey => _parent.altGraphKey;
  /** Accessor to the clipboardData available for this event. */
  DataTransfer get clipboardData => _parent.clipboardData;
  /** True if the ctrl key is pressed during this event. */
  bool get ctrlKey => _parent.ctrlKey;
  int get detail => _parent.detail;
  /**
   * Accessor to the part of the keyboard that the key was pressed from (one of
   * KeyLocation.STANDARD, KeyLocation.RIGHT, KeyLocation.LEFT,
   * KeyLocation.NUMPAD, KeyLocation.MOBILE, KeyLocation.JOYSTICK).
   */
  int get keyLocation => _parent.keyLocation;
  Point get layer => _parent.layer;
  /** True if the Meta (or Mac command) key is pressed during this event. */
  bool get metaKey => _parent.metaKey;
  Point get page => _parent.page;
  /** True if the shift key was pressed during this event. */
  bool get shiftKey => _parent.shiftKey;
  Window get view => _parent.view;
  void _initUIEvent(String type, bool canBubble, bool cancelable,
      Window view, int detail) {
    throw new UnsupportedError("Cannot initialize a UI Event from a KeyEvent.");
  }
  String get _shadowKeyIdentifier => JS('String', '#.keyIdentifier', _parent);

  int get _charCode => charCode;
  int get _keyCode => keyCode;
  String get _keyIdentifier {
    throw new UnsupportedError("keyIdentifier is unsupported.");
  }
  void _initKeyboardEvent(String type, bool canBubble, bool cancelable,
      Window view, String keyIdentifier, int keyLocation, bool ctrlKey,
      bool altKey, bool shiftKey, bool metaKey,
      bool altGraphKey) {
    throw new UnsupportedError(
        "Cannot initialize a KeyboardEvent from a KeyEvent.");
  }
  int get _layerX => throw new UnsupportedError('Not applicable to KeyEvent');
  int get _layerY => throw new UnsupportedError('Not applicable to KeyEvent');
  int get _pageX => throw new UnsupportedError('Not applicable to KeyEvent');
  int get _pageY => throw new UnsupportedError('Not applicable to KeyEvent');
  @Experimental() // untriaged
  bool getModifierState(String keyArgument) => throw new UnimplementedError();
  @Experimental() // untriaged
  int get location => throw new UnimplementedError();
  @Experimental() // untriaged
  bool get repeat => throw new UnimplementedError();
  dynamic get _get_view => throw new UnimplementedError();
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


class Platform {
  /**
   * Returns true if dart:typed_data types are supported on this
   * browser.  If false, using these types will generate a runtime
   * error.
   */
  static final supportsTypedData = JS('bool', '!!(window.ArrayBuffer)');

  /**
   * Returns true if SIMD types in dart:typed_data types are supported
   * on this browser.  If false, using these types will generate a runtime
   * error.
   */
  static final supportsSimd = false;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * Helper class to implement custom events which wrap DOM events.
 */
class _WrappedEvent implements Event {
  final Event wrapped;

  /** The CSS selector involved with event delegation. */
  String _selector;

  _WrappedEvent(this.wrapped);

  bool get bubbles => wrapped.bubbles;

  bool get cancelable => wrapped.cancelable;

  DataTransfer get clipboardData => wrapped.clipboardData;

  EventTarget get currentTarget => wrapped.currentTarget;

  bool get defaultPrevented => wrapped.defaultPrevented;

  int get eventPhase => wrapped.eventPhase;

  EventTarget get target => wrapped.target;

  int get timeStamp => wrapped.timeStamp;

  String get type => wrapped.type;

  void _initEvent(String eventTypeArg, bool canBubbleArg,
      bool cancelableArg) {
    throw new UnsupportedError(
        'Cannot initialize this Event.');
  }

  void preventDefault() {
    wrapped.preventDefault();
  }

  void stopImmediatePropagation() {
    wrapped.stopImmediatePropagation();
  }

  void stopPropagation() {
    wrapped.stopPropagation();
  }

  /**
   * A pointer to the element whose CSS selector matched within which an event
   * was fired. If this Event was not associated with any Event delegation,
   * accessing this value will throw an [UnsupportedError].
   */
  Element get matchingTarget {
    if (_selector == null) {
      throw new UnsupportedError('Cannot call matchingTarget if this Event did'
          ' not arise as a result of event delegation.');
    }
    var currentTarget = this.currentTarget;
    var target = this.target;
    var matchedTarget;
    do {
      if (target.matches(_selector)) return target;
      target = target.parent;
    } while (target != null && target != currentTarget.parent);
    throw new StateError('No selector matched for populating matchedTarget.');
  }

  /**
   * This event's path, taking into account shadow DOM.
   *
   * ## Other resources
   *
   * * [Shadow DOM extensions to Event]
   * (http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event) from
   * W3C.
   */
  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#extensions-to-event
  @Experimental()
  List<Node> get path => wrapped.path;

  dynamic get _get_currentTarget => wrapped._get_currentTarget;

  dynamic get _get_target => wrapped._get_target;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


_wrapZone(callback(arg)) {
  // For performance reasons avoid wrapping if we are in the root zone.
  if (Zone.current == Zone.ROOT) return callback;
  if (callback == null) return null;
  return Zone.current.bindUnaryCallback(callback, runGuarded: true);
}

_wrapBinaryZone(callback(arg1, arg2)) {
  if (Zone.current == Zone.ROOT) return callback;
  if (callback == null) return null;
  return Zone.current.bindBinaryCallback(callback, runGuarded: true);
}

/**
 * Alias for [querySelector]. Note this function is deprecated because its
 * semantics will be changing in the future.
 */
@deprecated
@Experimental()
Element query(String relativeSelectors) => document.query(relativeSelectors);
/**
 * Alias for [querySelectorAll]. Note this function is deprecated because its
 * semantics will be changing in the future.
 */
@deprecated
@Experimental()
ElementList queryAll(String relativeSelectors) => document.queryAll(relativeSelectors);

/**
 * Finds the first descendant element of this document that matches the
 * specified group of selectors.
 *
 * Unless your webpage contains multiple documents, the top-level
 * [querySelector]
 * method behaves the same as this method, so you should use it instead to
 * save typing a few characters.
 *
 * [selectors] should be a string using CSS selector syntax.
 *
 *     var element1 = document.querySelector('.className');
 *     var element2 = document.querySelector('#id');
 *
 * For details about CSS selector syntax, see the
 * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
 */
Element querySelector(String selectors) => document.querySelector(selectors);

/**
 * Finds all descendant elements of this document that match the specified
 * group of selectors.
 *
 * Unless your webpage contains multiple documents, the top-level
 * [querySelectorAll]
 * method behaves the same as this method, so you should use it instead to
 * save typing a few characters.
 *
 * [selectors] should be a string using CSS selector syntax.
 *
 *     var items = document.querySelectorAll('.itemClassName');
 *
 * For details about CSS selector syntax, see the
 * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
 */
ElementList querySelectorAll(String selectors) => document.querySelectorAll(selectors);

/// A utility for changing the Dart wrapper type for elements.
abstract class ElementUpgrader {
  /// Upgrade the specified element to be of the Dart type this was created for.
  ///
  /// After upgrading the element passed in is invalid and the returned value
  /// should be used instead.
  Element upgrade(Element element);
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.



/**
 * Interface used to validate that only accepted elements and attributes are
 * allowed while parsing HTML strings into DOM nodes.
 *
 * In general, customization of validation behavior should be done via the
 * [NodeValidatorBuilder] class to mitigate the chances of incorrectly
 * implementing validation rules.
 */
abstract class NodeValidator {

  /**
   * Construct a default NodeValidator which only accepts whitelisted HTML5
   * elements and attributes.
   *
   * If a uriPolicy is not specified then the default uriPolicy will be used.
   */
  factory NodeValidator({UriPolicy uriPolicy}) =>
      new _Html5NodeValidator(uriPolicy: uriPolicy);

  factory NodeValidator.throws(NodeValidator base) =>
      new _ThrowsNodeValidator(base);

  /**
   * Returns true if the tagName is an accepted type.
   */
  bool allowsElement(Element element);

  /**
   * Returns true if the attribute is allowed.
   *
   * The attributeName parameter will always be in lowercase.
   *
   * See [allowsElement] for format of tagName.
   */
  bool allowsAttribute(Element element, String attributeName, String value);
}

/**
 * Performs sanitization of a node tree after construction to ensure that it
 * does not contain any disallowed elements or attributes.
 *
 * In general custom implementations of this class should not be necessary and
 * all validation customization should be done in custom NodeValidators, but
 * custom implementations of this class can be created to perform more complex
 * tree sanitization.
 */
abstract class NodeTreeSanitizer {

  /**
   * Constructs a default tree sanitizer which will remove all elements and
   * attributes which are not allowed by the provided validator.
   */
  factory NodeTreeSanitizer(NodeValidator validator) =>
      new _ValidatingTreeSanitizer(validator);

  /**
   * Called with the root of the tree which is to be sanitized.
   *
   * This method needs to walk the entire tree and either remove elements and
   * attributes which are not recognized as safe or throw an exception which
   * will mark the entire tree as unsafe.
   */
  void sanitizeTree(Node node);
}

/**
 * Defines the policy for what types of uris are allowed for particular
 * attribute values.
 *
 * This can be used to provide custom rules such as allowing all http:// URIs
 * for image attributes but only same-origin URIs for anchor tags.
 */
abstract class UriPolicy {
  /**
   * Constructs the default UriPolicy which is to only allow Uris to the same
   * origin as the application was launched from.
   *
   * This will block all ftp: mailto: URIs. It will also block accessing
   * https://example.com if the app is running from http://example.com.
   */
  factory UriPolicy() => new _SameOriginUriPolicy();

  /**
   * Checks if the uri is allowed on the specified attribute.
   *
   * The uri provided may or may not be a relative path.
   */
  bool allowsUri(String uri);
}

/**
 * Allows URIs to the same origin as the current application was loaded from
 * (such as https://example.com:80).
 */
class _SameOriginUriPolicy implements UriPolicy {
  final AnchorElement _hiddenAnchor = new AnchorElement();
  final Location _loc = window.location;

  bool allowsUri(String uri) {
    _hiddenAnchor.href = uri;
    // IE leaves an empty hostname for same-origin URIs.
    return (_hiddenAnchor.hostname == _loc.hostname &&
        _hiddenAnchor.port == _loc.port &&
        _hiddenAnchor.protocol == _loc.protocol) ||
        (_hiddenAnchor.hostname == '' &&
        _hiddenAnchor.port == '' &&
        _hiddenAnchor.protocol == ':');
  }
}


class _ThrowsNodeValidator implements NodeValidator {
  final NodeValidator validator;

  _ThrowsNodeValidator(this.validator) {}

  bool allowsElement(Element element) {
    if (!validator.allowsElement(element)) {
      throw new ArgumentError(element.tagName);
    }
    return true;
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (!validator.allowsAttribute(element, attributeName, value)) {
      throw new ArgumentError('${element.tagName}[$attributeName="$value"]');
    }
  }
}


/**
 * Standard tree sanitizer which validates a node tree against the provided
 * validator and removes any nodes or attributes which are not allowed.
 */
class _ValidatingTreeSanitizer implements NodeTreeSanitizer {
  NodeValidator validator;
  _ValidatingTreeSanitizer(this.validator) {}

  void sanitizeTree(Node node) {
    void walk(Node node) {
      sanitizeNode(node);

      var child = node.lastChild;
      while (child != null) {
        // Child may be removed during the walk.
        var nextChild = child.previousNode;
        walk(child);
        child = nextChild;
      }
    }
    walk(node);
  }

  void sanitizeNode(Node node) {
    switch (node.nodeType) {
      case Node.ELEMENT_NODE:
        Element element = node;
        var attrs = element.attributes;
        if (!validator.allowsElement(element)) {
          window.console.warn(
              'Removing disallowed element <${element.tagName}>');
          element.remove();
          break;
        }

        var isAttr = attrs['is'];
        if (isAttr != null) {
          if (!validator.allowsAttribute(element, 'is', isAttr)) {
            window.console.warn('Removing disallowed type extension '
                '<${element.tagName} is="$isAttr">');
            element.remove();
            break;
          }
        }

        // TODO(blois): Need to be able to get all attributes, irrespective of
        // XMLNS.
        var keys = attrs.keys.toList();
        for (var i = attrs.length - 1; i >= 0; --i) {
          var name = keys[i];
          if (!validator.allowsAttribute(element, name.toLowerCase(),
              attrs[name])) {
            window.console.warn('Removing disallowed attribute '
                '<${element.tagName} $name="${attrs[name]}">');
            attrs.remove(name);
          }
        }

        if (element is TemplateElement) {
          TemplateElement template = element;
          sanitizeTree(template.content);
        }
        break;
      case Node.COMMENT_NODE:
      case Node.DOCUMENT_FRAGMENT_NODE:
      case Node.TEXT_NODE:
      case Node.CDATA_SECTION_NODE:
        break;
      default:
        node.remove();
    }
  }
}
