/**
 * 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' hide LinkedList, LinkedListEntry;
import 'dart:_internal' hide Symbol;
import 'dart:html_common';
import 'dart:indexed_db';
import 'dart:isolate';
import "dart:convert";
import 'dart:math';
import 'dart:_native_typed_data';
import 'dart:typed_data';
import 'dart:svg' as svg;
import 'dart:svg' show Matrix;
import 'dart:svg' show SvgSvgElement;
import 'dart:web_audio' as web_audio;
import 'dart:web_gl' as gl;
import 'dart:web_gl' show RenderingContext, RenderingContext2;
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,
        Native,
        Returns,
        ForceInline,
        findDispatchTagForInterceptorClass,
        setNativeSubclassDispatchRecord,
        makeLeafDispatchRecord,
        registerGlobalObject;
import 'dart:_interceptors'
    show
        Interceptor,
        JSExtendableArray,
        JSUInt31,
        findInterceptorConstructorForType,
        findConstructorForNativeSubclassType,
        getNativeInterceptor,
        setDispatchProperty;

export 'dart:math' show Rectangle, Point;

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

/**
 * Root node for all content in a web page.
 */
HtmlDocument get document =>
    JS('returns:HtmlDocument;depends:none;effects:none;gvn:true', 'document');

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

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

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

createCustomUpgrader(Type customElementClass, $this) => $this;

/**
 * Emitted for any setlike IDL entry needs a callback signature.
 * Today there is only one.
 */
@DomName('FontFaceSetForEachCallback')
@Experimental() // untriaged
typedef void FontFaceSetForEachCallback(
    FontFace fontFace, FontFace fontFaceAgain, FontFaceSet set);
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

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

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

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

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

  @DomName('HTMLAnchorElement.HTMLAnchorElement')
  @DocsEditable()
  factory AnchorElement({String href}) {
    AnchorElement e = JS('returns:AnchorElement;creates:AnchorElement;new:true',
        '#.createElement(#)', document, "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.referrerpolicy')
  @DocsEditable()
  @Experimental() // untriaged
  String referrerpolicy;

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

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

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

  // From URLUtils

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  @DomName('Animation.effect')
  @DocsEditable()
  @Experimental() // untriaged
  AnimationEffectReadOnly effect;

  @DomName('Animation.finished')
  @DocsEditable()
  @Experimental() // untriaged
  final Future finished;

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

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

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

  @DomName('Animation.ready')
  @DocsEditable()
  @Experimental() // untriaged
  final Future ready;

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

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

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

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

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

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

  @DomName('AnimationEffectReadOnly.computedTiming')
  @DocsEditable()
  @Experimental() // untriaged
  Map get computedTiming =>
      convertNativeToDart_Dictionary(this._get_computedTiming);
  @JSName('computedTiming')
  @DomName('AnimationEffectReadOnly.computedTiming')
  @DocsEditable()
  @Experimental() // untriaged
  final dynamic _get_computedTiming;

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

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

  @DomName('AnimationEffectTiming.delay')
  @DocsEditable()
  @Experimental() // untriaged
  num delay;

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

  @DomName('AnimationEffectTiming.duration')
  @DocsEditable()
  @Experimental() // untriaged
  @Creates('Null')
  @Returns('num|String')
  Object duration;

  @DomName('AnimationEffectTiming.easing')
  @DocsEditable()
  @Experimental() // untriaged
  String easing;

  @DomName('AnimationEffectTiming.endDelay')
  @DocsEditable()
  @Experimental() // untriaged
  num endDelay;

  @DomName('AnimationEffectTiming.fill')
  @DocsEditable()
  @Experimental() // untriaged
  String fill;

  @DomName('AnimationEffectTiming.iterationStart')
  @DocsEditable()
  @Experimental() // untriaged
  num iterationStart;

  @DomName('AnimationEffectTiming.iterations')
  @DocsEditable()
  @Experimental() // untriaged
  num iterations;

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

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

  @DomName('AnimationEvent.AnimationEvent')
  @DocsEditable()
  factory AnimationEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return AnimationEvent._create_1(type, eventInitDict_1);
    }
    return AnimationEvent._create_2(type);
  }
  static AnimationEvent _create_1(type, eventInitDict) =>
      JS('AnimationEvent', 'new AnimationEvent(#,#)', type, eventInitDict);
  static AnimationEvent _create_2(type) =>
      JS('AnimationEvent', 'new AnimationEvent(#)', type);

  @DomName('AnimationEvent.animationName')
  @DocsEditable()
  @Experimental() // untriaged
  final String animationName;

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

  @DomName('AnimationPlayerEvent.AnimationPlayerEvent')
  @DocsEditable()
  factory AnimationPlayerEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return AnimationPlayerEvent._create_1(type, eventInitDict_1);
    }
    return AnimationPlayerEvent._create_2(type);
  }
  static AnimationPlayerEvent _create_1(type, eventInitDict) => JS(
      'AnimationPlayerEvent',
      'new AnimationPlayerEvent(#,#)',
      type,
      eventInitDict);
  static AnimationPlayerEvent _create_2(type) =>
      JS('AnimationPlayerEvent', 'new AnimationPlayerEvent(#)', type);

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

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

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

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

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

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

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

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

  @DomName('AppBannerPromptResult.outcome')
  @DocsEditable()
  @Experimental() // untriaged
  final String outcome;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  @DomName('ApplicationCacheErrorEvent.ApplicationCacheErrorEvent')
  @DocsEditable()
  factory ApplicationCacheErrorEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return ApplicationCacheErrorEvent._create_1(type, eventInitDict_1);
    }
    return ApplicationCacheErrorEvent._create_2(type);
  }
  static ApplicationCacheErrorEvent _create_1(type, eventInitDict) => JS(
      'ApplicationCacheErrorEvent',
      'new ApplicationCacheErrorEvent(#,#)',
      type,
      eventInitDict);
  static ApplicationCacheErrorEvent _create_2(type) => JS(
      'ApplicationCacheErrorEvent', 'new ApplicationCacheErrorEvent(#)', type);

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

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

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

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

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

  @DomName('HTMLAreaElement.HTMLAreaElement')
  @DocsEditable()
  factory AreaElement() => JS(
      'returns:AreaElement;creates:AreaElement;new:true',
      '#.createElement(#)',
      document,
      "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.referrerpolicy')
  @DocsEditable()
  @Experimental() // untriaged
  String referrerpolicy;

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

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

  // From URLUtils

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@DocsEditable()
@DomName('AudioTrackList')
@Experimental() // untriaged
@Native("AudioTrackList")
class AudioTrackList extends EventTarget
    with ListMixin<AudioTrack>, ImmutableListMixin<AudioTrack>
    implements JavaScriptIndexingBehavior<AudioTrack>, List<AudioTrack> {
  // To suppress missing implicit constructor warnings.
  factory AudioTrackList._() {
    throw new UnsupportedError("Not supported");
  }

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

  @DomName('AudioTrackList.length')
  @DocsEditable()
  @Experimental() // untriaged
  int get length => JS("int", "#.length", this);

  AudioTrack operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("AudioTrack", "#[#]", this, index);
  }

  void operator []=(int index, AudioTrack value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<AudioTrack> mixins.
  // AudioTrack is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  AudioTrack get first {
    if (this.length > 0) {
      return JS('AudioTrack', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  AudioTrack get last {
    int len = this.length;
    if (len > 0) {
      return JS('AudioTrack', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  AudioTrack get single {
    int len = this.length;
    if (len == 1) {
      return JS('AudioTrack', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  AudioTrack elementAt(int index) => this[index];
  // -- end List<AudioTrack> mixins.

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

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

  @DomName('AudioTrackList.onchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onChange => changeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

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

  @DomName('AutocompleteErrorEvent.AutocompleteErrorEvent')
  @DocsEditable()
  factory AutocompleteErrorEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return AutocompleteErrorEvent._create_1(type, eventInitDict_1);
    }
    return AutocompleteErrorEvent._create_2(type);
  }
  static AutocompleteErrorEvent _create_1(type, eventInitDict) => JS(
      'AutocompleteErrorEvent',
      'new AutocompleteErrorEvent(#,#)',
      type,
      eventInitDict);
  static AutocompleteErrorEvent _create_2(type) =>
      JS('AutocompleteErrorEvent', 'new AutocompleteErrorEvent(#)', type);

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

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

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

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

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

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

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

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

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

@DocsEditable()
@DomName('BatteryManager')
// https://dvcs.w3.org/hg/dap/raw-file/default/battery/Overview.html#batterymanager-interface
@Experimental() // stable
@Native("BatteryManager")
class BatteryManager extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory BatteryManager._() {
    throw new UnsupportedError("Not supported");
  }

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

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

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

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

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

  @DomName('BeforeInstallPromptEvent.BeforeInstallPromptEvent')
  @DocsEditable()
  factory BeforeInstallPromptEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return BeforeInstallPromptEvent._create_1(type, eventInitDict_1);
    }
    return BeforeInstallPromptEvent._create_2(type);
  }
  static BeforeInstallPromptEvent _create_1(type, eventInitDict) => JS(
      'BeforeInstallPromptEvent',
      'new BeforeInstallPromptEvent(#,#)',
      type,
      eventInitDict);
  static BeforeInstallPromptEvent _create_2(type) =>
      JS('BeforeInstallPromptEvent', 'new BeforeInstallPromptEvent(#)', type);

  List<String> get platforms => JS("List<String>", "#.platforms", this);

  @DomName('BeforeInstallPromptEvent.userChoice')
  @DocsEditable()
  @Experimental() // untriaged
  final Future userChoice;

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

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

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

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

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

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

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

  @DomName('Blob.close')
  @DocsEditable()
  @Experimental() // untriaged
  void close() native;

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

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

  static _create_1(parts) => JS('Blob', 'new self.Blob(#)', parts);
  static _create_2(parts, bag) => JS('Blob', 'new self.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.

// WARNING: Do not edit - generated code.

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

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

  @DomName('BlobEvent.BlobEvent')
  @DocsEditable()
  factory BlobEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return BlobEvent._create_1(type, eventInitDict_1);
  }
  static BlobEvent _create_1(type, eventInitDict) =>
      JS('BlobEvent', 'new BlobEvent(#,#)', type, eventInitDict);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  @DomName('HTMLButtonElement.HTMLButtonElement')
  @DocsEditable()
  factory ButtonElement() => JS(
      'returns:ButtonElement;creates:ButtonElement;new:true',
      '#.createElement(#)',
      document,
      "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|Null')
  @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.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() native;

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

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

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

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

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

  @DomName('CacheStorage.keys')
  @DocsEditable()
  @Experimental() // untriaged
  Future keys() native;

  @DomName('CacheStorage.match')
  @DocsEditable()
  @Experimental() // untriaged
  Future match(/*RequestInfo*/ request, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _match_1(request, options_1);
    }
    return _match_2(request);
  }

  @JSName('match')
  @DomName('CacheStorage.match')
  @DocsEditable()
  @Experimental() // untriaged
  Future _match_1(request, options) native;
  @JSName('match')
  @DomName('CacheStorage.match')
  @DocsEditable()
  @Experimental() // untriaged
  Future _match_2(request) native;

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

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

  @DomName('CalcLength.CalcLength')
  @DocsEditable()
  factory CalcLength(calcDictionary_OR_length) {
    if ((calcDictionary_OR_length is LengthValue)) {
      return CalcLength._create_1(calcDictionary_OR_length);
    }
    if ((calcDictionary_OR_length is Map)) {
      var calcDictionary_1 =
          convertDartToNative_Dictionary(calcDictionary_OR_length);
      return CalcLength._create_2(calcDictionary_1);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static CalcLength _create_1(calcDictionary_OR_length) =>
      JS('CalcLength', 'new CalcLength(#)', calcDictionary_OR_length);
  static CalcLength _create_2(calcDictionary_OR_length) =>
      JS('CalcLength', 'new CalcLength(#)', calcDictionary_OR_length);

  @DomName('CalcLength.ch')
  @DocsEditable()
  @Experimental() // untriaged
  final double ch;

  @DomName('CalcLength.cm')
  @DocsEditable()
  @Experimental() // untriaged
  final double cm;

  @DomName('CalcLength.em')
  @DocsEditable()
  @Experimental() // untriaged
  final double em;

  @DomName('CalcLength.ex')
  @DocsEditable()
  @Experimental() // untriaged
  final double ex;

  @JSName('in')
  @DomName('CalcLength.in')
  @DocsEditable()
  @Experimental() // untriaged
  final double inch;

  @DomName('CalcLength.mm')
  @DocsEditable()
  @Experimental() // untriaged
  final double mm;

  @DomName('CalcLength.pc')
  @DocsEditable()
  @Experimental() // untriaged
  final double pc;

  @DomName('CalcLength.percent')
  @DocsEditable()
  @Experimental() // untriaged
  final double percent;

  @DomName('CalcLength.pt')
  @DocsEditable()
  @Experimental() // untriaged
  final double pt;

  @DomName('CalcLength.px')
  @DocsEditable()
  @Experimental() // untriaged
  final double px;

  @DomName('CalcLength.rem')
  @DocsEditable()
  @Experimental() // untriaged
  final double rem;

  @DomName('CalcLength.vh')
  @DocsEditable()
  @Experimental() // untriaged
  final double vh;

  @DomName('CalcLength.vmax')
  @DocsEditable()
  @Experimental() // untriaged
  final double vmax;

  @DomName('CalcLength.vmin')
  @DocsEditable()
  @Experimental() // untriaged
  final double vmin;

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

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

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

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

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

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

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

  @DomName('HTMLCanvasElement.HTMLCanvasElement')
  @DocsEditable()
  factory CanvasElement({int width, int height}) {
    CanvasElement e = JS('returns:CanvasElement;creates:CanvasElement;new:true',
        '#.createElement(#)', document, "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.captureStream')
  @DocsEditable()
  @Experimental() // untriaged
  MediaStream captureStream([num frameRate]) native;

  @DomName('HTMLCanvasElement.getContext')
  @DocsEditable()
  @Creates('CanvasRenderingContext2D|RenderingContext|RenderingContext2')
  @Returns('CanvasRenderingContext2D|RenderingContext|RenderingContext2|Null')
  Object getContext(String contextId, [Map attributes]) {
    if (attributes != null) {
      var attributes_1 = convertDartToNative_Dictionary(attributes);
      return _getContext_1(contextId, attributes_1);
    }
    return _getContext_2(contextId);
  }

  @JSName('getContext')
  @DomName('HTMLCanvasElement.getContext')
  @DocsEditable()
  @Creates('CanvasRenderingContext2D|RenderingContext|RenderingContext2')
  @Returns('CanvasRenderingContext2D|RenderingContext|RenderingContext2|Null')
  Object _getContext_1(contextId, attributes) native;
  @JSName('getContext')
  @DomName('HTMLCanvasElement.getContext')
  @DocsEditable()
  @Creates('CanvasRenderingContext2D|RenderingContext|RenderingContext2')
  @Returns('CanvasRenderingContext2D|RenderingContext|RenderingContext2|Null')
  Object _getContext_2(contextId) native;

  @DomName('HTMLCanvasElement.toBlob')
  @DocsEditable()
  @Experimental() // untriaged
  void toBlob(BlobCallback callback, String type, [Object arguments]) native;

  @JSName('toDataURL')
  @DomName('HTMLCanvasElement.toDataURL')
  @DocsEditable()
  String _toDataUrl(String type, [arguments_OR_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](https://html.spec.whatwg.org/multipage/scripting.html#canvasgradient)
 *   from WHATWG.
 * * [CanvasGradient](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvasgradient) from W3C.
 */
@DomName('CanvasGradient')
@Native("CanvasGradient")
class CanvasGradient extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory CanvasGradient._() {
    throw new UnsupportedError("Not supported");
  }

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

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

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

abstract class CanvasRenderingContext {
  CanvasElement get canvas;
}

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

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

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

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

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

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

  @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](https://html.spec.whatwg.org/multipage/scripting.html#image-smoothing)
   *   from WHATWG.
   */
  @DomName('CanvasRenderingContext2D.imageSmoothingEnabled')
  @DocsEditable()
  @Experimental() // untriaged
  bool imageSmoothingEnabled;

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

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

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

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

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

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

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

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

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

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

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

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

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

  @JSName('addHitRegion')
  @DomName('CanvasRenderingContext2D.addHitRegion')
  @DocsEditable()
  @Experimental() // untriaged
  void _addHitRegion_1(options) native;
  @JSName('addHitRegion')
  @DomName('CanvasRenderingContext2D.addHitRegion')
  @DocsEditable()
  @Experimental() // untriaged
  void _addHitRegion_2() native;

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

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

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

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

  @DomName('CanvasRenderingContext2D.createImageData')
  @DocsEditable()
  @Creates('ImageData|=Object')
  ImageData createImageData(imagedata_OR_sw, [num sh]) {
    if ((imagedata_OR_sw is ImageData) && sh == null) {
      var imagedata_1 = convertDartToNative_ImageData(imagedata_OR_sw);
      return convertNativeToDart_ImageData(_createImageData_1(imagedata_1));
    }
    if (sh != null && (imagedata_OR_sw is num)) {
      return convertNativeToDart_ImageData(
          _createImageData_2(imagedata_OR_sw, sh));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('createImageData')
  @DomName('CanvasRenderingContext2D.createImageData')
  @DocsEditable()
  @Creates('ImageData|=Object')
  _createImageData_1(imagedata) native;
  @JSName('createImageData')
  @DomName('CanvasRenderingContext2D.createImageData')
  @DocsEditable()
  @Creates('ImageData|=Object')
  _createImageData_2(num sw, sh) native;

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

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

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

  @DomName('CanvasRenderingContext2D.drawFocusIfNeeded')
  @DocsEditable()
  @Experimental() // untriaged
  void drawFocusIfNeeded(element_OR_path, [Element element]) native;

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

  @DomName('CanvasRenderingContext2D.getContextAttributes')
  @DocsEditable()
  // http://wiki.whatwg.org/wiki/CanvasOpaque#Suggested_IDL
  @Experimental()
  Map getContextAttributes() {
    return convertNativeToDart_Dictionary(_getContextAttributes_1());
  }

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

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

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

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

  @DomName('CanvasRenderingContext2D.isContextLost')
  @DocsEditable()
  @Experimental() // untriaged
  bool isContextLost() native;

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

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

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

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

  @JSName('putImageData')
  @DomName('CanvasRenderingContext2D.putImageData')
  @DocsEditable()
  void _putImageData_1(imagedata, dx, dy) native;
  @JSName('putImageData')
  @DomName('CanvasRenderingContext2D.putImageData')
  @DocsEditable()
  void _putImageData_2(
      imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight) native;

  @DomName('CanvasRenderingContext2D.removeHitRegion')
  @DocsEditable()
  @Experimental() // untriaged
  void removeHitRegion(String id) native;

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

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

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

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

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

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

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

  @DomName('CanvasRenderingContext2D.stroke')
  @DocsEditable()
  void stroke([Path2D path]) native;

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

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

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

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

  // From CanvasPathMethods

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

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

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

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

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

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

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

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

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

  @DomName('CanvasRenderingContext2D.createImageDataFromImageData')
  @DocsEditable()
  ImageData createImageDataFromImageData(ImageData imagedata) =>
      JS('ImageData', '#.createImageData(#)', this, imagedata);

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

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

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

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

  @DomName('CanvasRenderingContext2D.arc')
  void arc(num x, num y, num radius, num startAngle, num endAngle,
      [bool anticlockwise = false]) {
    // TODO(terry): This should not be needed: dartbug.com/20939.
    JS('void', '#.arc(#, #, #, #, #, #)', this, x, y, radius, startAngle,
        endAngle, anticlockwise);
  }

  @DomName('CanvasRenderingContext2D.createPatternFromImage')
  CanvasPattern createPatternFromImage(
          ImageElement image, String repetitionType) =>
      JS('CanvasPattern', '#.createPattern(#, #)', this, image, repetitionType);

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

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

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

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

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

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

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

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

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

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

  /** Deprecated always returns 1.0 */
  @DomName('CanvasRenderingContext2D.webkitBackingStorePixelRation')
  @Experimental()
  @deprecated
  double get backingStorePixelRatio => 1.0;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

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

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

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

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

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

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

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

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

  // From ChildNode

  // From NonDocumentTypeChildNode

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

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

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

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

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

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

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

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

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

  @DomName('Client.frameType')
  @DocsEditable()
  @Experimental() // untriaged
  final String frameType;

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

  @DomName('Client.url')
  @DocsEditable()
  @Experimental() // untriaged
  final String url;

  @DomName('Client.postMessage')
  @DocsEditable()
  @Experimental() // untriaged
  void postMessage(/*SerializedScriptValue*/ message,
      [List<MessagePort> transfer]) {
    if (transfer != null) {
      var message_1 = convertDartToNative_SerializedScriptValue(message);
      _postMessage_1(message_1, transfer);
      return;
    }
    var message_1 = convertDartToNative_SerializedScriptValue(message);
    _postMessage_2(message_1);
    return;
  }

  @JSName('postMessage')
  @DomName('Client.postMessage')
  @DocsEditable()
  @Experimental() // untriaged
  void _postMessage_1(message, List<MessagePort> transfer) native;
  @JSName('postMessage')
  @DomName('Client.postMessage')
  @DocsEditable()
  @Experimental() // untriaged
  void _postMessage_2(message) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

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

  @DomName('Clients.claim')
  @DocsEditable()
  @Experimental() // untriaged
  Future claim() native;

  @DomName('Clients.get')
  @DocsEditable()
  @Experimental() // untriaged
  Future get(String id) native;

  @DomName('Clients.matchAll')
  @DocsEditable()
  @Experimental() // untriaged
  Future matchAll([Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _matchAll_1(options_1);
    }
    return _matchAll_2();
  }

  @JSName('matchAll')
  @DomName('Clients.matchAll')
  @DocsEditable()
  @Experimental() // untriaged
  Future _matchAll_1(options) native;
  @JSName('matchAll')
  @DomName('Clients.matchAll')
  @DocsEditable()
  @Experimental() // untriaged
  Future _matchAll_2() native;

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

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

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

  @DomName('CloseEvent.CloseEvent')
  @DocsEditable()
  factory CloseEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return CloseEvent._create_1(type, eventInitDict_1);
    }
    return CloseEvent._create_2(type);
  }
  static CloseEvent _create_1(type, eventInitDict) =>
      JS('CloseEvent', 'new CloseEvent(#,#)', type, eventInitDict);
  static CloseEvent _create_2(type) =>
      JS('CloseEvent', 'new CloseEvent(#)', type);

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

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

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

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

// WARNING: Do not edit - generated code.

@DomName('CompositionEvent')
@Native("CompositionEvent")
class CompositionEvent extends UIEvent {
  factory CompositionEvent(String type,
      {bool canBubble: false,
      bool cancelable: false,
      Window view,
      String data,
      String locale}) {
    if (view == null) {
      view = window;
    }
    CompositionEvent e = document._createEvent("CompositionEvent");

    if (Device.isFirefox) {
      // Firefox requires the locale parameter that isn't supported elsewhere.
      JS('void', '#.initCompositionEvent(#, #, #, #, #, #)', e, type, canBubble,
          cancelable, view, data, locale);
    } else {
      e._initCompositionEvent(type, canBubble, cancelable, view, data);
    }

    return e;
  }

  @DomName('CompositionEvent.CompositionEvent')
  @DocsEditable()
  factory CompositionEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return CompositionEvent._create_1(type, eventInitDict_1);
    }
    return CompositionEvent._create_2(type);
  }
  static CompositionEvent _create_1(type, eventInitDict) =>
      JS('CompositionEvent', 'new CompositionEvent(#,#)', type, eventInitDict);
  static CompositionEvent _create_2(type) =>
      JS('CompositionEvent', 'new CompositionEvent(#)', type);

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

  @JSName('initCompositionEvent')
  @DomName('CompositionEvent.initCompositionEvent')
  @DocsEditable()
  void _initCompositionEvent(String type, bool bubbles, bool cancelable,
      Window view, 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.

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

  @DomName('CompositorProxy.CompositorProxy')
  @DocsEditable()
  factory CompositorProxy(Element element, List<String> attributeArray) {
    return CompositorProxy._create_1(element, attributeArray);
  }
  static CompositorProxy _create_1(element, attributeArray) => JS(
      'CompositorProxy', 'new CompositorProxy(#,#)', element, attributeArray);

  @DomName('CompositorProxy.opacity')
  @DocsEditable()
  @Experimental() // untriaged
  num opacity;

  @DomName('CompositorProxy.scrollLeft')
  @DocsEditable()
  @Experimental() // untriaged
  num scrollLeft;

  @DomName('CompositorProxy.scrollTop')
  @DocsEditable()
  @Experimental() // untriaged
  num scrollTop;

  @DomName('CompositorProxy.transform')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix transform;

  @DomName('CompositorProxy.disconnect')
  @DocsEditable()
  @Experimental() // untriaged
  void disconnect() native;

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

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

  @DomName('CompositorWorker.errorEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  @DomName('CompositorWorker.messageEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  @DomName('CompositorWorker.CompositorWorker')
  @DocsEditable()
  factory CompositorWorker(String scriptUrl) {
    return CompositorWorker._create_1(scriptUrl);
  }
  static CompositorWorker _create_1(scriptUrl) =>
      JS('CompositorWorker', 'new CompositorWorker(#)', scriptUrl);

  @DomName('CompositorWorker.postMessage')
  @DocsEditable()
  @Experimental() // untriaged
  void postMessage(/*SerializedScriptValue*/ message,
      [List<MessagePort> transfer]) {
    if (transfer != null) {
      var message_1 = convertDartToNative_SerializedScriptValue(message);
      _postMessage_1(message_1, transfer);
      return;
    }
    var message_1 = convertDartToNative_SerializedScriptValue(message);
    _postMessage_2(message_1);
    return;
  }

  @JSName('postMessage')
  @DomName('CompositorWorker.postMessage')
  @DocsEditable()
  @Experimental() // untriaged
  void _postMessage_1(message, List<MessagePort> transfer) native;
  @JSName('postMessage')
  @DomName('CompositorWorker.postMessage')
  @DocsEditable()
  @Experimental() // untriaged
  void _postMessage_2(message) native;

  @DomName('CompositorWorker.terminate')
  @DocsEditable()
  @Experimental() // untriaged
  void terminate() native;

  @DomName('CompositorWorker.onerror')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onError => errorEvent.forTarget(this);

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

  @DomName('CompositorWorkerGlobalScope.messageEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  @DomName('CompositorWorkerGlobalScope.cancelAnimationFrame')
  @DocsEditable()
  @Experimental() // untriaged
  void cancelAnimationFrame(int handle) native;

  @DomName('CompositorWorkerGlobalScope.postMessage')
  @DocsEditable()
  @Experimental() // untriaged
  void postMessage(/*any*/ message, [List<MessagePort> transfer]) {
    if (transfer != null) {
      var message_1 = convertDartToNative_SerializedScriptValue(message);
      _postMessage_1(message_1, transfer);
      return;
    }
    var message_1 = convertDartToNative_SerializedScriptValue(message);
    _postMessage_2(message_1);
    return;
  }

  @JSName('postMessage')
  @DomName('CompositorWorkerGlobalScope.postMessage')
  @DocsEditable()
  @Experimental() // untriaged
  void _postMessage_1(message, List<MessagePort> transfer) native;
  @JSName('postMessage')
  @DomName('CompositorWorkerGlobalScope.postMessage')
  @DocsEditable()
  @Experimental() // untriaged
  void _postMessage_2(message) native;

  @DomName('CompositorWorkerGlobalScope.requestAnimationFrame')
  @DocsEditable()
  @Experimental() // untriaged
  int requestAnimationFrame(FrameRequestCallback callback) native;

  @DomName('CompositorWorkerGlobalScope.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.

@DomName('Console')
class Console {
  const Console._safe();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  @DomName('Console.warn')
  void warn(Object arg) =>
      _isConsoleDefined ? JS('void', 'console.warn(#)', arg) : null;
  // To suppress missing implicit constructor warnings.
  factory Console._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

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

  @JSName('assert')
  @DomName('ConsoleBase.assert')
  @DocsEditable()
  @Experimental() // untriaged
  void assertCondition(bool condition, Object arg) native;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  @JSName('iconURL')
  @DomName('Credential.iconURL')
  @DocsEditable()
  @Experimental() // untriaged
  final String iconUrl;

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

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

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

  @DomName('CredentialsContainer.get')
  @DocsEditable()
  @Experimental() // untriaged
  Future get([Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _get_1(options_1);
    }
    return _get_2();
  }

  @JSName('get')
  @DomName('CredentialsContainer.get')
  @DocsEditable()
  @Experimental() // untriaged
  Future _get_1(options) native;
  @JSName('get')
  @DomName('CredentialsContainer.get')
  @DocsEditable()
  @Experimental() // untriaged
  Future _get_2() native;

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

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

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

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

  @DomName('CrossOriginServiceWorkerClient.targetUrl')
  @DocsEditable()
  @Experimental() // untriaged
  final String targetUrl;

  @DomName('CrossOriginServiceWorkerClient.postMessage')
  @DocsEditable()
  @Experimental() // untriaged
  void postMessage(/*SerializedScriptValue*/ message,
      [List<MessagePort> transfer]) {
    if (transfer != null) {
      var message_1 = convertDartToNative_SerializedScriptValue(message);
      _postMessage_1(message_1, transfer);
      return;
    }
    var message_1 = convertDartToNative_SerializedScriptValue(message);
    _postMessage_2(message_1);
    return;
  }

  @JSName('postMessage')
  @DomName('CrossOriginServiceWorkerClient.postMessage')
  @DocsEditable()
  @Experimental() // untriaged
  void _postMessage_1(message, List<MessagePort> transfer) native;
  @JSName('postMessage')
  @DomName('CrossOriginServiceWorkerClient.postMessage')
  @DocsEditable()
  @Experimental() // untriaged
  void _postMessage_2(message) native;
}
// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DomName('Crypto')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
// http://www.w3.org/TR/WebCryptoAPI/
@Native("Crypto")
class Crypto extends Interceptor {
  TypedData getRandomValues(TypedData array) {
    return _getRandomValues(array);
  }

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

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

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

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

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

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

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

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

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

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

  @DomName('CSS.escape')
  @DocsEditable()
  @Experimental() // untriaged
  static String escape(String ident) native;

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

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

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

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

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

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

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

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

  @DomName('CSSGroupingRule.deleteRule')
  @DocsEditable()
  @Experimental() // untriaged
  void deleteRule(int index) native;

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

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

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

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

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

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

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

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

  @DomName('CSSKeyframesRule.cssRules')
  @DocsEditable()
  @Experimental() // untriaged
  @Returns('_CssRuleList|Null')
  @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.appendRule')
  @DocsEditable()
  @Experimental() // untriaged
  void appendRule(String rule) native;

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

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

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

  @DomName('CSSMediaRule.media')
  @DocsEditable()
  final MediaList 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('CSSNamespaceRule')
@Experimental() // untriaged
@Native("CSSNamespaceRule")
class CssNamespaceRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssNamespaceRule._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('namespaceURI')
  @DomName('CSSNamespaceRule.namespaceURI')
  @DocsEditable()
  @Experimental() // untriaged
  final String namespaceUri;

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

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

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

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

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

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

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

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

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

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

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

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

  @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_KEYFRAMES_RULE')
  @DocsEditable()
  // http://www.w3.org/TR/css3-animations/#cssrule
  @Experimental()
  static const int WEBKIT_KEYFRAMES_RULE = 7;

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

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

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

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

  @DomName('CSSRule.type')
  @DocsEditable()
  final int type;
}

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

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

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

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

  factory CssStyleDeclaration.css(String css) {
    final style = new DivElement().style;
    style.cssText = css;
    return style;
  }

  /// Returns the value of the property if the provided *CSS* property
  /// name is supported on this element and if the value is set. Otherwise
  /// returns an empty string.
  ///
  /// Please note the property name uses camelCase, not-hyphens.
  String getPropertyValue(String propertyName) {
    var propValue = _getPropertyValueHelper(propertyName);
    return propValue ?? '';
  }

  String _getPropertyValueHelper(String propertyName) {
    return _getPropertyValue(_browserPropertyName(propertyName));
  }

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

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

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

  String _browserPropertyName(String propertyName) {
    String name = _readCache(propertyName);
    if (name is String) return name;
    name = _supportedBrowserPropertyName(propertyName);
    _writeCache(propertyName, name);
    return name;
  }

  String _supportedBrowserPropertyName(String propertyName) {
    if (_supportsProperty(_camelCase(propertyName))) {
      return propertyName;
    }
    var prefixed = "${Device.cssPrefix}$propertyName";
    if (_supportsProperty(prefixed)) {
      return prefixed;
    }
    // May be a CSS variable, just use it as provided.
    return propertyName;
  }

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

  static String _camelCase(String hyphenated) {
    var replacedMs = JS('String', r'#.replace(/^-ms-/, "ms-")', hyphenated);
    return JS(
        'String',
        r'#.replace(/-([\da-z])/ig,'
        r'function(_, letter) { return letter.toUpperCase();})',
        replacedMs);
  }

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

  /**
   * Checks to see if CSS Transitions are supported.
   */
  static bool get supportsTransitions {
    return document.body.style.supportsProperty('transition');
  }

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

  @DomName('CSSStyleDeclaration.cssFloat')
  @DocsEditable()
  @Experimental() // untriaged
  String cssFloat;

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

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

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

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

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

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

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

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

  /** Sets the value of "background" */
  set background(String value) {
    _background = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('background')
  String _background;

  /** Gets the value of "background-attachment" */
  String get backgroundAttachment => this._backgroundAttachment;

  /** Sets the value of "background-attachment" */
  set backgroundAttachment(String value) {
    _backgroundAttachment = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('backgroundAttachment')
  String _backgroundAttachment;

  /** Gets the value of "background-color" */
  String get backgroundColor => this._backgroundColor;

  /** Sets the value of "background-color" */
  set backgroundColor(String value) {
    _backgroundColor = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('backgroundColor')
  String _backgroundColor;

  /** Gets the value of "background-image" */
  String get backgroundImage => this._backgroundImage;

  /** Sets the value of "background-image" */
  set backgroundImage(String value) {
    _backgroundImage = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('backgroundImage')
  String _backgroundImage;

  /** Gets the value of "background-position" */
  String get backgroundPosition => this._backgroundPosition;

  /** Sets the value of "background-position" */
  set backgroundPosition(String value) {
    _backgroundPosition = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('backgroundPosition')
  String _backgroundPosition;

  /** Gets the value of "background-repeat" */
  String get backgroundRepeat => this._backgroundRepeat;

  /** Sets the value of "background-repeat" */
  set backgroundRepeat(String value) {
    _backgroundRepeat = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('backgroundRepeat')
  String _backgroundRepeat;

  /** Gets the value of "border" */
  String get border => this._border;

  /** Sets the value of "border" */
  set border(String value) {
    _border = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('border')
  String _border;

  /** Gets the value of "border-bottom" */
  String get borderBottom => this._borderBottom;

  /** Sets the value of "border-bottom" */
  set borderBottom(String value) {
    _borderBottom = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderBottom')
  String _borderBottom;

  /** Gets the value of "border-bottom-color" */
  String get borderBottomColor => this._borderBottomColor;

  /** Sets the value of "border-bottom-color" */
  set borderBottomColor(String value) {
    _borderBottomColor = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderBottomColor')
  String _borderBottomColor;

  /** Gets the value of "border-bottom-style" */
  String get borderBottomStyle => this._borderBottomStyle;

  /** Sets the value of "border-bottom-style" */
  set borderBottomStyle(String value) {
    _borderBottomStyle = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderBottomStyle')
  String _borderBottomStyle;

  /** Gets the value of "border-bottom-width" */
  String get borderBottomWidth => this._borderBottomWidth;

  /** Sets the value of "border-bottom-width" */
  set borderBottomWidth(String value) {
    _borderBottomWidth = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderBottomWidth')
  String _borderBottomWidth;

  /** Gets the value of "border-collapse" */
  String get borderCollapse => this._borderCollapse;

  /** Sets the value of "border-collapse" */
  set borderCollapse(String value) {
    _borderCollapse = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderCollapse')
  String _borderCollapse;

  /** Gets the value of "border-color" */
  String get borderColor => this._borderColor;

  /** Sets the value of "border-color" */
  set borderColor(String value) {
    _borderColor = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderColor')
  String _borderColor;

  /** Gets the value of "border-left" */
  String get borderLeft => this._borderLeft;

  /** Sets the value of "border-left" */
  set borderLeft(String value) {
    _borderLeft = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderLeft')
  String _borderLeft;

  /** Gets the value of "border-left-color" */
  String get borderLeftColor => this._borderLeftColor;

  /** Sets the value of "border-left-color" */
  set borderLeftColor(String value) {
    _borderLeftColor = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderLeftColor')
  String _borderLeftColor;

  /** Gets the value of "border-left-style" */
  String get borderLeftStyle => this._borderLeftStyle;

  /** Sets the value of "border-left-style" */
  set borderLeftStyle(String value) {
    _borderLeftStyle = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderLeftStyle')
  String _borderLeftStyle;

  /** Gets the value of "border-left-width" */
  String get borderLeftWidth => this._borderLeftWidth;

  /** Sets the value of "border-left-width" */
  set borderLeftWidth(String value) {
    _borderLeftWidth = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderLeftWidth')
  String _borderLeftWidth;

  /** Gets the value of "border-right" */
  String get borderRight => this._borderRight;

  /** Sets the value of "border-right" */
  set borderRight(String value) {
    _borderRight = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderRight')
  String _borderRight;

  /** Gets the value of "border-right-color" */
  String get borderRightColor => this._borderRightColor;

  /** Sets the value of "border-right-color" */
  set borderRightColor(String value) {
    _borderRightColor = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderRightColor')
  String _borderRightColor;

  /** Gets the value of "border-right-style" */
  String get borderRightStyle => this._borderRightStyle;

  /** Sets the value of "border-right-style" */
  set borderRightStyle(String value) {
    _borderRightStyle = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderRightStyle')
  String _borderRightStyle;

  /** Gets the value of "border-right-width" */
  String get borderRightWidth => this._borderRightWidth;

  /** Sets the value of "border-right-width" */
  set borderRightWidth(String value) {
    _borderRightWidth = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderRightWidth')
  String _borderRightWidth;

  /** Gets the value of "border-spacing" */
  String get borderSpacing => this._borderSpacing;

  /** Sets the value of "border-spacing" */
  set borderSpacing(String value) {
    _borderSpacing = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderSpacing')
  String _borderSpacing;

  /** Gets the value of "border-style" */
  String get borderStyle => this._borderStyle;

  /** Sets the value of "border-style" */
  set borderStyle(String value) {
    _borderStyle = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderStyle')
  String _borderStyle;

  /** Gets the value of "border-top" */
  String get borderTop => this._borderTop;

  /** Sets the value of "border-top" */
  set borderTop(String value) {
    _borderTop = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderTop')
  String _borderTop;

  /** Gets the value of "border-top-color" */
  String get borderTopColor => this._borderTopColor;

  /** Sets the value of "border-top-color" */
  set borderTopColor(String value) {
    _borderTopColor = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderTopColor')
  String _borderTopColor;

  /** Gets the value of "border-top-style" */
  String get borderTopStyle => this._borderTopStyle;

  /** Sets the value of "border-top-style" */
  set borderTopStyle(String value) {
    _borderTopStyle = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderTopStyle')
  String _borderTopStyle;

  /** Gets the value of "border-top-width" */
  String get borderTopWidth => this._borderTopWidth;

  /** Sets the value of "border-top-width" */
  set borderTopWidth(String value) {
    _borderTopWidth = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderTopWidth')
  String _borderTopWidth;

  /** Gets the value of "border-width" */
  String get borderWidth => this._borderWidth;

  /** Sets the value of "border-width" */
  set borderWidth(String value) {
    _borderWidth = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('borderWidth')
  String _borderWidth;

  /** Gets the value of "bottom" */
  String get bottom => this._bottom;

  /** Sets the value of "bottom" */
  set bottom(String value) {
    _bottom = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('bottom')
  String _bottom;

  /** Gets the value of "caption-side" */
  String get captionSide => this._captionSide;

  /** Sets the value of "caption-side" */
  set captionSide(String value) {
    _captionSide = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('captionSide')
  String _captionSide;

  /** Gets the value of "clear" */
  String get clear => this._clear;

  /** Sets the value of "clear" */
  set clear(String value) {
    _clear = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('clear')
  String _clear;

  /** Gets the value of "clip" */
  String get clip => this._clip;

  /** Sets the value of "clip" */
  set clip(String value) {
    _clip = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('clip')
  String _clip;

  /** Gets the value of "color" */
  String get color => this._color;

  /** Sets the value of "color" */
  set color(String value) {
    _color = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('color')
  String _color;

  /** Gets the value of "content" */
  String get content => this._content;

  /** Sets the value of "content" */
  set content(String value) {
    _content = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('content')
  String _content;

  /** Gets the value of "cursor" */
  String get cursor => this._cursor;

  /** Sets the value of "cursor" */
  set cursor(String value) {
    _cursor = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('cursor')
  String _cursor;

  /** Gets the value of "direction" */
  String get direction => this._direction;

  /** Sets the value of "direction" */
  set direction(String value) {
    _direction = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('direction')
  String _direction;

  /** Gets the value of "display" */
  String get display => this._display;

  /** Sets the value of "display" */
  set display(String value) {
    _display = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('display')
  String _display;

  /** Gets the value of "empty-cells" */
  String get emptyCells => this._emptyCells;

  /** Sets the value of "empty-cells" */
  set emptyCells(String value) {
    _emptyCells = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('emptyCells')
  String _emptyCells;

  /** Gets the value of "font" */
  String get font => this._font;

  /** Sets the value of "font" */
  set font(String value) {
    _font = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('font')
  String _font;

  /** Gets the value of "font-family" */
  String get fontFamily => this._fontFamily;

  /** Sets the value of "font-family" */
  set fontFamily(String value) {
    _fontFamily = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('fontFamily')
  String _fontFamily;

  /** Gets the value of "font-size" */
  String get fontSize => this._fontSize;

  /** Sets the value of "font-size" */
  set fontSize(String value) {
    _fontSize = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('fontSize')
  String _fontSize;

  /** Gets the value of "font-style" */
  String get fontStyle => this._fontStyle;

  /** Sets the value of "font-style" */
  set fontStyle(String value) {
    _fontStyle = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('fontStyle')
  String _fontStyle;

  /** Gets the value of "font-variant" */
  String get fontVariant => this._fontVariant;

  /** Sets the value of "font-variant" */
  set fontVariant(String value) {
    _fontVariant = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('fontVariant')
  String _fontVariant;

  /** Gets the value of "font-weight" */
  String get fontWeight => this._fontWeight;

  /** Sets the value of "font-weight" */
  set fontWeight(String value) {
    _fontWeight = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('fontWeight')
  String _fontWeight;

  /** Gets the value of "height" */
  String get height => this._height;

  /** Sets the value of "height" */
  set height(String value) {
    _height = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('height')
  String _height;

  /** Gets the value of "left" */
  String get left => this._left;

  /** Sets the value of "left" */
  set left(String value) {
    _left = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('left')
  String _left;

  /** Gets the value of "letter-spacing" */
  String get letterSpacing => this._letterSpacing;

  /** Sets the value of "letter-spacing" */
  set letterSpacing(String value) {
    _letterSpacing = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('letterSpacing')
  String _letterSpacing;

  /** Gets the value of "line-height" */
  String get lineHeight => this._lineHeight;

  /** Sets the value of "line-height" */
  set lineHeight(String value) {
    _lineHeight = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('lineHeight')
  String _lineHeight;

  /** Gets the value of "list-style" */
  String get listStyle => this._listStyle;

  /** Sets the value of "list-style" */
  set listStyle(String value) {
    _listStyle = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('listStyle')
  String _listStyle;

  /** Gets the value of "list-style-image" */
  String get listStyleImage => this._listStyleImage;

  /** Sets the value of "list-style-image" */
  set listStyleImage(String value) {
    _listStyleImage = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('listStyleImage')
  String _listStyleImage;

  /** Gets the value of "list-style-position" */
  String get listStylePosition => this._listStylePosition;

  /** Sets the value of "list-style-position" */
  set listStylePosition(String value) {
    _listStylePosition = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('listStylePosition')
  String _listStylePosition;

  /** Gets the value of "list-style-type" */
  String get listStyleType => this._listStyleType;

  /** Sets the value of "list-style-type" */
  set listStyleType(String value) {
    _listStyleType = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('listStyleType')
  String _listStyleType;

  /** Gets the value of "margin" */
  String get margin => this._margin;

  /** Sets the value of "margin" */
  set margin(String value) {
    _margin = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('margin')
  String _margin;

  /** Gets the value of "margin-bottom" */
  String get marginBottom => this._marginBottom;

  /** Sets the value of "margin-bottom" */
  set marginBottom(String value) {
    _marginBottom = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('marginBottom')
  String _marginBottom;

  /** Gets the value of "margin-left" */
  String get marginLeft => this._marginLeft;

  /** Sets the value of "margin-left" */
  set marginLeft(String value) {
    _marginLeft = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('marginLeft')
  String _marginLeft;

  /** Gets the value of "margin-right" */
  String get marginRight => this._marginRight;

  /** Sets the value of "margin-right" */
  set marginRight(String value) {
    _marginRight = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('marginRight')
  String _marginRight;

  /** Gets the value of "margin-top" */
  String get marginTop => this._marginTop;

  /** Sets the value of "margin-top" */
  set marginTop(String value) {
    _marginTop = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('marginTop')
  String _marginTop;

  /** Gets the value of "max-height" */
  String get maxHeight => this._maxHeight;

  /** Sets the value of "max-height" */
  set maxHeight(String value) {
    _maxHeight = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('maxHeight')
  String _maxHeight;

  /** Gets the value of "max-width" */
  String get maxWidth => this._maxWidth;

  /** Sets the value of "max-width" */
  set maxWidth(String value) {
    _maxWidth = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('maxWidth')
  String _maxWidth;

  /** Gets the value of "min-height" */
  String get minHeight => this._minHeight;

  /** Sets the value of "min-height" */
  set minHeight(String value) {
    _minHeight = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('minHeight')
  String _minHeight;

  /** Gets the value of "min-width" */
  String get minWidth => this._minWidth;

  /** Sets the value of "min-width" */
  set minWidth(String value) {
    _minWidth = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('minWidth')
  String _minWidth;

  /** Gets the value of "outline" */
  String get outline => this._outline;

  /** Sets the value of "outline" */
  set outline(String value) {
    _outline = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('outline')
  String _outline;

  /** Gets the value of "outline-color" */
  String get outlineColor => this._outlineColor;

  /** Sets the value of "outline-color" */
  set outlineColor(String value) {
    _outlineColor = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('outlineColor')
  String _outlineColor;

  /** Gets the value of "outline-style" */
  String get outlineStyle => this._outlineStyle;

  /** Sets the value of "outline-style" */
  set outlineStyle(String value) {
    _outlineStyle = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('outlineStyle')
  String _outlineStyle;

  /** Gets the value of "outline-width" */
  String get outlineWidth => this._outlineWidth;

  /** Sets the value of "outline-width" */
  set outlineWidth(String value) {
    _outlineWidth = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('outlineWidth')
  String _outlineWidth;

  /** Gets the value of "overflow" */
  String get overflow => this._overflow;

  /** Sets the value of "overflow" */
  set overflow(String value) {
    _overflow = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('overflow')
  String _overflow;

  /** Gets the value of "padding" */
  String get padding => this._padding;

  /** Sets the value of "padding" */
  set padding(String value) {
    _padding = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('padding')
  String _padding;

  /** Gets the value of "padding-bottom" */
  String get paddingBottom => this._paddingBottom;

  /** Sets the value of "padding-bottom" */
  set paddingBottom(String value) {
    _paddingBottom = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('paddingBottom')
  String _paddingBottom;

  /** Gets the value of "padding-left" */
  String get paddingLeft => this._paddingLeft;

  /** Sets the value of "padding-left" */
  set paddingLeft(String value) {
    _paddingLeft = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('paddingLeft')
  String _paddingLeft;

  /** Gets the value of "padding-right" */
  String get paddingRight => this._paddingRight;

  /** Sets the value of "padding-right" */
  set paddingRight(String value) {
    _paddingRight = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('paddingRight')
  String _paddingRight;

  /** Gets the value of "padding-top" */
  String get paddingTop => this._paddingTop;

  /** Sets the value of "padding-top" */
  set paddingTop(String value) {
    _paddingTop = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('paddingTop')
  String _paddingTop;

  /** Gets the value of "page-break-after" */
  String get pageBreakAfter => this._pageBreakAfter;

  /** Sets the value of "page-break-after" */
  set pageBreakAfter(String value) {
    _pageBreakAfter = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('pageBreakAfter')
  String _pageBreakAfter;

  /** Gets the value of "page-break-before" */
  String get pageBreakBefore => this._pageBreakBefore;

  /** Sets the value of "page-break-before" */
  set pageBreakBefore(String value) {
    _pageBreakBefore = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('pageBreakBefore')
  String _pageBreakBefore;

  /** Gets the value of "page-break-inside" */
  String get pageBreakInside => this._pageBreakInside;

  /** Sets the value of "page-break-inside" */
  set pageBreakInside(String value) {
    _pageBreakInside = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('pageBreakInside')
  String _pageBreakInside;

  /** Gets the value of "position" */
  String get position => this._position;

  /** Sets the value of "position" */
  set position(String value) {
    _position = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('position')
  String _position;

  /** Gets the value of "quotes" */
  String get quotes => this._quotes;

  /** Sets the value of "quotes" */
  set quotes(String value) {
    _quotes = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('quotes')
  String _quotes;

  /** Gets the value of "right" */
  String get right => this._right;

  /** Sets the value of "right" */
  set right(String value) {
    _right = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('right')
  String _right;

  /** Gets the value of "table-layout" */
  String get tableLayout => this._tableLayout;

  /** Sets the value of "table-layout" */
  set tableLayout(String value) {
    _tableLayout = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('tableLayout')
  String _tableLayout;

  /** Gets the value of "text-align" */
  String get textAlign => this._textAlign;

  /** Sets the value of "text-align" */
  set textAlign(String value) {
    _textAlign = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('textAlign')
  String _textAlign;

  /** Gets the value of "text-decoration" */
  String get textDecoration => this._textDecoration;

  /** Sets the value of "text-decoration" */
  set textDecoration(String value) {
    _textDecoration = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('textDecoration')
  String _textDecoration;

  /** Gets the value of "text-indent" */
  String get textIndent => this._textIndent;

  /** Sets the value of "text-indent" */
  set textIndent(String value) {
    _textIndent = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('textIndent')
  String _textIndent;

  /** Gets the value of "text-transform" */
  String get textTransform => this._textTransform;

  /** Sets the value of "text-transform" */
  set textTransform(String value) {
    _textTransform = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('textTransform')
  String _textTransform;

  /** Gets the value of "top" */
  String get top => this._top;

  /** Sets the value of "top" */
  set top(String value) {
    _top = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('top')
  String _top;

  /** Gets the value of "unicode-bidi" */
  String get unicodeBidi => this._unicodeBidi;

  /** Sets the value of "unicode-bidi" */
  set unicodeBidi(String value) {
    _unicodeBidi = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('unicodeBidi')
  String _unicodeBidi;

  /** Gets the value of "vertical-align" */
  String get verticalAlign => this._verticalAlign;

  /** Sets the value of "vertical-align" */
  set verticalAlign(String value) {
    _verticalAlign = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('verticalAlign')
  String _verticalAlign;

  /** Gets the value of "visibility" */
  String get visibility => this._visibility;

  /** Sets the value of "visibility" */
  set visibility(String value) {
    _visibility = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('visibility')
  String _visibility;

  /** Gets the value of "white-space" */
  String get whiteSpace => this._whiteSpace;

  /** Sets the value of "white-space" */
  set whiteSpace(String value) {
    _whiteSpace = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('whiteSpace')
  String _whiteSpace;

  /** Gets the value of "width" */
  String get width => this._width;

  /** Sets the value of "width" */
  set width(String value) {
    _width = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('width')
  String _width;

  /** Gets the value of "word-spacing" */
  String get wordSpacing => this._wordSpacing;

  /** Sets the value of "word-spacing" */
  set wordSpacing(String value) {
    _wordSpacing = value == null ? '' : value;
  }

  @Returns('String')
  @JSName('wordSpacing')
  String _wordSpacing;

  /** Gets the value of "z-index" */
  String get zIndex => this._zIndex;

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

  @Returns('String')
  @JSName('zIndex')
  String _zIndex;
}

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

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

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

  void setProperty(String propertyName, String value, [String priority]) {
    _elementCssStyleDeclarationSetIterable
        .forEach((e) => e.setProperty(propertyName, value, priority));
  }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  /** Sets the value of "max-width" */
  set maxWidth(String value) {
    _setAll('maxWidth', value);
  }

  /** Sets the value of "min-height" */
  set minHeight(String value) {
    _setAll('minHeight', value);
  }

  /** Sets the value of "min-width" */
  set minWidth(String value) {
    _setAll('minWidth', value);
  }

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

  /** Sets the value of "outline-color" */
  set outlineColor(String value) {
    _setAll('outlineColor', value);
  }

  /** Sets the value of "outline-style" */
  set outlineStyle(String value) {
    _setAll('outlineStyle', value);
  }

  /** Sets the value of "outline-width" */
  set outlineWidth(String value) {
    _setAll('outlineWidth', value);
  }

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

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

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

  /** Sets the value of "padding-left" */
  set paddingLeft(String value) {
    _setAll('paddingLeft', value);
  }

  /** Sets the value of "padding-right" */
  set paddingRight(String value) {
    _setAll('paddingRight', value);
  }

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

  /** Sets the value of "page-break-after" */
  set pageBreakAfter(String value) {
    _setAll('pageBreakAfter', value);
  }

  /** Sets the value of "page-break-before" */
  set pageBreakBefore(String value) {
    _setAll('pageBreakBefore', value);
  }

  /** Sets the value of "page-break-inside" */
  set pageBreakInside(String value) {
    _setAll('pageBreakInside', value);
  }

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

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

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

  /** Sets the value of "table-layout" */
  set tableLayout(String value) {
    _setAll('tableLayout', value);
  }

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

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

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

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

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

  /** Sets the value of "unicode-bidi" */
  set unicodeBidi(String value) {
    _setAll('unicodeBidi', value);
  }

  /** Sets the value of "vertical-align" */
  set verticalAlign(String value) {
    _setAll('verticalAlign', value);
  }

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

  /** Sets the value of "white-space" */
  set whiteSpace(String value) {
    _setAll('whiteSpace', value);
  }

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

  /** Sets the value of "word-spacing" */
  set wordSpacing(String value) {
    _setAll('wordSpacing', value);
  }

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

  // Important note: CssStyleDeclarationSet does NOT implement every method
  // available in CssStyleDeclaration. Some of the methods don't make so much
  // sense in terms of having a resonable value to return when you're
  // considering a list of Elements. You will need to manually add any of the
  // items in the MEMBERS set if you want that functionality.
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  /** Sets the value of "isolation" */
  set isolation(String value) {
    setProperty('isolation', value, '');
  }

  /** Gets the value of "justify-content" */
  String get justifyContent => getPropertyValue('justify-content');

  /** Sets the value of "justify-content" */
  set justifyContent(String value) {
    setProperty('justify-content', value, '');
  }

  /** Gets the value of "justify-self" */
  String get justifySelf => getPropertyValue('justify-self');

  /** Sets the value of "justify-self" */
  set justifySelf(String value) {
    setProperty('justify-self', value, '');
  }

  /** Gets the value of "left" */
  String get left => getPropertyValue('left');

  /** Sets the value of "left" */
  set left(String value) {
    setProperty('left', value, '');
  }

  /** Gets the value of "letter-spacing" */
  String get letterSpacing => getPropertyValue('letter-spacing');

  /** Sets the value of "letter-spacing" */
  set letterSpacing(String value) {
    setProperty('letter-spacing', value, '');
  }

  /** Gets the value of "line-box-contain" */
  String get lineBoxContain => getPropertyValue('line-box-contain');

  /** Sets the value of "line-box-contain" */
  set lineBoxContain(String value) {
    setProperty('line-box-contain', value, '');
  }

  /** Gets the value of "line-break" */
  String get lineBreak => getPropertyValue('line-break');

  /** Sets the value of "line-break" */
  set lineBreak(String value) {
    setProperty('line-break', value, '');
  }

  /** Gets the value of "line-clamp" */
  String get lineClamp => getPropertyValue('line-clamp');

  /** Sets the value of "line-clamp" */
  set lineClamp(String value) {
    setProperty('line-clamp', value, '');
  }

  /** Gets the value of "line-height" */
  String get lineHeight => getPropertyValue('line-height');

  /** Sets the value of "line-height" */
  set lineHeight(String value) {
    setProperty('line-height', value, '');
  }

  /** Gets the value of "list-style" */
  String get listStyle => getPropertyValue('list-style');

  /** Sets the value of "list-style" */
  set listStyle(String value) {
    setProperty('list-style', value, '');
  }

  /** Gets the value of "list-style-image" */
  String get listStyleImage => getPropertyValue('list-style-image');

  /** Sets the value of "list-style-image" */
  set listStyleImage(String value) {
    setProperty('list-style-image', value, '');
  }

  /** Gets the value of "list-style-position" */
  String get listStylePosition => getPropertyValue('list-style-position');

  /** Sets the value of "list-style-position" */
  set listStylePosition(String value) {
    setProperty('list-style-position', value, '');
  }

  /** Gets the value of "list-style-type" */
  String get listStyleType => getPropertyValue('list-style-type');

  /** Sets the value of "list-style-type" */
  set listStyleType(String value) {
    setProperty('list-style-type', value, '');
  }

  /** Gets the value of "locale" */
  String get locale => getPropertyValue('locale');

  /** Sets the value of "locale" */
  set locale(String value) {
    setProperty('locale', value, '');
  }

  /** Gets the value of "logical-height" */
  String get logicalHeight => getPropertyValue('logical-height');

  /** Sets the value of "logical-height" */
  set logicalHeight(String value) {
    setProperty('logical-height', value, '');
  }

  /** Gets the value of "logical-width" */
  String get logicalWidth => getPropertyValue('logical-width');

  /** Sets the value of "logical-width" */
  set logicalWidth(String value) {
    setProperty('logical-width', value, '');
  }

  /** Gets the value of "margin" */
  String get margin => getPropertyValue('margin');

  /** Sets the value of "margin" */
  set margin(String value) {
    setProperty('margin', value, '');
  }

  /** Gets the value of "margin-after" */
  String get marginAfter => getPropertyValue('margin-after');

  /** Sets the value of "margin-after" */
  set marginAfter(String value) {
    setProperty('margin-after', value, '');
  }

  /** Gets the value of "margin-after-collapse" */
  String get marginAfterCollapse => getPropertyValue('margin-after-collapse');

  /** Sets the value of "margin-after-collapse" */
  set marginAfterCollapse(String value) {
    setProperty('margin-after-collapse', value, '');
  }

  /** Gets the value of "margin-before" */
  String get marginBefore => getPropertyValue('margin-before');

  /** Sets the value of "margin-before" */
  set marginBefore(String value) {
    setProperty('margin-before', value, '');
  }

  /** Gets the value of "margin-before-collapse" */
  String get marginBeforeCollapse => getPropertyValue('margin-before-collapse');

  /** Sets the value of "margin-before-collapse" */
  set marginBeforeCollapse(String value) {
    setProperty('margin-before-collapse', value, '');
  }

  /** Gets the value of "margin-bottom" */
  String get marginBottom => getPropertyValue('margin-bottom');

  /** Sets the value of "margin-bottom" */
  set marginBottom(String value) {
    setProperty('margin-bottom', value, '');
  }

  /** Gets the value of "margin-bottom-collapse" */
  String get marginBottomCollapse => getPropertyValue('margin-bottom-collapse');

  /** Sets the value of "margin-bottom-collapse" */
  set marginBottomCollapse(String value) {
    setProperty('margin-bottom-collapse', value, '');
  }

  /** Gets the value of "margin-collapse" */
  String get marginCollapse => getPropertyValue('margin-collapse');

  /** Sets the value of "margin-collapse" */
  set marginCollapse(String value) {
    setProperty('margin-collapse', value, '');
  }

  /** Gets the value of "margin-end" */
  String get marginEnd => getPropertyValue('margin-end');

  /** Sets the value of "margin-end" */
  set marginEnd(String value) {
    setProperty('margin-end', value, '');
  }

  /** Gets the value of "margin-left" */
  String get marginLeft => getPropertyValue('margin-left');

  /** Sets the value of "margin-left" */
  set marginLeft(String value) {
    setProperty('margin-left', value, '');
  }

  /** Gets the value of "margin-right" */
  String get marginRight => getPropertyValue('margin-right');

  /** Sets the value of "margin-right" */
  set marginRight(String value) {
    setProperty('margin-right', value, '');
  }

  /** Gets the value of "margin-start" */
  String get marginStart => getPropertyValue('margin-start');

  /** Sets the value of "margin-start" */
  set marginStart(String value) {
    setProperty('margin-start', value, '');
  }

  /** Gets the value of "margin-top" */
  String get marginTop => getPropertyValue('margin-top');

  /** Sets the value of "margin-top" */
  set marginTop(String value) {
    setProperty('margin-top', value, '');
  }

  /** Gets the value of "margin-top-collapse" */
  String get marginTopCollapse => getPropertyValue('margin-top-collapse');

  /** Sets the value of "margin-top-collapse" */
  set marginTopCollapse(String value) {
    setProperty('margin-top-collapse', value, '');
  }

  /** Gets the value of "mask" */
  String get mask => getPropertyValue('mask');

  /** Sets the value of "mask" */
  set mask(String value) {
    setProperty('mask', value, '');
  }

  /** Gets the value of "mask-box-image" */
  String get maskBoxImage => getPropertyValue('mask-box-image');

  /** Sets the value of "mask-box-image" */
  set maskBoxImage(String value) {
    setProperty('mask-box-image', value, '');
  }

  /** Gets the value of "mask-box-image-outset" */
  String get maskBoxImageOutset => getPropertyValue('mask-box-image-outset');

  /** Sets the value of "mask-box-image-outset" */
  set maskBoxImageOutset(String value) {
    setProperty('mask-box-image-outset', value, '');
  }

  /** Gets the value of "mask-box-image-repeat" */
  String get maskBoxImageRepeat => getPropertyValue('mask-box-image-repeat');

  /** Sets the value of "mask-box-image-repeat" */
  set maskBoxImageRepeat(String value) {
    setProperty('mask-box-image-repeat', value, '');
  }

  /** Gets the value of "mask-box-image-slice" */
  String get maskBoxImageSlice => getPropertyValue('mask-box-image-slice');

  /** Sets the value of "mask-box-image-slice" */
  set maskBoxImageSlice(String value) {
    setProperty('mask-box-image-slice', value, '');
  }

  /** Gets the value of "mask-box-image-source" */
  String get maskBoxImageSource => getPropertyValue('mask-box-image-source');

  /** Sets the value of "mask-box-image-source" */
  set maskBoxImageSource(String value) {
    setProperty('mask-box-image-source', value, '');
  }

  /** Gets the value of "mask-box-image-width" */
  String get maskBoxImageWidth => getPropertyValue('mask-box-image-width');

  /** Sets the value of "mask-box-image-width" */
  set maskBoxImageWidth(String value) {
    setProperty('mask-box-image-width', value, '');
  }

  /** Gets the value of "mask-clip" */
  String get maskClip => getPropertyValue('mask-clip');

  /** Sets the value of "mask-clip" */
  set maskClip(String value) {
    setProperty('mask-clip', value, '');
  }

  /** Gets the value of "mask-composite" */
  String get maskComposite => getPropertyValue('mask-composite');

  /** Sets the value of "mask-composite" */
  set maskComposite(String value) {
    setProperty('mask-composite', value, '');
  }

  /** Gets the value of "mask-image" */
  String get maskImage => getPropertyValue('mask-image');

  /** Sets the value of "mask-image" */
  set maskImage(String value) {
    setProperty('mask-image', value, '');
  }

  /** Gets the value of "mask-origin" */
  String get maskOrigin => getPropertyValue('mask-origin');

  /** Sets the value of "mask-origin" */
  set maskOrigin(String value) {
    setProperty('mask-origin', value, '');
  }

  /** Gets the value of "mask-position" */
  String get maskPosition => getPropertyValue('mask-position');

  /** Sets the value of "mask-position" */
  set maskPosition(String value) {
    setProperty('mask-position', value, '');
  }

  /** Gets the value of "mask-position-x" */
  String get maskPositionX => getPropertyValue('mask-position-x');

  /** Sets the value of "mask-position-x" */
  set maskPositionX(String value) {
    setProperty('mask-position-x', value, '');
  }

  /** Gets the value of "mask-position-y" */
  String get maskPositionY => getPropertyValue('mask-position-y');

  /** Sets the value of "mask-position-y" */
  set maskPositionY(String value) {
    setProperty('mask-position-y', value, '');
  }

  /** Gets the value of "mask-repeat" */
  String get maskRepeat => getPropertyValue('mask-repeat');

  /** Sets the value of "mask-repeat" */
  set maskRepeat(String value) {
    setProperty('mask-repeat', value, '');
  }

  /** Gets the value of "mask-repeat-x" */
  String get maskRepeatX => getPropertyValue('mask-repeat-x');

  /** Sets the value of "mask-repeat-x" */
  set maskRepeatX(String value) {
    setProperty('mask-repeat-x', value, '');
  }

  /** Gets the value of "mask-repeat-y" */
  String get maskRepeatY => getPropertyValue('mask-repeat-y');

  /** Sets the value of "mask-repeat-y" */
  set maskRepeatY(String value) {
    setProperty('mask-repeat-y', value, '');
  }

  /** Gets the value of "mask-size" */
  String get maskSize => getPropertyValue('mask-size');

  /** Sets the value of "mask-size" */
  set maskSize(String value) {
    setProperty('mask-size', value, '');
  }

  /** Gets the value of "mask-source-type" */
  String get maskSourceType => getPropertyValue('mask-source-type');

  /** Sets the value of "mask-source-type" */
  set maskSourceType(String value) {
    setProperty('mask-source-type', value, '');
  }

  /** Gets the value of "max-height" */
  String get maxHeight => getPropertyValue('max-height');

  /** Sets the value of "max-height" */
  set maxHeight(String value) {
    setProperty('max-height', value, '');
  }

  /** Gets the value of "max-logical-height" */
  String get maxLogicalHeight => getPropertyValue('max-logical-height');

  /** Sets the value of "max-logical-height" */
  set maxLogicalHeight(String value) {
    setProperty('max-logical-height', value, '');
  }

  /** Gets the value of "max-logical-width" */
  String get maxLogicalWidth => getPropertyValue('max-logical-width');

  /** Sets the value of "max-logical-width" */
  set maxLogicalWidth(String value) {
    setProperty('max-logical-width', value, '');
  }

  /** Gets the value of "max-width" */
  String get maxWidth => getPropertyValue('max-width');

  /** Sets the value of "max-width" */
  set maxWidth(String value) {
    setProperty('max-width', value, '');
  }

  /** Gets the value of "max-zoom" */
  String get maxZoom => getPropertyValue('max-zoom');

  /** Sets the value of "max-zoom" */
  set maxZoom(String value) {
    setProperty('max-zoom', value, '');
  }

  /** Gets the value of "min-height" */
  String get minHeight => getPropertyValue('min-height');

  /** Sets the value of "min-height" */
  set minHeight(String value) {
    setProperty('min-height', value, '');
  }

  /** Gets the value of "min-logical-height" */
  String get minLogicalHeight => getPropertyValue('min-logical-height');

  /** Sets the value of "min-logical-height" */
  set minLogicalHeight(String value) {
    setProperty('min-logical-height', value, '');
  }

  /** Gets the value of "min-logical-width" */
  String get minLogicalWidth => getPropertyValue('min-logical-width');

  /** Sets the value of "min-logical-width" */
  set minLogicalWidth(String value) {
    setProperty('min-logical-width', value, '');
  }

  /** Gets the value of "min-width" */
  String get minWidth => getPropertyValue('min-width');

  /** Sets the value of "min-width" */
  set minWidth(String value) {
    setProperty('min-width', value, '');
  }

  /** Gets the value of "min-zoom" */
  String get minZoom => getPropertyValue('min-zoom');

  /** Sets the value of "min-zoom" */
  set minZoom(String value) {
    setProperty('min-zoom', value, '');
  }

  /** Gets the value of "mix-blend-mode" */
  String get mixBlendMode => getPropertyValue('mix-blend-mode');

  /** Sets the value of "mix-blend-mode" */
  set mixBlendMode(String value) {
    setProperty('mix-blend-mode', value, '');
  }

  /** Gets the value of "object-fit" */
  String get objectFit => getPropertyValue('object-fit');

  /** Sets the value of "object-fit" */
  set objectFit(String value) {
    setProperty('object-fit', value, '');
  }

  /** Gets the value of "object-position" */
  String get objectPosition => getPropertyValue('object-position');

  /** Sets the value of "object-position" */
  set objectPosition(String value) {
    setProperty('object-position', value, '');
  }

  /** Gets the value of "opacity" */
  String get opacity => getPropertyValue('opacity');

  /** Sets the value of "opacity" */
  set opacity(String value) {
    setProperty('opacity', value, '');
  }

  /** Gets the value of "order" */
  String get order => getPropertyValue('order');

  /** Sets the value of "order" */
  set order(String value) {
    setProperty('order', value, '');
  }

  /** Gets the value of "orientation" */
  String get orientation => getPropertyValue('orientation');

  /** Sets the value of "orientation" */
  set orientation(String value) {
    setProperty('orientation', value, '');
  }

  /** Gets the value of "orphans" */
  String get orphans => getPropertyValue('orphans');

  /** Sets the value of "orphans" */
  set orphans(String value) {
    setProperty('orphans', value, '');
  }

  /** Gets the value of "outline" */
  String get outline => getPropertyValue('outline');

  /** Sets the value of "outline" */
  set outline(String value) {
    setProperty('outline', value, '');
  }

  /** Gets the value of "outline-color" */
  String get outlineColor => getPropertyValue('outline-color');

  /** Sets the value of "outline-color" */
  set outlineColor(String value) {
    setProperty('outline-color', value, '');
  }

  /** Gets the value of "outline-offset" */
  String get outlineOffset => getPropertyValue('outline-offset');

  /** Sets the value of "outline-offset" */
  set outlineOffset(String value) {
    setProperty('outline-offset', value, '');
  }

  /** Gets the value of "outline-style" */
  String get outlineStyle => getPropertyValue('outline-style');

  /** Sets the value of "outline-style" */
  set outlineStyle(String value) {
    setProperty('outline-style', value, '');
  }

  /** Gets the value of "outline-width" */
  String get outlineWidth => getPropertyValue('outline-width');

  /** Sets the value of "outline-width" */
  set outlineWidth(String value) {
    setProperty('outline-width', value, '');
  }

  /** Gets the value of "overflow" */
  String get overflow => getPropertyValue('overflow');

  /** Sets the value of "overflow" */
  set overflow(String value) {
    setProperty('overflow', value, '');
  }

  /** Gets the value of "overflow-wrap" */
  String get overflowWrap => getPropertyValue('overflow-wrap');

  /** Sets the value of "overflow-wrap" */
  set overflowWrap(String value) {
    setProperty('overflow-wrap', value, '');
  }

  /** Gets the value of "overflow-x" */
  String get overflowX => getPropertyValue('overflow-x');

  /** Sets the value of "overflow-x" */
  set overflowX(String value) {
    setProperty('overflow-x', value, '');
  }

  /** Gets the value of "overflow-y" */
  String get overflowY => getPropertyValue('overflow-y');

  /** Sets the value of "overflow-y" */
  set overflowY(String value) {
    setProperty('overflow-y', value, '');
  }

  /** Gets the value of "padding" */
  String get padding => getPropertyValue('padding');

  /** Sets the value of "padding" */
  set padding(String value) {
    setProperty('padding', value, '');
  }

  /** Gets the value of "padding-after" */
  String get paddingAfter => getPropertyValue('padding-after');

  /** Sets the value of "padding-after" */
  set paddingAfter(String value) {
    setProperty('padding-after', value, '');
  }

  /** Gets the value of "padding-before" */
  String get paddingBefore => getPropertyValue('padding-before');

  /** Sets the value of "padding-before" */
  set paddingBefore(String value) {
    setProperty('padding-before', value, '');
  }

  /** Gets the value of "padding-bottom" */
  String get paddingBottom => getPropertyValue('padding-bottom');

  /** Sets the value of "padding-bottom" */
  set paddingBottom(String value) {
    setProperty('padding-bottom', value, '');
  }

  /** Gets the value of "padding-end" */
  String get paddingEnd => getPropertyValue('padding-end');

  /** Sets the value of "padding-end" */
  set paddingEnd(String value) {
    setProperty('padding-end', value, '');
  }

  /** Gets the value of "padding-left" */
  String get paddingLeft => getPropertyValue('padding-left');

  /** Sets the value of "padding-left" */
  set paddingLeft(String value) {
    setProperty('padding-left', value, '');
  }

  /** Gets the value of "padding-right" */
  String get paddingRight => getPropertyValue('padding-right');

  /** Sets the value of "padding-right" */
  set paddingRight(String value) {
    setProperty('padding-right', value, '');
  }

  /** Gets the value of "padding-start" */
  String get paddingStart => getPropertyValue('padding-start');

  /** Sets the value of "padding-start" */
  set paddingStart(String value) {
    setProperty('padding-start', value, '');
  }

  /** Gets the value of "padding-top" */
  String get paddingTop => getPropertyValue('padding-top');

  /** Sets the value of "padding-top" */
  set paddingTop(String value) {
    setProperty('padding-top', value, '');
  }

  /** Gets the value of "page" */
  String get page => getPropertyValue('page');

  /** Sets the value of "page" */
  set page(String value) {
    setProperty('page', value, '');
  }

  /** Gets the value of "page-break-after" */
  String get pageBreakAfter => getPropertyValue('page-break-after');

  /** Sets the value of "page-break-after" */
  set pageBreakAfter(String value) {
    setProperty('page-break-after', value, '');
  }

  /** Gets the value of "page-break-before" */
  String get pageBreakBefore => getPropertyValue('page-break-before');

  /** Sets the value of "page-break-before" */
  set pageBreakBefore(String value) {
    setProperty('page-break-before', value, '');
  }

  /** Gets the value of "page-break-inside" */
  String get pageBreakInside => getPropertyValue('page-break-inside');

  /** Sets the value of "page-break-inside" */
  set pageBreakInside(String value) {
    setProperty('page-break-inside', value, '');
  }

  /** Gets the value of "perspective" */
  String get perspective => getPropertyValue('perspective');

  /** Sets the value of "perspective" */
  set perspective(String value) {
    setProperty('perspective', value, '');
  }

  /** Gets the value of "perspective-origin" */
  String get perspectiveOrigin => getPropertyValue('perspective-origin');

  /** Sets the value of "perspective-origin" */
  set perspectiveOrigin(String value) {
    setProperty('perspective-origin', value, '');
  }

  /** Gets the value of "perspective-origin-x" */
  String get perspectiveOriginX => getPropertyValue('perspective-origin-x');

  /** Sets the value of "perspective-origin-x" */
  set perspectiveOriginX(String value) {
    setProperty('perspective-origin-x', value, '');
  }

  /** Gets the value of "perspective-origin-y" */
  String get perspectiveOriginY => getPropertyValue('perspective-origin-y');

  /** Sets the value of "perspective-origin-y" */
  set perspectiveOriginY(String value) {
    setProperty('perspective-origin-y', value, '');
  }

  /** Gets the value of "pointer-events" */
  String get pointerEvents => getPropertyValue('pointer-events');

  /** Sets the value of "pointer-events" */
  set pointerEvents(String value) {
    setProperty('pointer-events', value, '');
  }

  /** Gets the value of "position" */
  String get position => getPropertyValue('position');

  /** Sets the value of "position" */
  set position(String value) {
    setProperty('position', value, '');
  }

  /** Gets the value of "print-color-adjust" */
  String get printColorAdjust => getPropertyValue('print-color-adjust');

  /** Sets the value of "print-color-adjust" */
  set printColorAdjust(String value) {
    setProperty('print-color-adjust', value, '');
  }

  /** Gets the value of "quotes" */
  String get quotes => getPropertyValue('quotes');

  /** Sets the value of "quotes" */
  set quotes(String value) {
    setProperty('quotes', value, '');
  }

  /** Gets the value of "resize" */
  String get resize => getPropertyValue('resize');

  /** Sets the value of "resize" */
  set resize(String value) {
    setProperty('resize', value, '');
  }

  /** Gets the value of "right" */
  String get right => getPropertyValue('right');

  /** Sets the value of "right" */
  set right(String value) {
    setProperty('right', value, '');
  }

  /** Gets the value of "rtl-ordering" */
  String get rtlOrdering => getPropertyValue('rtl-ordering');

  /** Sets the value of "rtl-ordering" */
  set rtlOrdering(String value) {
    setProperty('rtl-ordering', value, '');
  }

  /** Gets the value of "ruby-position" */
  String get rubyPosition => getPropertyValue('ruby-position');

  /** Sets the value of "ruby-position" */
  set rubyPosition(String value) {
    setProperty('ruby-position', value, '');
  }

  /** Gets the value of "scroll-behavior" */
  String get scrollBehavior => getPropertyValue('scroll-behavior');

  /** Sets the value of "scroll-behavior" */
  set scrollBehavior(String value) {
    setProperty('scroll-behavior', value, '');
  }

  /** Gets the value of "shape-image-threshold" */
  String get shapeImageThreshold => getPropertyValue('shape-image-threshold');

  /** Sets the value of "shape-image-threshold" */
  set shapeImageThreshold(String value) {
    setProperty('shape-image-threshold', value, '');
  }

  /** Gets the value of "shape-margin" */
  String get shapeMargin => getPropertyValue('shape-margin');

  /** Sets the value of "shape-margin" */
  set shapeMargin(String value) {
    setProperty('shape-margin', value, '');
  }

  /** Gets the value of "shape-outside" */
  String get shapeOutside => getPropertyValue('shape-outside');

  /** Sets the value of "shape-outside" */
  set shapeOutside(String value) {
    setProperty('shape-outside', value, '');
  }

  /** Gets the value of "size" */
  String get size => getPropertyValue('size');

  /** Sets the value of "size" */
  set size(String value) {
    setProperty('size', value, '');
  }

  /** Gets the value of "speak" */
  String get speak => getPropertyValue('speak');

  /** Sets the value of "speak" */
  set speak(String value) {
    setProperty('speak', value, '');
  }

  /** Gets the value of "src" */
  String get src => getPropertyValue('src');

  /** Sets the value of "src" */
  set src(String value) {
    setProperty('src', value, '');
  }

  /** Gets the value of "tab-size" */
  String get tabSize => getPropertyValue('tab-size');

  /** Sets the value of "tab-size" */
  set tabSize(String value) {
    setProperty('tab-size', value, '');
  }

  /** Gets the value of "table-layout" */
  String get tableLayout => getPropertyValue('table-layout');

  /** Sets the value of "table-layout" */
  set tableLayout(String value) {
    setProperty('table-layout', value, '');
  }

  /** Gets the value of "tap-highlight-color" */
  String get tapHighlightColor => getPropertyValue('tap-highlight-color');

  /** Sets the value of "tap-highlight-color" */
  set tapHighlightColor(String value) {
    setProperty('tap-highlight-color', value, '');
  }

  /** Gets the value of "text-align" */
  String get textAlign => getPropertyValue('text-align');

  /** Sets the value of "text-align" */
  set textAlign(String value) {
    setProperty('text-align', value, '');
  }

  /** Gets the value of "text-align-last" */
  String get textAlignLast => getPropertyValue('text-align-last');

  /** Sets the value of "text-align-last" */
  set textAlignLast(String value) {
    setProperty('text-align-last', value, '');
  }

  /** Gets the value of "text-combine" */
  String get textCombine => getPropertyValue('text-combine');

  /** Sets the value of "text-combine" */
  set textCombine(String value) {
    setProperty('text-combine', value, '');
  }

  /** Gets the value of "text-decoration" */
  String get textDecoration => getPropertyValue('text-decoration');

  /** Sets the value of "text-decoration" */
  set textDecoration(String value) {
    setProperty('text-decoration', value, '');
  }

  /** Gets the value of "text-decoration-color" */
  String get textDecorationColor => getPropertyValue('text-decoration-color');

  /** Sets the value of "text-decoration-color" */
  set textDecorationColor(String value) {
    setProperty('text-decoration-color', value, '');
  }

  /** Gets the value of "text-decoration-line" */
  String get textDecorationLine => getPropertyValue('text-decoration-line');

  /** Sets the value of "text-decoration-line" */
  set textDecorationLine(String value) {
    setProperty('text-decoration-line', value, '');
  }

  /** Gets the value of "text-decoration-style" */
  String get textDecorationStyle => getPropertyValue('text-decoration-style');

  /** Sets the value of "text-decoration-style" */
  set textDecorationStyle(String value) {
    setProperty('text-decoration-style', value, '');
  }

  /** Gets the value of "text-decorations-in-effect" */
  String get textDecorationsInEffect =>
      getPropertyValue('text-decorations-in-effect');

  /** Sets the value of "text-decorations-in-effect" */
  set textDecorationsInEffect(String value) {
    setProperty('text-decorations-in-effect', value, '');
  }

  /** Gets the value of "text-emphasis" */
  String get textEmphasis => getPropertyValue('text-emphasis');

  /** Sets the value of "text-emphasis" */
  set textEmphasis(String value) {
    setProperty('text-emphasis', value, '');
  }

  /** Gets the value of "text-emphasis-color" */
  String get textEmphasisColor => getPropertyValue('text-emphasis-color');

  /** Sets the value of "text-emphasis-color" */
  set textEmphasisColor(String value) {
    setProperty('text-emphasis-color', value, '');
  }

  /** Gets the value of "text-emphasis-position" */
  String get textEmphasisPosition => getPropertyValue('text-emphasis-position');

  /** Sets the value of "text-emphasis-position" */
  set textEmphasisPosition(String value) {
    setProperty('text-emphasis-position', value, '');
  }

  /** Gets the value of "text-emphasis-style" */
  String get textEmphasisStyle => getPropertyValue('text-emphasis-style');

  /** Sets the value of "text-emphasis-style" */
  set textEmphasisStyle(String value) {
    setProperty('text-emphasis-style', value, '');
  }

  /** Gets the value of "text-fill-color" */
  String get textFillColor => getPropertyValue('text-fill-color');

  /** Sets the value of "text-fill-color" */
  set textFillColor(String value) {
    setProperty('text-fill-color', value, '');
  }

  /** Gets the value of "text-indent" */
  String get textIndent => getPropertyValue('text-indent');

  /** Sets the value of "text-indent" */
  set textIndent(String value) {
    setProperty('text-indent', value, '');
  }

  /** Gets the value of "text-justify" */
  String get textJustify => getPropertyValue('text-justify');

  /** Sets the value of "text-justify" */
  set textJustify(String value) {
    setProperty('text-justify', value, '');
  }

  /** Gets the value of "text-line-through-color" */
  String get textLineThroughColor =>
      getPropertyValue('text-line-through-color');

  /** Sets the value of "text-line-through-color" */
  set textLineThroughColor(String value) {
    setProperty('text-line-through-color', value, '');
  }

  /** Gets the value of "text-line-through-mode" */
  String get textLineThroughMode => getPropertyValue('text-line-through-mode');

  /** Sets the value of "text-line-through-mode" */
  set textLineThroughMode(String value) {
    setProperty('text-line-through-mode', value, '');
  }

  /** Gets the value of "text-line-through-style" */
  String get textLineThroughStyle =>
      getPropertyValue('text-line-through-style');

  /** Sets the value of "text-line-through-style" */
  set textLineThroughStyle(String value) {
    setProperty('text-line-through-style', value, '');
  }

  /** Gets the value of "text-line-through-width" */
  String get textLineThroughWidth =>
      getPropertyValue('text-line-through-width');

  /** Sets the value of "text-line-through-width" */
  set textLineThroughWidth(String value) {
    setProperty('text-line-through-width', value, '');
  }

  /** Gets the value of "text-orientation" */
  String get textOrientation => getPropertyValue('text-orientation');

  /** Sets the value of "text-orientation" */
  set textOrientation(String value) {
    setProperty('text-orientation', value, '');
  }

  /** Gets the value of "text-overflow" */
  String get textOverflow => getPropertyValue('text-overflow');

  /** Sets the value of "text-overflow" */
  set textOverflow(String value) {
    setProperty('text-overflow', value, '');
  }

  /** Gets the value of "text-overline-color" */
  String get textOverlineColor => getPropertyValue('text-overline-color');

  /** Sets the value of "text-overline-color" */
  set textOverlineColor(String value) {
    setProperty('text-overline-color', value, '');
  }

  /** Gets the value of "text-overline-mode" */
  String get textOverlineMode => getPropertyValue('text-overline-mode');

  /** Sets the value of "text-overline-mode" */
  set textOverlineMode(String value) {
    setProperty('text-overline-mode', value, '');
  }

  /** Gets the value of "text-overline-style" */
  String get textOverlineStyle => getPropertyValue('text-overline-style');

  /** Sets the value of "text-overline-style" */
  set textOverlineStyle(String value) {
    setProperty('text-overline-style', value, '');
  }

  /** Gets the value of "text-overline-width" */
  String get textOverlineWidth => getPropertyValue('text-overline-width');

  /** Sets the value of "text-overline-width" */
  set textOverlineWidth(String value) {
    setProperty('text-overline-width', value, '');
  }

  /** Gets the value of "text-rendering" */
  String get textRendering => getPropertyValue('text-rendering');

  /** Sets the value of "text-rendering" */
  set textRendering(String value) {
    setProperty('text-rendering', value, '');
  }

  /** Gets the value of "text-security" */
  String get textSecurity => getPropertyValue('text-security');

  /** Sets the value of "text-security" */
  set textSecurity(String value) {
    setProperty('text-security', value, '');
  }

  /** Gets the value of "text-shadow" */
  String get textShadow => getPropertyValue('text-shadow');

  /** Sets the value of "text-shadow" */
  set textShadow(String value) {
    setProperty('text-shadow', value, '');
  }

  /** Gets the value of "text-stroke" */
  String get textStroke => getPropertyValue('text-stroke');

  /** Sets the value of "text-stroke" */
  set textStroke(String value) {
    setProperty('text-stroke', value, '');
  }

  /** Gets the value of "text-stroke-color" */
  String get textStrokeColor => getPropertyValue('text-stroke-color');

  /** Sets the value of "text-stroke-color" */
  set textStrokeColor(String value) {
    setProperty('text-stroke-color', value, '');
  }

  /** Gets the value of "text-stroke-width" */
  String get textStrokeWidth => getPropertyValue('text-stroke-width');

  /** Sets the value of "text-stroke-width" */
  set textStrokeWidth(String value) {
    setProperty('text-stroke-width', value, '');
  }

  /** Gets the value of "text-transform" */
  String get textTransform => getPropertyValue('text-transform');

  /** Sets the value of "text-transform" */
  set textTransform(String value) {
    setProperty('text-transform', value, '');
  }

  /** Gets the value of "text-underline-color" */
  String get textUnderlineColor => getPropertyValue('text-underline-color');

  /** Sets the value of "text-underline-color" */
  set textUnderlineColor(String value) {
    setProperty('text-underline-color', value, '');
  }

  /** Gets the value of "text-underline-mode" */
  String get textUnderlineMode => getPropertyValue('text-underline-mode');

  /** Sets the value of "text-underline-mode" */
  set textUnderlineMode(String value) {
    setProperty('text-underline-mode', value, '');
  }

  /** Gets the value of "text-underline-position" */
  String get textUnderlinePosition =>
      getPropertyValue('text-underline-position');

  /** Sets the value of "text-underline-position" */
  set textUnderlinePosition(String value) {
    setProperty('text-underline-position', value, '');
  }

  /** Gets the value of "text-underline-style" */
  String get textUnderlineStyle => getPropertyValue('text-underline-style');

  /** Sets the value of "text-underline-style" */
  set textUnderlineStyle(String value) {
    setProperty('text-underline-style', value, '');
  }

  /** Gets the value of "text-underline-width" */
  String get textUnderlineWidth => getPropertyValue('text-underline-width');

  /** Sets the value of "text-underline-width" */
  set textUnderlineWidth(String value) {
    setProperty('text-underline-width', value, '');
  }

  /** Gets the value of "top" */
  String get top => getPropertyValue('top');

  /** Sets the value of "top" */
  set top(String value) {
    setProperty('top', value, '');
  }

  /** Gets the value of "touch-action" */
  String get touchAction => getPropertyValue('touch-action');

  /** Sets the value of "touch-action" */
  set touchAction(String value) {
    setProperty('touch-action', value, '');
  }

  /** Gets the value of "touch-action-delay" */
  String get touchActionDelay => getPropertyValue('touch-action-delay');

  /** Sets the value of "touch-action-delay" */
  set touchActionDelay(String value) {
    setProperty('touch-action-delay', value, '');
  }

  /** Gets the value of "transform" */
  String get transform => getPropertyValue('transform');

  /** Sets the value of "transform" */
  set transform(String value) {
    setProperty('transform', value, '');
  }

  /** Gets the value of "transform-origin" */
  String get transformOrigin => getPropertyValue('transform-origin');

  /** Sets the value of "transform-origin" */
  set transformOrigin(String value) {
    setProperty('transform-origin', value, '');
  }

  /** Gets the value of "transform-origin-x" */
  String get transformOriginX => getPropertyValue('transform-origin-x');

  /** Sets the value of "transform-origin-x" */
  set transformOriginX(String value) {
    setProperty('transform-origin-x', value, '');
  }

  /** Gets the value of "transform-origin-y" */
  String get transformOriginY => getPropertyValue('transform-origin-y');

  /** Sets the value of "transform-origin-y" */
  set transformOriginY(String value) {
    setProperty('transform-origin-y', value, '');
  }

  /** Gets the value of "transform-origin-z" */
  String get transformOriginZ => getPropertyValue('transform-origin-z');

  /** Sets the value of "transform-origin-z" */
  set transformOriginZ(String value) {
    setProperty('transform-origin-z', value, '');
  }

  /** Gets the value of "transform-style" */
  String get transformStyle => getPropertyValue('transform-style');

  /** Sets the value of "transform-style" */
  set transformStyle(String value) {
    setProperty('transform-style', value, '');
  }

  /** Gets the value of "transition" */ @SupportedBrowser(
      SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  String get transition => getPropertyValue('transition');

  /** Sets the value of "transition" */ @SupportedBrowser(
      SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  set transition(String value) {
    setProperty('transition', value, '');
  }

  /** Gets the value of "transition-delay" */
  String get transitionDelay => getPropertyValue('transition-delay');

  /** Sets the value of "transition-delay" */
  set transitionDelay(String value) {
    setProperty('transition-delay', value, '');
  }

  /** Gets the value of "transition-duration" */
  String get transitionDuration => getPropertyValue('transition-duration');

  /** Sets the value of "transition-duration" */
  set transitionDuration(String value) {
    setProperty('transition-duration', value, '');
  }

  /** Gets the value of "transition-property" */
  String get transitionProperty => getPropertyValue('transition-property');

  /** Sets the value of "transition-property" */
  set transitionProperty(String value) {
    setProperty('transition-property', value, '');
  }

  /** Gets the value of "transition-timing-function" */
  String get transitionTimingFunction =>
      getPropertyValue('transition-timing-function');

  /** Sets the value of "transition-timing-function" */
  set transitionTimingFunction(String value) {
    setProperty('transition-timing-function', value, '');
  }

  /** Gets the value of "unicode-bidi" */
  String get unicodeBidi => getPropertyValue('unicode-bidi');

  /** Sets the value of "unicode-bidi" */
  set unicodeBidi(String value) {
    setProperty('unicode-bidi', value, '');
  }

  /** Gets the value of "unicode-range" */
  String get unicodeRange => getPropertyValue('unicode-range');

  /** Sets the value of "unicode-range" */
  set unicodeRange(String value) {
    setProperty('unicode-range', value, '');
  }

  /** Gets the value of "user-drag" */
  String get userDrag => getPropertyValue('user-drag');

  /** Sets the value of "user-drag" */
  set userDrag(String value) {
    setProperty('user-drag', value, '');
  }

  /** Gets the value of "user-modify" */
  String get userModify => getPropertyValue('user-modify');

  /** Sets the value of "user-modify" */
  set userModify(String value) {
    setProperty('user-modify', value, '');
  }

  /** Gets the value of "user-select" */
  String get userSelect => getPropertyValue('user-select');

  /** Sets the value of "user-select" */
  set userSelect(String value) {
    setProperty('user-select', value, '');
  }

  /** Gets the value of "user-zoom" */
  String get userZoom => getPropertyValue('user-zoom');

  /** Sets the value of "user-zoom" */
  set userZoom(String value) {
    setProperty('user-zoom', value, '');
  }

  /** Gets the value of "vertical-align" */
  String get verticalAlign => getPropertyValue('vertical-align');

  /** Sets the value of "vertical-align" */
  set verticalAlign(String value) {
    setProperty('vertical-align', value, '');
  }

  /** Gets the value of "visibility" */
  String get visibility => getPropertyValue('visibility');

  /** Sets the value of "visibility" */
  set visibility(String value) {
    setProperty('visibility', value, '');
  }

  /** Gets the value of "white-space" */
  String get whiteSpace => getPropertyValue('white-space');

  /** Sets the value of "white-space" */
  set whiteSpace(String value) {
    setProperty('white-space', value, '');
  }

  /** Gets the value of "widows" */
  String get widows => getPropertyValue('widows');

  /** Sets the value of "widows" */
  set widows(String value) {
    setProperty('widows', value, '');
  }

  /** Gets the value of "width" */
  String get width => getPropertyValue('width');

  /** Sets the value of "width" */
  set width(String value) {
    setProperty('width', value, '');
  }

  /** Gets the value of "will-change" */
  String get willChange => getPropertyValue('will-change');

  /** Sets the value of "will-change" */
  set willChange(String value) {
    setProperty('will-change', value, '');
  }

  /** Gets the value of "word-break" */
  String get wordBreak => getPropertyValue('word-break');

  /** Sets the value of "word-break" */
  set wordBreak(String value) {
    setProperty('word-break', value, '');
  }

  /** Gets the value of "word-spacing" */
  String get wordSpacing => getPropertyValue('word-spacing');

  /** Sets the value of "word-spacing" */
  set wordSpacing(String value) {
    setProperty('word-spacing', value, '');
  }

  /** Gets the value of "word-wrap" */
  String get wordWrap => getPropertyValue('word-wrap');

  /** Sets the value of "word-wrap" */
  set wordWrap(String value) {
    setProperty('word-wrap', value, '');
  }

  /** Gets the value of "wrap-flow" */
  String get wrapFlow => getPropertyValue('wrap-flow');

  /** Sets the value of "wrap-flow" */
  set wrapFlow(String value) {
    setProperty('wrap-flow', value, '');
  }

  /** Gets the value of "wrap-through" */
  String get wrapThrough => getPropertyValue('wrap-through');

  /** Sets the value of "wrap-through" */
  set wrapThrough(String value) {
    setProperty('wrap-through', value, '');
  }

  /** Gets the value of "writing-mode" */
  String get writingMode => getPropertyValue('writing-mode');

  /** Sets the value of "writing-mode" */
  set writingMode(String value) {
    setProperty('writing-mode', value, '');
  }

  /** Gets the value of "z-index" */
  String get zIndex => getPropertyValue('z-index');

  /** Sets the value of "z-index" */
  set zIndex(String value) {
    setProperty('z-index', value, '');
  }

  /** Gets the value of "zoom" */
  String get zoom => getPropertyValue('zoom');

  /** Sets the value of "zoom" */
  set zoom(String value) {
    setProperty('zoom', value, '');
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('CSSStyleRule')
@Native("CSSStyleRule")
class CssStyleRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssStyleRule._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('CSSStyleRule.selectorText')
  @DocsEditable()
  String selectorText;

  @DomName('CSSStyleRule.style')
  @DocsEditable()
  final CssStyleDeclaration style;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('CSSStyleSheet')
@Native("CSSStyleSheet")
class CssStyleSheet extends StyleSheet {
  // To suppress missing implicit constructor warnings.
  factory CssStyleSheet._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('CSSStyleSheet.cssRules')
  @DocsEditable()
  @Returns('_CssRuleList|Null')
  @Creates('_CssRuleList')
  final List<CssRule> cssRules;

  @DomName('CSSStyleSheet.ownerRule')
  @DocsEditable()
  final CssRule ownerRule;

  @DomName('CSSStyleSheet.rules')
  @DocsEditable()
  @Experimental() // non-standard
  @Returns('_CssRuleList|Null')
  @Creates('_CssRuleList')
  final List<CssRule> rules;

  @DomName('CSSStyleSheet.addRule')
  @DocsEditable()
  @Experimental() // non-standard
  int addRule(String selector, String style, [int index]) native;

  @DomName('CSSStyleSheet.deleteRule')
  @DocsEditable()
  void deleteRule(int index) native;

  @DomName('CSSStyleSheet.insertRule')
  @DocsEditable()
  int insertRule(String rule, [int index]) native;

  @DomName('CSSStyleSheet.removeRule')
  @DocsEditable()
  @Experimental() // non-standard
  void removeRule(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('CSSSupportsRule')
@Native("CSSSupportsRule")
class CssSupportsRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssSupportsRule._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('CSSSupportsRule.conditionText')
  @DocsEditable()
  final String conditionText;

  @DomName('CSSSupportsRule.cssRules')
  @DocsEditable()
  @Returns('_CssRuleList|Null')
  @Creates('_CssRuleList')
  final List<CssRule> cssRules;

  @DomName('CSSSupportsRule.deleteRule')
  @DocsEditable()
  void deleteRule(int index) native;

  @DomName('CSSSupportsRule.insertRule')
  @DocsEditable()
  int insertRule(String rule, int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('CSSViewportRule')
@Experimental() // untriaged
@Native("CSSViewportRule")
class CssViewportRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssViewportRule._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('CSSViewportRule.style')
  @DocsEditable()
  @Experimental() // untriaged
  final CssStyleDeclaration style;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('CustomEvent')
@Native("CustomEvent")
class CustomEvent extends Event {
  @Creates('Null') // Set from Dart code; does not instantiate a native type.
  var _dartDetail;

  factory CustomEvent(String type,
      {bool canBubble: true, bool cancelable: true, Object detail}) {
    final CustomEvent e = document._createEvent('CustomEvent');

    e._dartDetail = detail;

    // Only try setting the detail if it's one of these types to avoid
    // first-chance exceptions. Can expand this list in the future as needed.
    if (detail is List || detail is Map || detail is String || detail is num) {
      try {
        detail = convertDartToNative_SerializedScriptValue(detail);
        e._initCustomEvent(type, canBubble, cancelable, detail);
      } catch (_) {
        e._initCustomEvent(type, canBubble, cancelable, null);
      }
    } else {
      e._initCustomEvent(type, canBubble, cancelable, null);
    }

    return e;
  }

  @DomName('CustomEvent.detail')
  get detail {
    if (_dartDetail != null) {
      return _dartDetail;
    }
    return _detail;
  }

  @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 type, bool bubbles, bool cancelable, Object detail) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLDListElement')
@Native("HTMLDListElement")
class DListElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory DListElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLDListElement.HTMLDListElement')
  @DocsEditable()
  factory DListElement() => JS(
      'returns:DListElement;creates:DListElement;new:true',
      '#.createElement(#)',
      document,
      "dl");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DListElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLDataListElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
@Native("HTMLDataListElement")
class DataListElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory DataListElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLDataListElement.HTMLDataListElement')
  @DocsEditable()
  factory DataListElement() => document.createElement("datalist");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DataListElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('datalist');

  @DomName('HTMLDataListElement.options')
  @DocsEditable()
  @Returns('HtmlCollection|Null')
  @Creates('HtmlCollection')
  final List<Node> options;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('DataTransfer')
@Experimental() // untriaged
@Native("DataTransfer")
class DataTransfer extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DataTransfer._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('DataTransfer.dropEffect')
  @DocsEditable()
  @Experimental() // untriaged
  String dropEffect;

  @DomName('DataTransfer.effectAllowed')
  @DocsEditable()
  @Experimental() // untriaged
  String effectAllowed;

  @DomName('DataTransfer.files')
  @DocsEditable()
  @Experimental() // untriaged
  @Returns('FileList|Null')
  @Creates('FileList')
  final List<File> files;

  @DomName('DataTransfer.items')
  @DocsEditable()
  @Experimental() // untriaged
  final DataTransferItemList items;

  @DomName('DataTransfer.types')
  @DocsEditable()
  @Experimental() // untriaged
  final List<String> types;

  @DomName('DataTransfer.clearData')
  @DocsEditable()
  @Experimental() // untriaged
  void clearData([String format]) native;

  @DomName('DataTransfer.getData')
  @DocsEditable()
  @Experimental() // untriaged
  String getData(String format) native;

  @DomName('DataTransfer.setData')
  @DocsEditable()
  @Experimental() // untriaged
  void setData(String format, String data) native;

  @DomName('DataTransfer.setDragImage')
  @DocsEditable()
  @Experimental() // untriaged
  void setDragImage(Element image, int x, int y) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('DataTransferItem')
// http://www.w3.org/TR/2011/WD-html5-20110113/dnd.html#the-datatransferitem-interface
@Experimental()
@Native("DataTransferItem")
class DataTransferItem extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DataTransferItem._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('DataTransferItem.kind')
  @DocsEditable()
  final String kind;

  @DomName('DataTransferItem.type')
  @DocsEditable()
  final String type;

  @DomName('DataTransferItem.getAsFile')
  @DocsEditable()
  Blob getAsFile() native;

  @JSName('getAsString')
  @DomName('DataTransferItem.getAsString')
  @DocsEditable()
  void _getAsString(_StringCallback callback) native;

  @JSName('getAsString')
  @DomName('DataTransferItem.getAsString')
  @DocsEditable()
  Future<String> getAsString() {
    var completer = new Completer<String>();
    _getAsString((value) {
      completer.complete(value);
    });
    return completer.future;
  }

  @JSName('webkitGetAsEntry')
  @DomName('DataTransferItem.webkitGetAsEntry')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  Entry getAsEntry() native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('DataTransferItemList')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#the-datatransferitemlist-interface
@Experimental()
@Native("DataTransferItemList")
class DataTransferItemList extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DataTransferItemList._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('DataTransferItemList.length')
  @DocsEditable()
  final int length;

  @DomName('DataTransferItemList.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.item')
  @DocsEditable()
  DataTransferItem item(int index) native;

  @DomName('DataTransferItemList.remove')
  @DocsEditable()
  @Experimental() // untriaged
  void remove(int index) native;

  DataTransferItem operator [](int index) {
    return JS('DataTransferItem', '#[#]', this, index);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('DatabaseCallback')
// http://www.w3.org/TR/webdatabase/#databasecallback
@Experimental() // deprecated
typedef void DatabaseCallback(SqlDatabase database);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('DedicatedWorkerGlobalScope')
@Experimental() // untriaged
@Native("DedicatedWorkerGlobalScope")
class DedicatedWorkerGlobalScope extends WorkerGlobalScope {
  // To suppress missing implicit constructor warnings.
  factory DedicatedWorkerGlobalScope._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [DedicatedWorkerGlobalScope].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('DedicatedWorkerGlobalScope.messageEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  @DomName('DedicatedWorkerGlobalScope.PERSISTENT')
  @DocsEditable()
  @Experimental() // untriaged
  static const int PERSISTENT = 1;

  @DomName('DedicatedWorkerGlobalScope.TEMPORARY')
  @DocsEditable()
  @Experimental() // untriaged
  static const int TEMPORARY = 0;

  @DomName('DedicatedWorkerGlobalScope.postMessage')
  @DocsEditable()
  @Experimental() // untriaged
  void postMessage(/*any*/ message, [List<MessagePort> transfer]) {
    if (transfer != null) {
      var message_1 = convertDartToNative_SerializedScriptValue(message);
      _postMessage_1(message_1, transfer);
      return;
    }
    var message_1 = convertDartToNative_SerializedScriptValue(message);
    _postMessage_2(message_1);
    return;
  }

  @JSName('postMessage')
  @DomName('DedicatedWorkerGlobalScope.postMessage')
  @DocsEditable()
  @Experimental() // untriaged
  void _postMessage_1(message, List<MessagePort> transfer) native;
  @JSName('postMessage')
  @DomName('DedicatedWorkerGlobalScope.postMessage')
  @DocsEditable()
  @Experimental() // untriaged
  void _postMessage_2(message) native;

  @JSName('webkitRequestFileSystem')
  @DomName('DedicatedWorkerGlobalScope.webkitRequestFileSystem')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // untriaged
  void _webkitRequestFileSystem(int type, int size,
      [_FileSystemCallback successCallback,
      _ErrorCallback errorCallback]) native;

  @JSName('webkitRequestFileSystemSync')
  @DomName('DedicatedWorkerGlobalScope.webkitRequestFileSystemSync')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // untriaged
  _DOMFileSystemSync requestFileSystemSync(int type, int size) native;

  @JSName('webkitResolveLocalFileSystemSyncURL')
  @DomName('DedicatedWorkerGlobalScope.webkitResolveLocalFileSystemSyncURL')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // untriaged
  _EntrySync resolveLocalFileSystemSyncUrl(String url) native;

  @JSName('webkitResolveLocalFileSystemURL')
  @DomName('DedicatedWorkerGlobalScope.webkitResolveLocalFileSystemURL')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // untriaged
  void _webkitResolveLocalFileSystemUrl(
      String url, _EntryCallback successCallback,
      [_ErrorCallback errorCallback]) native;

  /// Stream of `message` events handled by this [DedicatedWorkerGlobalScope].
  @DomName('DedicatedWorkerGlobalScope.onmessage')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('DeprecatedStorageInfo')
@Experimental() // untriaged
@Native("DeprecatedStorageInfo")
class DeprecatedStorageInfo extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DeprecatedStorageInfo._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('DeprecatedStorageInfo.PERSISTENT')
  @DocsEditable()
  @Experimental() // untriaged
  static const int PERSISTENT = 1;

  @DomName('DeprecatedStorageInfo.TEMPORARY')
  @DocsEditable()
  @Experimental() // untriaged
  static const int TEMPORARY = 0;

  @DomName('DeprecatedStorageInfo.queryUsageAndQuota')
  @DocsEditable()
  @Experimental() // untriaged
  void queryUsageAndQuota(int storageType,
      [StorageUsageCallback usageCallback,
      StorageErrorCallback errorCallback]) native;

  @DomName('DeprecatedStorageInfo.requestQuota')
  @DocsEditable()
  @Experimental() // untriaged
  void requestQuota(int storageType, int newQuotaInBytes,
      [StorageQuotaCallback quotaCallback,
      StorageErrorCallback errorCallback]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('DeprecatedStorageQuota')
@Experimental() // untriaged
@Native("DeprecatedStorageQuota")
class DeprecatedStorageQuota extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DeprecatedStorageQuota._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('DeprecatedStorageQuota.queryUsageAndQuota')
  @DocsEditable()
  @Experimental() // untriaged
  void queryUsageAndQuota(StorageUsageCallback usageCallback,
      [StorageErrorCallback errorCallback]) native;

  @DomName('DeprecatedStorageQuota.requestQuota')
  @DocsEditable()
  @Experimental() // untriaged
  void requestQuota(int newQuotaInBytes,
      [StorageQuotaCallback quotaCallback,
      StorageErrorCallback errorCallback]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLDetailsElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
@Native("HTMLDetailsElement")
class DetailsElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory DetailsElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLDetailsElement.HTMLDetailsElement')
  @DocsEditable()
  factory DetailsElement() => document.createElement("details");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DetailsElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('details');

  @DomName('HTMLDetailsElement.open')
  @DocsEditable()
  bool open;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('DeviceAcceleration')
// http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
@Experimental()
@Native("DeviceAcceleration")
class DeviceAcceleration extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DeviceAcceleration._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('DeviceAcceleration.x')
  @DocsEditable()
  final double x;

  @DomName('DeviceAcceleration.y')
  @DocsEditable()
  final double y;

  @DomName('DeviceAcceleration.z')
  @DocsEditable()
  final double z;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('DeviceLightEvent')
@Experimental() // untriaged
@Native("DeviceLightEvent")
class DeviceLightEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory DeviceLightEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('DeviceLightEvent.DeviceLightEvent')
  @DocsEditable()
  factory DeviceLightEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return DeviceLightEvent._create_1(type, eventInitDict_1);
    }
    return DeviceLightEvent._create_2(type);
  }
  static DeviceLightEvent _create_1(type, eventInitDict) =>
      JS('DeviceLightEvent', 'new DeviceLightEvent(#,#)', type, eventInitDict);
  static DeviceLightEvent _create_2(type) =>
      JS('DeviceLightEvent', 'new DeviceLightEvent(#)', type);

  @DomName('DeviceLightEvent.value')
  @DocsEditable()
  @Experimental() // untriaged
  final double value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('DeviceMotionEvent')
// http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
@Experimental()
@Native("DeviceMotionEvent")
class DeviceMotionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory DeviceMotionEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('DeviceMotionEvent.acceleration')
  @DocsEditable()
  final DeviceAcceleration acceleration;

  @DomName('DeviceMotionEvent.accelerationIncludingGravity')
  @DocsEditable()
  final DeviceAcceleration accelerationIncludingGravity;

  @DomName('DeviceMotionEvent.interval')
  @DocsEditable()
  final double interval;

  @DomName('DeviceMotionEvent.rotationRate')
  @DocsEditable()
  final DeviceRotationRate rotationRate;

  @DomName('DeviceMotionEvent.initDeviceMotionEvent')
  @DocsEditable()
  @Experimental() // untriaged
  void initDeviceMotionEvent(
      String type,
      bool bubbles,
      bool cancelable,
      DeviceAcceleration acceleration,
      DeviceAcceleration accelerationIncludingGravity,
      DeviceRotationRate rotationRate,
      num interval) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('DeviceOrientationEvent')
// http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
@Experimental()
@Native("DeviceOrientationEvent")
class DeviceOrientationEvent extends Event {
  factory DeviceOrientationEvent(String type,
      {bool canBubble: true,
      bool cancelable: true,
      num alpha: 0,
      num beta: 0,
      num gamma: 0,
      bool absolute: false}) {
    DeviceOrientationEvent e = document._createEvent("DeviceOrientationEvent");
    e._initDeviceOrientationEvent(
        type, canBubble, cancelable, alpha, beta, gamma, absolute);
    return e;
  }
  // To suppress missing implicit constructor warnings.
  factory DeviceOrientationEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('DeviceOrientationEvent.absolute')
  @DocsEditable()
  final bool absolute;

  @DomName('DeviceOrientationEvent.alpha')
  @DocsEditable()
  final double alpha;

  @DomName('DeviceOrientationEvent.beta')
  @DocsEditable()
  final double beta;

  @DomName('DeviceOrientationEvent.gamma')
  @DocsEditable()
  final double gamma;

  @JSName('initDeviceOrientationEvent')
  @DomName('DeviceOrientationEvent.initDeviceOrientationEvent')
  @DocsEditable()
  void _initDeviceOrientationEvent(String type, bool bubbles, bool cancelable,
      num alpha, num beta, num gamma, bool absolute) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('DeviceRotationRate')
// http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
@Experimental()
@Native("DeviceRotationRate")
class DeviceRotationRate extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DeviceRotationRate._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('DeviceRotationRate.alpha')
  @DocsEditable()
  final double alpha;

  @DomName('DeviceRotationRate.beta')
  @DocsEditable()
  final double beta;

  @DomName('DeviceRotationRate.gamma')
  @DocsEditable()
  final double gamma;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLDialogElement')
@Unstable()
@Native("HTMLDialogElement")
class DialogElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory DialogElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DialogElement.created() : super.created();

  @DomName('HTMLDialogElement.open')
  @DocsEditable()
  bool open;

  @DomName('HTMLDialogElement.returnValue')
  @DocsEditable()
  @Experimental() // untriaged
  String returnValue;

  @DomName('HTMLDialogElement.close')
  @DocsEditable()
  void close(String returnValue) native;

  @DomName('HTMLDialogElement.show')
  @DocsEditable()
  void show() native;

  @DomName('HTMLDialogElement.showModal')
  @DocsEditable()
  void showModal() native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DomName('DirectoryEntry')
// http://www.w3.org/TR/file-system-api/#the-directoryentry-interface
@Experimental()
@Native("DirectoryEntry")
class DirectoryEntry extends Entry {
  /**
   * Create a new directory with the specified `path`. If `exclusive` is true,
   * the returned Future will complete with an error if a directory already
   * exists with the specified `path`.
   */
  Future<Entry> createDirectory(String path, {bool exclusive: false}) {
    return _getDirectory(path,
        options: {'create': true, 'exclusive': exclusive});
  }

  /**
   * Retrieve an already existing directory entry. The returned future will
   * result in an error if a directory at `path` does not exist or if the item
   * at `path` is not a directory.
   */
  Future<Entry> getDirectory(String path) {
    return _getDirectory(path);
  }

  /**
   * Create a new file with the specified `path`. If `exclusive` is true,
   * the returned Future will complete with an error if a file already
   * exists at the specified `path`.
   */
  Future<Entry> createFile(String path, {bool exclusive: false}) {
    return _getFile(path, options: {'create': true, 'exclusive': exclusive});
  }

  /**
   * Retrieve an already existing file entry. The returned future will
   * result in an error if a file at `path` does not exist or if the item at
   * `path` is not a file.
   */
  Future<Entry> getFile(String path) {
    return _getFile(path);
  }

  // To suppress missing implicit constructor warnings.
  factory DirectoryEntry._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('DirectoryEntry.createReader')
  @DocsEditable()
  DirectoryReader createReader() native;

  @DomName('DirectoryEntry.getDirectory')
  @DocsEditable()
  void __getDirectory(String path,
      {Map options,
      _EntryCallback successCallback,
      _ErrorCallback errorCallback}) {
    if (errorCallback != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      __getDirectory_1(path, options_1, successCallback, errorCallback);
      return;
    }
    if (successCallback != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      __getDirectory_2(path, options_1, successCallback);
      return;
    }
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      __getDirectory_3(path, options_1);
      return;
    }
    __getDirectory_4(path);
    return;
  }

  @JSName('getDirectory')
  @DomName('DirectoryEntry.getDirectory')
  @DocsEditable()
  void __getDirectory_1(path, options, _EntryCallback successCallback,
      _ErrorCallback errorCallback) native;
  @JSName('getDirectory')
  @DomName('DirectoryEntry.getDirectory')
  @DocsEditable()
  void __getDirectory_2(path, options, _EntryCallback successCallback) native;
  @JSName('getDirectory')
  @DomName('DirectoryEntry.getDirectory')
  @DocsEditable()
  void __getDirectory_3(path, options) native;
  @JSName('getDirectory')
  @DomName('DirectoryEntry.getDirectory')
  @DocsEditable()
  void __getDirectory_4(path) native;

  @JSName('getDirectory')
  @DomName('DirectoryEntry.getDirectory')
  @DocsEditable()
  Future<Entry> _getDirectory(String path, {Map options}) {
    var completer = new Completer<Entry>();
    __getDirectory(path, options: options, successCallback: (value) {
      completer.complete(value);
    }, errorCallback: (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  @DomName('DirectoryEntry.getFile')
  @DocsEditable()
  void __getFile(String path,
      {Map options,
      _EntryCallback successCallback,
      _ErrorCallback errorCallback}) {
    if (errorCallback != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      __getFile_1(path, options_1, successCallback, errorCallback);
      return;
    }
    if (successCallback != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      __getFile_2(path, options_1, successCallback);
      return;
    }
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      __getFile_3(path, options_1);
      return;
    }
    __getFile_4(path);
    return;
  }

  @JSName('getFile')
  @DomName('DirectoryEntry.getFile')
  @DocsEditable()
  void __getFile_1(path, options, _EntryCallback successCallback,
      _ErrorCallback errorCallback) native;
  @JSName('getFile')
  @DomName('DirectoryEntry.getFile')
  @DocsEditable()
  void __getFile_2(path, options, _EntryCallback successCallback) native;
  @JSName('getFile')
  @DomName('DirectoryEntry.getFile')
  @DocsEditable()
  void __getFile_3(path, options) native;
  @JSName('getFile')
  @DomName('DirectoryEntry.getFile')
  @DocsEditable()
  void __getFile_4(path) native;

  @JSName('getFile')
  @DomName('DirectoryEntry.getFile')
  @DocsEditable()
  Future<Entry> _getFile(String path, {Map options}) {
    var completer = new Completer<Entry>();
    __getFile(path, options: options, successCallback: (value) {
      completer.complete(value);
    }, errorCallback: (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  @JSName('removeRecursively')
  @DomName('DirectoryEntry.removeRecursively')
  @DocsEditable()
  void _removeRecursively(VoidCallback successCallback,
      [_ErrorCallback errorCallback]) native;

  @JSName('removeRecursively')
  @DomName('DirectoryEntry.removeRecursively')
  @DocsEditable()
  Future removeRecursively() {
    var completer = new Completer();
    _removeRecursively(() {
      completer.complete();
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('DirectoryReader')
// http://www.w3.org/TR/file-system-api/#the-directoryreader-interface
@Experimental()
@Native("DirectoryReader")
class DirectoryReader extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DirectoryReader._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('readEntries')
  @DomName('DirectoryReader.readEntries')
  @DocsEditable()
  void _readEntries(_EntriesCallback successCallback,
      [_ErrorCallback errorCallback]) native;

  @JSName('readEntries')
  @DomName('DirectoryReader.readEntries')
  @DocsEditable()
  Future<List<Entry>> readEntries() {
    var completer = new Completer<List<Entry>>();
    _readEntries((value) {
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
/**
 * A generic container for content on an HTML page;
 * corresponds to the &lt;div&gt; tag.
 *
 * The [DivElement] is a generic container and does not have any semantic
 * significance. It is functionally similar to [SpanElement].
 *
 * The [DivElement] is a block-level element, as opposed to [SpanElement],
 * which is an inline-level element.
 *
 * Example usage:
 *
 *     DivElement div = new DivElement();
 *     div.text = 'Here's my new DivElem
 *     document.body.elements.add(elem);
 *
 * See also:
 *
 * * [HTML `<div>` element](http://www.w3.org/TR/html-markup/div.html) from W3C.
 * * [Block-level element](http://www.w3.org/TR/CSS2/visuren.html#block-boxes) from W3C.
 * * [Inline-level element](http://www.w3.org/TR/CSS2/visuren.html#inline-boxes) from W3C.
 */
@DomName('HTMLDivElement')
@Native("HTMLDivElement")
class DivElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory DivElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLDivElement.HTMLDivElement')
  @DocsEditable()
  factory DivElement() => JS('returns:DivElement;creates:DivElement;new:true',
      '#.createElement(#)', document, "div");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  DivElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
/**
 * The base class for all documents.
 *
 * Each web page loaded in the browser has its own [Document] object, which is
 * typically an [HtmlDocument].
 *
 * If you aren't comfortable with DOM concepts, see the Dart tutorial
 * [Target 2: Connect Dart & HTML](http://www.dartlang.org/docs/tutorials/connect-dart-html/).
 */
@DomName('Document')
@Native("Document")
class Document extends Node {
  // To suppress missing implicit constructor warnings.
  factory Document._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Document.pointerlockchangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> pointerLockChangeEvent =
      const EventStreamProvider<Event>('pointerlockchange');

  @DomName('Document.pointerlockerrorEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> pointerLockErrorEvent =
      const EventStreamProvider<Event>('pointerlockerror');

  /**
   * Static factory designed to expose `readystatechange` events to event
   * handlers that are not necessarily instances of [Document].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Document.readystatechangeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> readyStateChangeEvent =
      const EventStreamProvider<Event>('readystatechange');

  /**
   * Static factory designed to expose `securitypolicyviolation` events to event
   * handlers that are not necessarily instances of [Document].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Document.securitypolicyviolationEvent')
  @DocsEditable()
  // https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#widl-Document-onsecuritypolicyviolation
  @Experimental()
  static const EventStreamProvider<SecurityPolicyViolationEvent>
      securityPolicyViolationEvent =
      const EventStreamProvider<SecurityPolicyViolationEvent>(
          'securitypolicyviolation');

  /**
   * Static factory designed to expose `selectionchange` events to event
   * handlers that are not necessarily instances of [Document].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Document.selectionchangeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> selectionChangeEvent =
      const EventStreamProvider<Event>('selectionchange');

  @DomName('Document.activeElement')
  @DocsEditable()
  @Experimental() // untriaged
  final Element activeElement;

  @JSName('body')
  @DomName('Document.body')
  @DocsEditable()
  HtmlElement _body;

  @DomName('Document.contentType')
  @DocsEditable()
  @Experimental() // untriaged
  final String contentType;

  @DomName('Document.cookie')
  @DocsEditable()
  String cookie;

  @DomName('Document.currentScript')
  @DocsEditable()
  @Experimental() // untriaged
  final ScriptElement currentScript;

  @DomName('Document.window')
  @DocsEditable()
  @Experimental() // untriaged
  WindowBase get window => _convertNativeToDart_Window(this._get_window);
  @JSName('defaultView')
  @DomName('Document.window')
  @DocsEditable()
  @Experimental() // untriaged
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  @Creates('Window|=Object|Null')
  @Returns('Window|=Object|Null')
  final dynamic _get_window;

  @DomName('Document.documentElement')
  @DocsEditable()
  final Element documentElement;

  @DomName('Document.domain')
  @DocsEditable()
  final String domain;

  @DomName('Document.fonts')
  @DocsEditable()
  @Experimental() // untriaged
  final FontFaceSet fonts;

  @DomName('Document.fullscreenElement')
  @DocsEditable()
  @Experimental() // untriaged
  final Element fullscreenElement;

  @DomName('Document.fullscreenEnabled')
  @DocsEditable()
  @Experimental() // untriaged
  final bool fullscreenEnabled;

  @JSName('head')
  @DomName('Document.head')
  @DocsEditable()
  final HeadElement _head;

  @DomName('Document.hidden')
  @DocsEditable()
  @Experimental() // untriaged
  final bool hidden;

  @DomName('Document.implementation')
  @DocsEditable()
  final DomImplementation implementation;

  @JSName('lastModified')
  @DomName('Document.lastModified')
  @DocsEditable()
  final String _lastModified;

  @DomName('Document.origin')
  @DocsEditable()
  @Experimental() // untriaged
  final String origin;

  @DomName('Document.pointerLockElement')
  @DocsEditable()
  @Experimental() // untriaged
  final Element pointerLockElement;

  @JSName('preferredStylesheetSet')
  @DomName('Document.preferredStylesheetSet')
  @DocsEditable()
  final String _preferredStylesheetSet;

  @DomName('Document.readyState')
  @DocsEditable()
  final String readyState;

  @JSName('referrer')
  @DomName('Document.referrer')
  @DocsEditable()
  final String _referrer;

  @DomName('Document.rootElement')
  @DocsEditable()
  @Experimental() // untriaged
  final SvgSvgElement rootElement;

  @DomName('Document.scrollingElement')
  @DocsEditable()
  @Experimental() // untriaged
  final Element scrollingElement;

  @JSName('selectedStylesheetSet')
  @DomName('Document.selectedStylesheetSet')
  @DocsEditable()
  String _selectedStylesheetSet;

  @JSName('styleSheets')
  @DomName('Document.styleSheets')
  @DocsEditable()
  @Returns('_StyleSheetList|Null')
  @Creates('_StyleSheetList')
  final List<StyleSheet> _styleSheets;

  @DomName('Document.suborigin')
  @DocsEditable()
  @Experimental() // untriaged
  final String suborigin;

  @DomName('Document.timeline')
  @DocsEditable()
  @Experimental() // untriaged
  final AnimationTimeline timeline;

  @JSName('title')
  @DomName('Document.title')
  @DocsEditable()
  String _title;

  @JSName('visibilityState')
  @DomName('Document.visibilityState')
  @DocsEditable()
  @Experimental() // untriaged
  final String _visibilityState;

  @JSName('webkitFullscreenElement')
  @DomName('Document.webkitFullscreenElement')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#dom-document-fullscreenelement
  final Element _webkitFullscreenElement;

  @JSName('webkitFullscreenEnabled')
  @DomName('Document.webkitFullscreenEnabled')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#dom-document-fullscreenenabled
  final bool _webkitFullscreenEnabled;

  @JSName('webkitHidden')
  @DomName('Document.webkitHidden')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/PageVisibility/Overview.html#document
  final bool _webkitHidden;

  @JSName('webkitVisibilityState')
  @DomName('Document.webkitVisibilityState')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/PageVisibility/Overview.html#dom-document-visibilitystate
  final String _webkitVisibilityState;

  @DomName('Document.adoptNode')
  @DocsEditable()
  Node adoptNode(Node node) native;

  @JSName('caretRangeFromPoint')
  @DomName('Document.caretRangeFromPoint')
  @DocsEditable()
  // http://www.w3.org/TR/2009/WD-cssom-view-20090804/#dom-documentview-caretrangefrompoint
  @Experimental()
  Range _caretRangeFromPoint(int x, int y) native;

  @DomName('Document.createDocumentFragment')
  @DocsEditable()
  DocumentFragment createDocumentFragment() native;

  @JSName('createElement')
  @DomName('Document.createElement')
  @DocsEditable()
  Element _createElement(String localName_OR_tagName, [String typeExtension])
      native;

  @JSName('createElementNS')
  @DomName('Document.createElementNS')
  @DocsEditable()
  Element _createElementNS(String namespaceURI, String qualifiedName,
      [String typeExtension]) native;

  @JSName('createEvent')
  @DomName('Document.createEvent')
  @DocsEditable()
  Event _createEvent(String eventType) native;

  @DomName('Document.createRange')
  @DocsEditable()
  Range createRange() native;

  @JSName('createTextNode')
  @DomName('Document.createTextNode')
  @DocsEditable()
  Text _createTextNode(String data) native;

  @DomName('Document.createTouch')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Touch _createTouch(
      Window window,
      EventTarget target,
      int identifier,
      num pageX,
      num pageY,
      num screenX,
      num screenY,
      num radiusX,
      num radiusY,
      num rotationAngle,
      num force) {
    var target_1 = _convertDartToNative_EventTarget(target);
    return _createTouch_1(window, target_1, identifier, pageX, pageY, screenX,
        screenY, radiusX, radiusY, rotationAngle, force);
  }

  @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, radiusX, radiusY, rotationAngle, force) native;

  @JSName('createTouchList')
  @DomName('Document.createTouchList')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  TouchList _createTouchList(Touch touches) native;

  @JSName('elementFromPoint')
  @DomName('Document.elementFromPoint')
  @DocsEditable()
  Element _elementFromPoint(int x, int y) native;

  @DomName('Document.elementsFromPoint')
  @DocsEditable()
  @Experimental() // untriaged
  List<Element> elementsFromPoint(int x, int y) native;

  @DomName('Document.execCommand')
  @DocsEditable()
  bool execCommand(String commandId, [bool showUI, String value]) native;

  @DomName('Document.exitFullscreen')
  @DocsEditable()
  @Experimental() // untriaged
  void exitFullscreen() native;

  @DomName('Document.exitPointerLock')
  @DocsEditable()
  @Experimental() // untriaged
  void exitPointerLock() native;

  @DomName('Document.getElementsByClassName')
  @DocsEditable()
  @Creates('NodeList|HtmlCollection')
  @Returns('NodeList|HtmlCollection')
  List<Node> getElementsByClassName(String classNames) native;

  @DomName('Document.getElementsByName')
  @DocsEditable()
  @Creates('NodeList|HtmlCollection')
  @Returns('NodeList|HtmlCollection')
  List<Node> getElementsByName(String elementName) native;

  @DomName('Document.getElementsByTagName')
  @DocsEditable()
  @Creates('NodeList|HtmlCollection')
  @Returns('NodeList|HtmlCollection')
  List<Node> getElementsByTagName(String localName) native;

  @DomName('Document.importNode')
  @DocsEditable()
  Node importNode(Node node, [bool deep]) native;

  @DomName('Document.queryCommandEnabled')
  @DocsEditable()
  bool queryCommandEnabled(String commandId) native;

  @DomName('Document.queryCommandIndeterm')
  @DocsEditable()
  bool queryCommandIndeterm(String commandId) native;

  @DomName('Document.queryCommandState')
  @DocsEditable()
  bool queryCommandState(String commandId) native;

  @DomName('Document.queryCommandSupported')
  @DocsEditable()
  bool queryCommandSupported(String commandId) native;

  @DomName('Document.queryCommandValue')
  @DocsEditable()
  String queryCommandValue(String commandId) native;

  @DomName('Document.transformDocumentToTreeView')
  @DocsEditable()
  @Experimental() // untriaged
  void transformDocumentToTreeView(String noStyleMessage) native;

  @JSName('webkitExitFullscreen')
  @DomName('Document.webkitExitFullscreen')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#dom-document-exitfullscreen
  void _webkitExitFullscreen() native;

  // From NonElementParentNode

  @DomName('Document.getElementById')
  @DocsEditable()
  Element getElementById(String elementId) native;

  // From ParentNode

  @JSName('childElementCount')
  @DomName('Document.childElementCount')
  @DocsEditable()
  final int _childElementCount;

  @JSName('children')
  @DomName('Document.children')
  @DocsEditable()
  @Returns('HtmlCollection|Null')
  @Creates('HtmlCollection')
  final List<Node> _children;

  @JSName('firstElementChild')
  @DomName('Document.firstElementChild')
  @DocsEditable()
  final Element _firstElementChild;

  @JSName('lastElementChild')
  @DomName('Document.lastElementChild')
  @DocsEditable()
  final Element _lastElementChild;

  /**
   * Finds the first descendant element of this document that matches the
   * specified group of selectors.
   *
   * Unless your webpage contains multiple documents, the top-level
   * [querySelector]
   * method behaves the same as this method, so you should use it instead to
   * save typing a few characters.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var element1 = document.querySelector('.className');
   *     var element2 = document.querySelector('#id');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  @DomName('Document.querySelector')
  @DocsEditable()
  Element querySelector(String selectors) native;

  @JSName('querySelectorAll')
  @DomName('Document.querySelectorAll')
  @DocsEditable()
  @Creates('NodeList')
  @Returns('NodeList')
  List<Node> _querySelectorAll(String selectors) native;

  /// Stream of `abort` events handled by this [Document].
  @DomName('Document.onabort')
  @DocsEditable()
  Stream<Event> get onAbort => Element.abortEvent.forTarget(this);

  /// Stream of `beforecopy` events handled by this [Document].
  @DomName('Document.onbeforecopy')
  @DocsEditable()
  Stream<Event> get onBeforeCopy => Element.beforeCopyEvent.forTarget(this);

  /// Stream of `beforecut` events handled by this [Document].
  @DomName('Document.onbeforecut')
  @DocsEditable()
  Stream<Event> get onBeforeCut => Element.beforeCutEvent.forTarget(this);

  /// Stream of `beforepaste` events handled by this [Document].
  @DomName('Document.onbeforepaste')
  @DocsEditable()
  Stream<Event> get onBeforePaste => Element.beforePasteEvent.forTarget(this);

  /// Stream of `blur` events handled by this [Document].
  @DomName('Document.onblur')
  @DocsEditable()
  Stream<Event> get onBlur => Element.blurEvent.forTarget(this);

  @DomName('Document.oncanplay')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onCanPlay => Element.canPlayEvent.forTarget(this);

  @DomName('Document.oncanplaythrough')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onCanPlayThrough =>
      Element.canPlayThroughEvent.forTarget(this);

  /// Stream of `change` events handled by this [Document].
  @DomName('Document.onchange')
  @DocsEditable()
  Stream<Event> get onChange => Element.changeEvent.forTarget(this);

  /// Stream of `click` events handled by this [Document].
  @DomName('Document.onclick')
  @DocsEditable()
  Stream<MouseEvent> get onClick => Element.clickEvent.forTarget(this);

  /// Stream of `contextmenu` events handled by this [Document].
  @DomName('Document.oncontextmenu')
  @DocsEditable()
  Stream<MouseEvent> get onContextMenu =>
      Element.contextMenuEvent.forTarget(this);

  /// Stream of `copy` events handled by this [Document].
  @DomName('Document.oncopy')
  @DocsEditable()
  Stream<ClipboardEvent> get onCopy => Element.copyEvent.forTarget(this);

  /// Stream of `cut` events handled by this [Document].
  @DomName('Document.oncut')
  @DocsEditable()
  Stream<ClipboardEvent> get onCut => Element.cutEvent.forTarget(this);

  /// Stream of `doubleclick` events handled by this [Document].
  @DomName('Document.ondblclick')
  @DocsEditable()
  Stream<Event> get onDoubleClick => Element.doubleClickEvent.forTarget(this);

  /// Stream of `drag` events handled by this [Document].
  @DomName('Document.ondrag')
  @DocsEditable()
  Stream<MouseEvent> get onDrag => Element.dragEvent.forTarget(this);

  /// Stream of `dragend` events handled by this [Document].
  @DomName('Document.ondragend')
  @DocsEditable()
  Stream<MouseEvent> get onDragEnd => Element.dragEndEvent.forTarget(this);

  /// Stream of `dragenter` events handled by this [Document].
  @DomName('Document.ondragenter')
  @DocsEditable()
  Stream<MouseEvent> get onDragEnter => Element.dragEnterEvent.forTarget(this);

  /// Stream of `dragleave` events handled by this [Document].
  @DomName('Document.ondragleave')
  @DocsEditable()
  Stream<MouseEvent> get onDragLeave => Element.dragLeaveEvent.forTarget(this);

  /// Stream of `dragover` events handled by this [Document].
  @DomName('Document.ondragover')
  @DocsEditable()
  Stream<MouseEvent> get onDragOver => Element.dragOverEvent.forTarget(this);

  /// Stream of `dragstart` events handled by this [Document].
  @DomName('Document.ondragstart')
  @DocsEditable()
  Stream<MouseEvent> get onDragStart => Element.dragStartEvent.forTarget(this);

  /// Stream of `drop` events handled by this [Document].
  @DomName('Document.ondrop')
  @DocsEditable()
  Stream<MouseEvent> get onDrop => Element.dropEvent.forTarget(this);

  @DomName('Document.ondurationchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onDurationChange =>
      Element.durationChangeEvent.forTarget(this);

  @DomName('Document.onemptied')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onEmptied => Element.emptiedEvent.forTarget(this);

  @DomName('Document.onended')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onEnded => Element.endedEvent.forTarget(this);

  /// Stream of `error` events handled by this [Document].
  @DomName('Document.onerror')
  @DocsEditable()
  Stream<Event> get onError => Element.errorEvent.forTarget(this);

  /// Stream of `focus` events handled by this [Document].
  @DomName('Document.onfocus')
  @DocsEditable()
  Stream<Event> get onFocus => Element.focusEvent.forTarget(this);

  /// Stream of `input` events handled by this [Document].
  @DomName('Document.oninput')
  @DocsEditable()
  Stream<Event> get onInput => Element.inputEvent.forTarget(this);

  /// Stream of `invalid` events handled by this [Document].
  @DomName('Document.oninvalid')
  @DocsEditable()
  Stream<Event> get onInvalid => Element.invalidEvent.forTarget(this);

  /// Stream of `keydown` events handled by this [Document].
  @DomName('Document.onkeydown')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyDown => Element.keyDownEvent.forTarget(this);

  /// Stream of `keypress` events handled by this [Document].
  @DomName('Document.onkeypress')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyPress => Element.keyPressEvent.forTarget(this);

  /// Stream of `keyup` events handled by this [Document].
  @DomName('Document.onkeyup')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyUp => Element.keyUpEvent.forTarget(this);

  /// Stream of `load` events handled by this [Document].
  @DomName('Document.onload')
  @DocsEditable()
  Stream<Event> get onLoad => Element.loadEvent.forTarget(this);

  @DomName('Document.onloadeddata')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onLoadedData => Element.loadedDataEvent.forTarget(this);

  @DomName('Document.onloadedmetadata')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onLoadedMetadata =>
      Element.loadedMetadataEvent.forTarget(this);

  /// Stream of `mousedown` events handled by this [Document].
  @DomName('Document.onmousedown')
  @DocsEditable()
  Stream<MouseEvent> get onMouseDown => Element.mouseDownEvent.forTarget(this);

  /// Stream of `mouseenter` events handled by this [Document].
  @DomName('Document.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseEnter =>
      Element.mouseEnterEvent.forTarget(this);

  /// Stream of `mouseleave` events handled by this [Document].
  @DomName('Document.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseLeave =>
      Element.mouseLeaveEvent.forTarget(this);

  /// Stream of `mousemove` events handled by this [Document].
  @DomName('Document.onmousemove')
  @DocsEditable()
  Stream<MouseEvent> get onMouseMove => Element.mouseMoveEvent.forTarget(this);

  /// Stream of `mouseout` events handled by this [Document].
  @DomName('Document.onmouseout')
  @DocsEditable()
  Stream<MouseEvent> get onMouseOut => Element.mouseOutEvent.forTarget(this);

  /// Stream of `mouseover` events handled by this [Document].
  @DomName('Document.onmouseover')
  @DocsEditable()
  Stream<MouseEvent> get onMouseOver => Element.mouseOverEvent.forTarget(this);

  /// Stream of `mouseup` events handled by this [Document].
  @DomName('Document.onmouseup')
  @DocsEditable()
  Stream<MouseEvent> get onMouseUp => Element.mouseUpEvent.forTarget(this);

  /// Stream of `mousewheel` events handled by this [Document].
  @DomName('Document.onmousewheel')
  @DocsEditable()
  Stream<WheelEvent> get onMouseWheel =>
      Element.mouseWheelEvent.forTarget(this);

  /// Stream of `paste` events handled by this [Document].
  @DomName('Document.onpaste')
  @DocsEditable()
  Stream<ClipboardEvent> get onPaste => Element.pasteEvent.forTarget(this);

  @DomName('Document.onpause')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onPause => Element.pauseEvent.forTarget(this);

  @DomName('Document.onplay')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onPlay => Element.playEvent.forTarget(this);

  @DomName('Document.onplaying')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onPlaying => Element.playingEvent.forTarget(this);

  @DomName('Document.onpointerlockchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onPointerLockChange =>
      pointerLockChangeEvent.forTarget(this);

  @DomName('Document.onpointerlockerror')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onPointerLockError => pointerLockErrorEvent.forTarget(this);

  @DomName('Document.onratechange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onRateChange => Element.rateChangeEvent.forTarget(this);

  /// Stream of `readystatechange` events handled by this [Document].
  @DomName('Document.onreadystatechange')
  @DocsEditable()
  Stream<Event> get onReadyStateChange => readyStateChangeEvent.forTarget(this);

  /// Stream of `reset` events handled by this [Document].
  @DomName('Document.onreset')
  @DocsEditable()
  Stream<Event> get onReset => Element.resetEvent.forTarget(this);

  @DomName('Document.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onResize => Element.resizeEvent.forTarget(this);

  /// Stream of `scroll` events handled by this [Document].
  @DomName('Document.onscroll')
  @DocsEditable()
  Stream<Event> get onScroll => Element.scrollEvent.forTarget(this);

  /// Stream of `search` events handled by this [Document].
  @DomName('Document.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  Stream<Event> get onSearch => Element.searchEvent.forTarget(this);

  /// Stream of `securitypolicyviolation` events handled by this [Document].
  @DomName('Document.onsecuritypolicyviolation')
  @DocsEditable()
  // https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#widl-Document-onsecuritypolicyviolation
  @Experimental()
  Stream<SecurityPolicyViolationEvent> get onSecurityPolicyViolation =>
      securityPolicyViolationEvent.forTarget(this);

  @DomName('Document.onseeked')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSeeked => Element.seekedEvent.forTarget(this);

  @DomName('Document.onseeking')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSeeking => Element.seekingEvent.forTarget(this);

  /// Stream of `select` events handled by this [Document].
  @DomName('Document.onselect')
  @DocsEditable()
  Stream<Event> get onSelect => Element.selectEvent.forTarget(this);

  /// Stream of `selectionchange` events handled by this [Document].
  @DomName('Document.onselectionchange')
  @DocsEditable()
  Stream<Event> get onSelectionChange => selectionChangeEvent.forTarget(this);

  /// Stream of `selectstart` events handled by this [Document].
  @DomName('Document.onselectstart')
  @DocsEditable()
  Stream<Event> get onSelectStart => Element.selectStartEvent.forTarget(this);

  @DomName('Document.onstalled')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onStalled => Element.stalledEvent.forTarget(this);

  /// Stream of `submit` events handled by this [Document].
  @DomName('Document.onsubmit')
  @DocsEditable()
  Stream<Event> get onSubmit => Element.submitEvent.forTarget(this);

  @DomName('Document.onsuspend')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSuspend => Element.suspendEvent.forTarget(this);

  @DomName('Document.ontimeupdate')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onTimeUpdate => Element.timeUpdateEvent.forTarget(this);

  /// Stream of `touchcancel` events handled by this [Document].
  @DomName('Document.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchCancel =>
      Element.touchCancelEvent.forTarget(this);

  /// Stream of `touchend` events handled by this [Document].
  @DomName('Document.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchEnd => Element.touchEndEvent.forTarget(this);

  /// Stream of `touchmove` events handled by this [Document].
  @DomName('Document.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchMove => Element.touchMoveEvent.forTarget(this);

  /// Stream of `touchstart` events handled by this [Document].
  @DomName('Document.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchStart =>
      Element.touchStartEvent.forTarget(this);

  @DomName('Document.onvolumechange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onVolumeChange => Element.volumeChangeEvent.forTarget(this);

  @DomName('Document.onwaiting')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onWaiting => Element.waitingEvent.forTarget(this);

  /// Stream of `fullscreenchange` events handled by this [Document].
  @DomName('Document.onwebkitfullscreenchange')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  Stream<Event> get onFullscreenChange =>
      Element.fullscreenChangeEvent.forTarget(this);

  /// Stream of `fullscreenerror` events handled by this [Document].
  @DomName('Document.onwebkitfullscreenerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  Stream<Event> get onFullscreenError =>
      Element.fullscreenErrorEvent.forTarget(this);

  /**
   * Finds all descendant elements of this document that match the specified
   * group of selectors.
   *
   * Unless your webpage contains multiple documents, the top-level
   * [querySelectorAll]
   * method behaves the same as this method, so you should use it instead to
   * save typing a few characters.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var items = document.querySelectorAll('.itemClassName');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  ElementList<Element/*=T*/ > querySelectorAll/*<T extends Element>*/(
          String selectors) =>
      new _FrozenElementList/*<T>*/ ._wrap(_querySelectorAll(selectors));

  /**
   * Alias for [querySelector]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @Experimental()
  @DomName('Document.querySelector')
  Element query(String relativeSelectors) => querySelector(relativeSelectors);

  /**
   * Alias for [querySelectorAll]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @Experimental()
  @DomName('Document.querySelectorAll')
  ElementList<Element/*=T*/ > queryAll/*<T extends Element>*/(
          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 (typeExtension == null)
        ? _createElement_2(tagName)
        : _createElement(tagName, typeExtension);
  }

  // The two-argument version of this is automatically generated, but we need to
  // omit the typeExtension if it's null on Firefox or we get an is="null" attribute.
  @DomName('Document.createElement')
  _createElement_2(String tagName) =>
      JS('Element', '#.createElement(#)', this, tagName);

  // The three-argument version of this is automatically generated, but we need to
  // omit the typeExtension if it's null on Firefox or we get an is="null" attribute.
  @DomName('Document.createElementNS')
  _createElementNS_2(String namespaceURI, String qualifiedName) => JS(
      'Element', '#.createElementNS(#, #)', this, namespaceURI, qualifiedName);

  @DomName('Document.createElementNS')
  @DocsEditable()
  Element createElementNS(String namespaceURI, String qualifiedName,
      [String typeExtension]) {
    return (typeExtension == null)
        ? _createElementNS_2(namespaceURI, qualifiedName)
        : _createElementNS(namespaceURI, qualifiedName, typeExtension);
  }

  @DomName('Document.createNodeIterator')
  NodeIterator _createNodeIterator(Node root,
          [int whatToShow, NodeFilter filter]) =>
      JS('NodeIterator', '#.createNodeIterator(#, #, #, false)', this, root,
          whatToShow, filter);

  @DomName('Document.createTreeWalker')
  TreeWalker _createTreeWalker(Node root,
          [int whatToShow, NodeFilter filter]) =>
      JS('TreeWalker', '#.createTreeWalker(#, #, #, false)', this, root,
          whatToShow, filter);

  @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);
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DomName('DocumentFragment')
@Native("DocumentFragment")
class DocumentFragment extends Node
    implements NonElementParentNode, ParentNode {
  factory DocumentFragment() => document.createDocumentFragment();

  factory DocumentFragment.html(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    return document.body.createFragment(html,
        validator: validator, treeSanitizer: treeSanitizer);
  }

  factory DocumentFragment.svg(String svgContent,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    return new svg.SvgSvgElement().createFragment(svgContent,
        validator: validator, treeSanitizer: treeSanitizer);
  }

  HtmlCollection get _children =>
      throw new UnimplementedError('Use _docChildren instead');

  // Native field is used only by Dart code so does not lead to instantiation
  // of native classes
  @Creates('Null')
  List<Element> _docChildren;

  List<Element> get children {
    if (_docChildren == null) {
      _docChildren = new FilteredElementList(this);
    }
    return _docChildren;
  }

  set children(List<Element> value) {
    // Copy list first since we don't want liveness during iteration.
    var copy = value.toList();
    var children = this.children;
    children.clear();
    children.addAll(copy);
  }

  /**
   * Finds all descendant elements of this document fragment that match the
   * specified group of selectors.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var items = document.querySelectorAll('.itemClassName');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  ElementList<Element/*=T*/ > querySelectorAll/*<T extends Element>*/(
          String selectors) =>
      new _FrozenElementList/*<T>*/ ._wrap(_querySelectorAll(selectors));

  String get innerHtml {
    final e = new DivElement();
    e.append(this.clone(true));
    return e.innerHtml;
  }

  set innerHtml(String value) {
    this.setInnerHtml(value);
  }

  void setInnerHtml(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    this.nodes.clear();
    append(document.body.createFragment(html,
        validator: validator, treeSanitizer: treeSanitizer));
  }

  /**
   * Adds the specified text as a text node after the last child of this
   * document fragment.
   */
  void appendText(String text) {
    this.append(new Text(text));
  }

  /**
   * Parses the specified text as HTML and adds the resulting node after the
   * last child of this document fragment.
   */
  void appendHtml(String text,
      {NodeValidator validator, NodeTreeSanitizer, treeSanitizer}) {
    this.append(new DocumentFragment.html(text,
        validator: validator, treeSanitizer: treeSanitizer));
  }

  /** 
   * Alias for [querySelector]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @Experimental()
  @DomName('DocumentFragment.querySelector')
  Element query(String relativeSelectors) {
    return querySelector(relativeSelectors);
  }

  /** 
   * Alias for [querySelectorAll]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @Experimental()
  @DomName('DocumentFragment.querySelectorAll')
  ElementList<Element/*=T*/ > queryAll/*<T extends Element>*/(
          String relativeSelectors) =>
      querySelectorAll(relativeSelectors);
  // To suppress missing implicit constructor warnings.
  factory DocumentFragment._() {
    throw new UnsupportedError("Not supported");
  }

  // From NonElementParentNode

  @DomName('DocumentFragment.getElementById')
  @DocsEditable()
  @Experimental() // untriaged
  Element getElementById(String elementId) native;

  // From ParentNode

  @JSName('childElementCount')
  @DomName('DocumentFragment.childElementCount')
  @DocsEditable()
  final int _childElementCount;

  @JSName('firstElementChild')
  @DomName('DocumentFragment.firstElementChild')
  @DocsEditable()
  final Element _firstElementChild;

  @JSName('lastElementChild')
  @DomName('DocumentFragment.lastElementChild')
  @DocsEditable()
  final Element _lastElementChild;

  /**
   * Finds the first descendant element of this document fragment that matches
   * the specified group of selectors.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var element1 = fragment.querySelector('.className');
   *     var element2 = fragment.querySelector('#id');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  @DomName('DocumentFragment.querySelector')
  @DocsEditable()
  Element querySelector(String selectors) native;

  @JSName('querySelectorAll')
  @DomName('DocumentFragment.querySelectorAll')
  @DocsEditable()
  @Creates('NodeList')
  @Returns('NodeList')
  List<Node> _querySelectorAll(String selectors) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('DOMError')
@Native("DOMError")
class DomError extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomError._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('DOMError.DOMError')
  @DocsEditable()
  factory DomError(String name, [String message]) {
    if (message != null) {
      return DomError._create_1(name, message);
    }
    return DomError._create_2(name);
  }
  static DomError _create_1(name, message) =>
      JS('DomError', 'new DOMError(#,#)', name, message);
  static DomError _create_2(name) => JS('DomError', 'new DOMError(#)', name);

  @DomName('DOMError.message')
  @DocsEditable()
  @Experimental() // untriaged
  final String message;

  @DomName('DOMError.name')
  @DocsEditable()
  final String name;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DomName('DOMException')
@Unstable()
@Native("DOMException")
class DomException extends Interceptor {
  static const String INDEX_SIZE = 'IndexSizeError';
  static const String HIERARCHY_REQUEST = 'HierarchyRequestError';
  static const String WRONG_DOCUMENT = 'WrongDocumentError';
  static const String INVALID_CHARACTER = 'InvalidCharacterError';
  static const String NO_MODIFICATION_ALLOWED = 'NoModificationAllowedError';
  static const String NOT_FOUND = 'NotFoundError';
  static const String NOT_SUPPORTED = 'NotSupportedError';
  static const String INVALID_STATE = 'InvalidStateError';
  static const String SYNTAX = 'SyntaxError';
  static const String INVALID_MODIFICATION = 'InvalidModificationError';
  static const String NAMESPACE = 'NamespaceError';
  static const String INVALID_ACCESS = 'InvalidAccessError';
  static const String TYPE_MISMATCH = 'TypeMismatchError';
  static const String SECURITY = 'SecurityError';
  static const String NETWORK = 'NetworkError';
  static const String ABORT = 'AbortError';
  static const String URL_MISMATCH = 'URLMismatchError';
  static const String QUOTA_EXCEEDED = 'QuotaExceededError';
  static const String TIMEOUT = 'TimeoutError';
  static const String INVALID_NODE_TYPE = 'InvalidNodeTypeError';
  static const String DATA_CLONE = 'DataCloneError';
  // Is TypeError class derived from DomException but name is 'TypeError'
  static const String TYPE_ERROR = 'TypeError';

  String get name {
    var errorName = JS('String', '#.name', this);
    // Although Safari nightly has updated the name to SecurityError, Safari 5
    // and 6 still return SECURITY_ERR.
    if (Device.isWebKit && errorName == 'SECURITY_ERR') return 'SecurityError';
    // Chrome release still uses old string, remove this line when Chrome stable
    // also prints out SyntaxError.
    if (Device.isWebKit && errorName == 'SYNTAX_ERR') return 'SyntaxError';
    return errorName;
  }

  // To suppress missing implicit constructor warnings.
  factory DomException._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('DOMException.message')
  @DocsEditable()
  final String message;

  @DomName('DOMException.toString')
  @DocsEditable()
  String toString() => JS('String', 'String(#)', this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('DOMImplementation')
@Native("DOMImplementation")
class DomImplementation extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomImplementation._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('DOMImplementation.createDocument')
  @DocsEditable()
  XmlDocument createDocument(
      String namespaceURI, String qualifiedName, _DocumentType doctype) native;

  @DomName('DOMImplementation.createDocumentType')
  @DocsEditable()
  _DocumentType createDocumentType(
      String qualifiedName, String publicId, String systemId) native;

  @JSName('createHTMLDocument')
  @DomName('DOMImplementation.createHTMLDocument')
  @DocsEditable()
  HtmlDocument createHtmlDocument(String title) native;

  @DomName('DOMImplementation.hasFeature')
  @DocsEditable()
  bool hasFeature() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('Iterator')
@Experimental() // untriaged
@Native("Iterator")
class DomIterator extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomIterator._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Iterator.next')
  @DocsEditable()
  @Experimental() // untriaged
  Object next([Object value]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('DOMMatrix')
@Experimental() // untriaged
@Native("DOMMatrix")
class DomMatrix extends DomMatrixReadOnly {
  // To suppress missing implicit constructor warnings.
  factory DomMatrix._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('DOMMatrix.DOMMatrix')
  @DocsEditable()
  factory DomMatrix([DomMatrixReadOnly other]) {
    if (other == null) {
      return DomMatrix._create_1();
    }
    if ((other is DomMatrixReadOnly)) {
      return DomMatrix._create_2(other);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static DomMatrix _create_1() => JS('DomMatrix', 'new DOMMatrix()');
  static DomMatrix _create_2(other) =>
      JS('DomMatrix', 'new DOMMatrix(#)', other);

  // Shadowing definition.
  num get a => JS("num", "#.a", this);

  set a(num value) {
    JS("void", "#.a = #", this, value);
  }

  // Shadowing definition.
  num get b => JS("num", "#.b", this);

  set b(num value) {
    JS("void", "#.b = #", this, value);
  }

  // Shadowing definition.
  num get c => JS("num", "#.c", this);

  set c(num value) {
    JS("void", "#.c = #", this, value);
  }

  // Shadowing definition.
  num get d => JS("num", "#.d", this);

  set d(num value) {
    JS("void", "#.d = #", this, value);
  }

  // Shadowing definition.
  num get e => JS("num", "#.e", this);

  set e(num value) {
    JS("void", "#.e = #", this, value);
  }

  // Shadowing definition.
  num get f => JS("num", "#.f", this);

  set f(num value) {
    JS("void", "#.f = #", this, value);
  }

  // Shadowing definition.
  num get m11 => JS("num", "#.m11", this);

  set m11(num value) {
    JS("void", "#.m11 = #", this, value);
  }

  // Shadowing definition.
  num get m12 => JS("num", "#.m12", this);

  set m12(num value) {
    JS("void", "#.m12 = #", this, value);
  }

  // Shadowing definition.
  num get m13 => JS("num", "#.m13", this);

  set m13(num value) {
    JS("void", "#.m13 = #", this, value);
  }

  // Shadowing definition.
  num get m14 => JS("num", "#.m14", this);

  set m14(num value) {
    JS("void", "#.m14 = #", this, value);
  }

  // Shadowing definition.
  num get m21 => JS("num", "#.m21", this);

  set m21(num value) {
    JS("void", "#.m21 = #", this, value);
  }

  // Shadowing definition.
  num get m22 => JS("num", "#.m22", this);

  set m22(num value) {
    JS("void", "#.m22 = #", this, value);
  }

  // Shadowing definition.
  num get m23 => JS("num", "#.m23", this);

  set m23(num value) {
    JS("void", "#.m23 = #", this, value);
  }

  // Shadowing definition.
  num get m24 => JS("num", "#.m24", this);

  set m24(num value) {
    JS("void", "#.m24 = #", this, value);
  }

  // Shadowing definition.
  num get m31 => JS("num", "#.m31", this);

  set m31(num value) {
    JS("void", "#.m31 = #", this, value);
  }

  // Shadowing definition.
  num get m32 => JS("num", "#.m32", this);

  set m32(num value) {
    JS("void", "#.m32 = #", this, value);
  }

  // Shadowing definition.
  num get m33 => JS("num", "#.m33", this);

  set m33(num value) {
    JS("void", "#.m33 = #", this, value);
  }

  // Shadowing definition.
  num get m34 => JS("num", "#.m34", this);

  set m34(num value) {
    JS("void", "#.m34 = #", this, value);
  }

  // Shadowing definition.
  num get m41 => JS("num", "#.m41", this);

  set m41(num value) {
    JS("void", "#.m41 = #", this, value);
  }

  // Shadowing definition.
  num get m42 => JS("num", "#.m42", this);

  set m42(num value) {
    JS("void", "#.m42 = #", this, value);
  }

  // Shadowing definition.
  num get m43 => JS("num", "#.m43", this);

  set m43(num value) {
    JS("void", "#.m43 = #", this, value);
  }

  // Shadowing definition.
  num get m44 => JS("num", "#.m44", this);

  set m44(num value) {
    JS("void", "#.m44 = #", this, value);
  }

  @DomName('DOMMatrix.multiplySelf')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix multiplySelf(DomMatrix other) native;

  @DomName('DOMMatrix.preMultiplySelf')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix preMultiplySelf(DomMatrix other) native;

  @DomName('DOMMatrix.scale3dSelf')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix scale3dSelf(num scale, [num originX, num originY, num originZ])
      native;

  @DomName('DOMMatrix.scaleNonUniformSelf')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix scaleNonUniformSelf(num scaleX,
      [num scaleY, num scaleZ, num originX, num originY, num originZ]) native;

  @DomName('DOMMatrix.scaleSelf')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix scaleSelf(num scale, [num originX, num originY]) native;

  @DomName('DOMMatrix.translateSelf')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix translateSelf(num tx, num ty, [num tz]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('DOMMatrixReadOnly')
@Experimental() // untriaged
@Native("DOMMatrixReadOnly")
class DomMatrixReadOnly extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomMatrixReadOnly._() {
    throw new UnsupportedError("Not supported");
  }

  num get a => JS("num", "#.a", this);

  num get b => JS("num", "#.b", this);

  num get c => JS("num", "#.c", this);

  num get d => JS("num", "#.d", this);

  num get e => JS("num", "#.e", this);

  num get f => JS("num", "#.f", this);

  bool get is2D => JS("bool", "#.is2D", this);

  bool get isIdentity => JS("bool", "#.isIdentity", this);

  num get m11 => JS("num", "#.m11", this);

  num get m12 => JS("num", "#.m12", this);

  num get m13 => JS("num", "#.m13", this);

  num get m14 => JS("num", "#.m14", this);

  num get m21 => JS("num", "#.m21", this);

  num get m22 => JS("num", "#.m22", this);

  num get m23 => JS("num", "#.m23", this);

  num get m24 => JS("num", "#.m24", this);

  num get m31 => JS("num", "#.m31", this);

  num get m32 => JS("num", "#.m32", this);

  num get m33 => JS("num", "#.m33", this);

  num get m34 => JS("num", "#.m34", this);

  num get m41 => JS("num", "#.m41", this);

  num get m42 => JS("num", "#.m42", this);

  num get m43 => JS("num", "#.m43", this);

  num get m44 => JS("num", "#.m44", this);

  @DomName('DOMMatrixReadOnly.multiply')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix multiply(DomMatrix other) native;

  @DomName('DOMMatrixReadOnly.scale')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix scale(num scale, [num originX, num originY]) native;

  @DomName('DOMMatrixReadOnly.scale3d')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix scale3d(num scale, [num originX, num originY, num originZ]) native;

  @DomName('DOMMatrixReadOnly.scaleNonUniform')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix scaleNonUniform(num scaleX,
      [num scaleY, num scaleZn, num originX, num originY, num originZ]) native;

  @DomName('DOMMatrixReadOnly.toFloat32Array')
  @DocsEditable()
  @Experimental() // untriaged
  Float32List toFloat32Array() native;

  @DomName('DOMMatrixReadOnly.toFloat64Array')
  @DocsEditable()
  @Experimental() // untriaged
  Float64List toFloat64Array() native;

  @DomName('DOMMatrixReadOnly.translate')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix translate(num tx, num ty, [num tz]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('DOMParser')
@Native("DOMParser")
class DomParser extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomParser._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('DOMParser.DOMParser')
  @DocsEditable()
  factory DomParser() {
    return DomParser._create_1();
  }
  static DomParser _create_1() => JS('DomParser', 'new DOMParser()');

  @DomName('DOMParser.parseFromString')
  @DocsEditable()
  Document parseFromString(String str, String type) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('DOMPoint')
@Experimental() // untriaged
@Native("DOMPoint")
class DomPoint extends DomPointReadOnly {
  // To suppress missing implicit constructor warnings.
  factory DomPoint._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('DOMPoint.DOMPoint')
  @DocsEditable()
  factory DomPoint([point_OR_x, num y, num z, num w]) {
    if ((point_OR_x is Map) && y == null && z == null && w == null) {
      var point_1 = convertDartToNative_Dictionary(point_OR_x);
      return DomPoint._create_1(point_1);
    }
    if (point_OR_x == null && y == null && z == null && w == null) {
      return DomPoint._create_2();
    }
    if ((point_OR_x is num || point_OR_x == null) &&
        y == null &&
        z == null &&
        w == null) {
      return DomPoint._create_3(point_OR_x);
    }
    if ((y is num || y == null) &&
        (point_OR_x is num || point_OR_x == null) &&
        z == null &&
        w == null) {
      return DomPoint._create_4(point_OR_x, y);
    }
    if ((z is num || z == null) &&
        (y is num || y == null) &&
        (point_OR_x is num || point_OR_x == null) &&
        w == null) {
      return DomPoint._create_5(point_OR_x, y, z);
    }
    if ((w is num || w == null) &&
        (z is num || z == null) &&
        (y is num || y == null) &&
        (point_OR_x is num || point_OR_x == null)) {
      return DomPoint._create_6(point_OR_x, y, z, w);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static DomPoint _create_1(point_OR_x) =>
      JS('DomPoint', 'new DOMPoint(#)', point_OR_x);
  static DomPoint _create_2() => JS('DomPoint', 'new DOMPoint()');
  static DomPoint _create_3(point_OR_x) =>
      JS('DomPoint', 'new DOMPoint(#)', point_OR_x);
  static DomPoint _create_4(point_OR_x, y) =>
      JS('DomPoint', 'new DOMPoint(#,#)', point_OR_x, y);
  static DomPoint _create_5(point_OR_x, y, z) =>
      JS('DomPoint', 'new DOMPoint(#,#,#)', point_OR_x, y, z);
  static DomPoint _create_6(point_OR_x, y, z, w) =>
      JS('DomPoint', 'new DOMPoint(#,#,#,#)', point_OR_x, y, z, w);

  /// Checks if this type is supported on the current platform.
  static bool get supported =>
      JS('bool', '!!(window.DOMPoint) || !!(window.WebKitPoint)');

  // Shadowing definition.
  num get w => JS("num", "#.w", this);

  set w(num value) {
    JS("void", "#.w = #", this, value);
  }

  // Shadowing definition.
  num get x => JS("num", "#.x", this);

  set x(num value) {
    JS("void", "#.x = #", this, value);
  }

  // Shadowing definition.
  num get y => JS("num", "#.y", this);

  set y(num value) {
    JS("void", "#.y = #", this, value);
  }

  // Shadowing definition.
  num get z => JS("num", "#.z", this);

  set z(num value) {
    JS("void", "#.z = #", this, value);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('DOMPointReadOnly')
@Experimental() // untriaged
@Native("DOMPointReadOnly")
class DomPointReadOnly extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomPointReadOnly._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('DOMPointReadOnly.DOMPointReadOnly')
  @DocsEditable()
  factory DomPointReadOnly(num x, num y, num z, num w) {
    return DomPointReadOnly._create_1(x, y, z, w);
  }
  static DomPointReadOnly _create_1(x, y, z, w) =>
      JS('DomPointReadOnly', 'new DOMPointReadOnly(#,#,#,#)', x, y, z, w);

  num get w => JS("num", "#.w", this);

  num get x => JS("num", "#.x", this);

  num get y => JS("num", "#.y", this);

  num get z => JS("num", "#.z", 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('DOMRectReadOnly')
@Experimental() // untriaged
@Native("DOMRectReadOnly")
class DomRectReadOnly extends Interceptor implements Rectangle {
  // NOTE! All code below should be common with RectangleBase.
  String toString() {
    return 'Rectangle ($left, $top) $width x $height';
  }

  bool operator ==(other) {
    if (other is! Rectangle) return false;
    return left == other.left &&
        top == other.top &&
        width == other.width &&
        height == other.height;
  }

  int get hashCode => _JenkinsSmiHash.hash4(
      left.hashCode, top.hashCode, width.hashCode, height.hashCode);

  /**
   * Computes the intersection of `this` and [other].
   *
   * The intersection of two axis-aligned rectangles, if any, is always another
   * axis-aligned rectangle.
   *
   * Returns the intersection of this and `other`, or null if they don't
   * intersect.
   */
  Rectangle intersection(Rectangle other) {
    var x0 = max(left, other.left);
    var x1 = min(left + width, other.left + other.width);

    if (x0 <= x1) {
      var y0 = max(top, other.top);
      var y1 = min(top + height, other.top + other.height);

      if (y0 <= y1) {
        return new Rectangle(x0, y0, x1 - x0, y1 - y0);
      }
    }
    return null;
  }

  /**
   * Returns true if `this` intersects [other].
   */
  bool intersects(Rectangle<num> other) {
    return (left <= other.left + other.width &&
        other.left <= left + width &&
        top <= other.top + other.height &&
        other.top <= top + height);
  }

  /**
   * Returns a new rectangle which completely contains `this` and [other].
   */
  Rectangle boundingBox(Rectangle other) {
    var right = max(this.left + this.width, other.left + other.width);
    var bottom = max(this.top + this.height, other.top + other.height);

    var left = min(this.left, other.left);
    var top = min(this.top, other.top);

    return new Rectangle(left, top, right - left, bottom - top);
  }

  /**
   * Tests whether `this` entirely contains [another].
   */
  bool containsRectangle(Rectangle<num> another) {
    return left <= another.left &&
        left + width >= another.left + another.width &&
        top <= another.top &&
        top + height >= another.top + another.height;
  }

  /**
   * Tests whether [another] is inside or along the edges of `this`.
   */
  bool containsPoint(Point<num> another) {
    return another.x >= left &&
        another.x <= left + width &&
        another.y >= top &&
        another.y <= top + height;
  }

  Point get topLeft => new Point/*<num>*/(this.left, this.top);
  Point get topRight => new Point/*<num>*/(this.left + this.width, this.top);
  Point get bottomRight =>
      new Point/*<num>*/(this.left + this.width, this.top + this.height);
  Point get bottomLeft => new Point/*<num>*/(this.left, this.top + this.height);

  // To suppress missing implicit constructor warnings.
  factory DomRectReadOnly._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('DOMRectReadOnly.DOMRectReadOnly')
  @DocsEditable()
  factory DomRectReadOnly(num x, num y, num width, num height) {
    return DomRectReadOnly._create_1(x, y, width, height);
  }
  static DomRectReadOnly _create_1(x, y, width, height) => JS(
      'DomRectReadOnly', 'new DOMRectReadOnly(#,#,#,#)', x, y, width, height);

  num get bottom => JS("num", "#.bottom", this);

  num get height => JS("num", "#.height", this);

  num get left => JS("num", "#.left", this);

  num get right => JS("num", "#.right", this);

  num get top => JS("num", "#.top", this);

  num get width => JS("num", "#.width", this);

  num get x => JS("num", "#.x", this);

  num get y => JS("num", "#.y", 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('DOMStringList')
@Native("DOMStringList")
class DomStringList extends Interceptor
    with ListMixin<String>, ImmutableListMixin<String>
    implements JavaScriptIndexingBehavior<String>, List<String> {
  // To suppress missing implicit constructor warnings.
  factory DomStringList._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('DOMStringList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  String operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("String", "#[#]", this, index);
  }

  void operator []=(int index, String value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<String> mixins.
  // String is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  String get first {
    if (this.length > 0) {
      return JS('String', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  String get last {
    int len = this.length;
    if (len > 0) {
      return JS('String', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  String get single {
    int len = this.length;
    if (len == 1) {
      return JS('String', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  String elementAt(int index) => this[index];
  // -- end List<String> mixins.

  @DomName('DOMStringList.__getter__')
  @DocsEditable()
  @Experimental() // untriaged
  String __getter__(int index) 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')
@Native("DOMStringMap")
class DomStringMap extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomStringMap._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('DOMStringMap.__delete__')
  @DocsEditable()
  void __delete__(index_OR_name) native;

  @DomName('DOMStringMap.__getter__')
  @DocsEditable()
  String __getter__(int index) native;

  @DomName('DOMStringMap.__setter__')
  @DocsEditable()
  void __setter__(index_OR_name, String value) native;

  @DomName('DOMStringMap.item')
  @DocsEditable()
  @Experimental() // untriaged
  String item(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('DOMTokenList')
@Native("DOMTokenList")
class DomTokenList extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory DomTokenList._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('DOMTokenList.length')
  @DocsEditable()
  final int length;

  @DomName('DOMTokenList.value')
  @DocsEditable()
  @Experimental() // untriaged
  String value;

  @DomName('DOMTokenList.add')
  @DocsEditable()
  @Experimental() // untriaged
  void add(String tokens) native;

  @DomName('DOMTokenList.contains')
  @DocsEditable()
  bool contains(String token) native;

  @DomName('DOMTokenList.item')
  @DocsEditable()
  String item(int index) native;

  @DomName('DOMTokenList.remove')
  @DocsEditable()
  @Experimental() // untriaged
  void remove(String tokens) native;

  @DomName('DOMTokenList.supports')
  @DocsEditable()
  @Experimental() // untriaged
  bool supports(String token) 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.

@DocsEditable()
@DomName('EffectModel')
@Experimental() // untriaged
@Native("EffectModel")
class EffectModel extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory EffectModel._() {
    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.

class _ChildrenElementList extends ListBase<Element>
    implements NodeListWrapper {
  // Raw Element.
  final Element _element;
  final HtmlCollection _childElements;

  _ChildrenElementList._wrap(Element element)
      : _childElements = element._children,
        _element = element;

  bool contains(Object element) => _childElements.contains(element);

  bool get isEmpty {
    return _element._firstElementChild == null;
  }

  int get length {
    return _childElements.length;
  }

  Element operator [](int index) {
    return _childElements[index];
  }

  void operator []=(int index, Element value) {
    _element._replaceChild(value, _childElements[index]);
  }

  set length(int newLength) {
    // TODO(jacobr): remove children when length is reduced.
    throw new UnsupportedError('Cannot resize element lists');
  }

  Element add(Element value) {
    _element.append(value);
    return value;
  }

  Iterator<Element> get iterator => toList().iterator;

  void addAll(Iterable<Element> iterable) {
    if (iterable is _ChildNodeListLazy) {
      iterable = new List.from(iterable);
    }

    for (Element element in iterable) {
      _element.append(element);
    }
  }

  void sort([int compare(Element a, Element b)]) {
    throw new UnsupportedError('Cannot sort element lists');
  }

  void shuffle([Random random]) {
    throw new UnsupportedError('Cannot shuffle element lists');
  }

  void removeWhere(bool test(Element element)) {
    _filter(test, false);
  }

  void retainWhere(bool test(Element element)) {
    _filter(test, true);
  }

  void _filter(bool test(Element 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 fillRange(int start, int end, [Element fillValue]) {
    throw new UnimplementedError();
  }

  void replaceRange(int start, int end, Iterable<Element> iterable) {
    throw new UnimplementedError();
  }

  void removeRange(int start, int end) {
    throw new UnimplementedError();
  }

  void setRange(int start, int end, Iterable<Element> iterable,
      [int skipCount = 0]) {
    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
   * dimensions 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 dimensions 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 dimensions 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 dimensions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's `outerHeight` value for an element.
   */
  @Experimental()
  CssRect get marginEdge;

  /// Stream of `abort` events handled by this [Element].
  @DomName('Element.onabort')
  @DocsEditable()
  ElementStream<Event> get onAbort;

  /// Stream of `beforecopy` events handled by this [Element].
  @DomName('Element.onbeforecopy')
  @DocsEditable()
  ElementStream<Event> get onBeforeCopy;

  /// Stream of `beforecut` events handled by this [Element].
  @DomName('Element.onbeforecut')
  @DocsEditable()
  ElementStream<Event> get onBeforeCut;

  /// Stream of `beforepaste` events handled by this [Element].
  @DomName('Element.onbeforepaste')
  @DocsEditable()
  ElementStream<Event> get onBeforePaste;

  /// Stream of `blur` events handled by this [Element].
  @DomName('Element.onblur')
  @DocsEditable()
  ElementStream<Event> get onBlur;

  @DomName('Element.oncanplay')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onCanPlay;

  @DomName('Element.oncanplaythrough')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onCanPlayThrough;

  /// Stream of `change` events handled by this [Element].
  @DomName('Element.onchange')
  @DocsEditable()
  ElementStream<Event> get onChange;

  /// Stream of `click` events handled by this [Element].
  @DomName('Element.onclick')
  @DocsEditable()
  ElementStream<MouseEvent> get onClick;

  /// Stream of `contextmenu` events handled by this [Element].
  @DomName('Element.oncontextmenu')
  @DocsEditable()
  ElementStream<MouseEvent> get onContextMenu;

  /// Stream of `copy` events handled by this [Element].
  @DomName('Element.oncopy')
  @DocsEditable()
  ElementStream<ClipboardEvent> get onCopy;

  /// Stream of `cut` events handled by this [Element].
  @DomName('Element.oncut')
  @DocsEditable()
  ElementStream<ClipboardEvent> 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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.ondrop')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrop;

  @DomName('Element.ondurationchange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onDurationChange;

  @DomName('Element.onemptied')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEmptied;

  @DomName('Element.onended')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEnded;

  /// Stream of `error` events handled by this [Element].
  @DomName('Element.onerror')
  @DocsEditable()
  ElementStream<Event> get onError;

  /// Stream of `focus` events handled by this [Element].
  @DomName('Element.onfocus')
  @DocsEditable()
  ElementStream<Event> get onFocus;

  /// Stream of `input` events handled by this [Element].
  @DomName('Element.oninput')
  @DocsEditable()
  ElementStream<Event> get onInput;

  /// Stream of `invalid` events handled by this [Element].
  @DomName('Element.oninvalid')
  @DocsEditable()
  ElementStream<Event> get onInvalid;

  /// Stream of `keydown` events handled by this [Element].
  @DomName('Element.onkeydown')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyDown;

  /// Stream of `keypress` events handled by this [Element].
  @DomName('Element.onkeypress')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyPress;

  /// Stream of `keyup` events handled by this [Element].
  @DomName('Element.onkeyup')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyUp;

  /// Stream of `load` events handled by this [Element].
  @DomName('Element.onload')
  @DocsEditable()
  ElementStream<Event> get onLoad;

  @DomName('Element.onloadeddata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedData;

  @DomName('Element.onloadedmetadata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedMetadata;

  /// Stream of `mousedown` events handled by this [Element].
  @DomName('Element.onmousedown')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseDown;

  /// Stream of `mouseenter` events handled by this [Element].
  @DomName('Element.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseEnter;

  /// Stream of `mouseleave` events handled by this [Element].
  @DomName('Element.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseLeave;

  /// Stream of `mousemove` events handled by this [Element].
  @DomName('Element.onmousemove')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseMove;

  /// Stream of `mouseout` events handled by this [Element].
  @DomName('Element.onmouseout')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOut;

  /// Stream of `mouseover` events handled by this [Element].
  @DomName('Element.onmouseover')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOver;

  /// Stream of `mouseup` events handled by this [Element].
  @DomName('Element.onmouseup')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseUp;

  /// Stream of `mousewheel` events handled by this [Element].
  @DomName('Element.onmousewheel')
  @DocsEditable()
  // http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents
  @Experimental() // non-standard
  ElementStream<WheelEvent> get onMouseWheel;

  /// Stream of `paste` events handled by this [Element].
  @DomName('Element.onpaste')
  @DocsEditable()
  ElementStream<ClipboardEvent> get onPaste;

  @DomName('Element.onpause')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPause;

  @DomName('Element.onplay')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPlay;

  @DomName('Element.onplaying')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPlaying;

  @DomName('Element.onratechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onRateChange;

  /// Stream of `reset` events handled by this [Element].
  @DomName('Element.onreset')
  @DocsEditable()
  ElementStream<Event> get onReset;

  @DomName('Element.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onResize;

  /// Stream of `scroll` events handled by this [Element].
  @DomName('Element.onscroll')
  @DocsEditable()
  ElementStream<Event> get onScroll;

  /// Stream of `search` events handled by this [Element].
  @DomName('Element.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  ElementStream<Event> get onSearch;

  @DomName('Element.onseeked')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeked;

  @DomName('Element.onseeking')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeking;

  /// Stream of `select` events handled by this [Element].
  @DomName('Element.onselect')
  @DocsEditable()
  ElementStream<Event> get onSelect;

  /// Stream of `selectstart` events handled by this [Element].
  @DomName('Element.onselectstart')
  @DocsEditable()
  @Experimental() // nonstandard
  ElementStream<Event> get onSelectStart;

  @DomName('Element.onstalled')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onStalled;

  /// Stream of `submit` events handled by this [Element].
  @DomName('Element.onsubmit')
  @DocsEditable()
  ElementStream<Event> get onSubmit;

  @DomName('Element.onsuspend')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSuspend;

  @DomName('Element.ontimeupdate')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onTimeUpdate;

  /// Stream of `touchcancel` events handled by this [Element].
  @DomName('Element.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchCancel;

  /// Stream of `touchend` events handled by this [Element].
  @DomName('Element.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnd;

  /// Stream of `touchenter` events handled by this [Element].
  @DomName('Element.ontouchenter')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnter;

  /// Stream of `touchleave` events handled by this [Element].
  @DomName('Element.ontouchleave')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchLeave;

  /// Stream of `touchmove` events handled by this [Element].
  @DomName('Element.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchMove;

  /// Stream of `touchstart` events handled by this [Element].
  @DomName('Element.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchStart;

  /// Stream of `transitionend` events handled by this [Element].
  @DomName('Element.ontransitionend')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  ElementStream<TransitionEvent> get onTransitionEnd;

  @DomName('Element.onvolumechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onVolumeChange;

  @DomName('Element.onwaiting')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onWaiting;

  /// Stream of `fullscreenchange` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenchange')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenChange;

  /// Stream of `fullscreenerror` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenError;
}

// Wrapper over an immutable NodeList to make it implement ElementList.
//
// Clients are {`Document`, `DocumentFragment`}.`querySelectorAll` which are
// declared to return `ElementList`.  This provides all the static analysis
// benefit so there is no need for this class have a constrained type parameter.
//
class _FrozenElementList<E extends Element> extends ListBase<E>
    implements ElementList<E>, NodeListWrapper {
  final List<Node> _nodeList;

  _FrozenElementList._wrap(this._nodeList);

  int get length => _nodeList.length;

  E operator [](int index) => _downcast/*<Node, E>*/(_nodeList[index]);

  void operator []=(int index, E value) {
    throw new UnsupportedError('Cannot modify list');
  }

  set length(int newLength) {
    throw new UnsupportedError('Cannot modify list');
  }

  void sort([Comparator<E> compare]) {
    throw new UnsupportedError('Cannot sort list');
  }

  void shuffle([Random random]) {
    throw new UnsupportedError('Cannot shuffle list');
  }

  E get first => _downcast/*<Node, E>*/(_nodeList.first);

  E get last => _downcast/*<Node, E>*/(_nodeList.last);

  E get single => _downcast/*<Node, E>*/(_nodeList.single);

  CssClassSet get classes => new _MultiElementCssClassSet(this);

  CssStyleDeclarationBase get style => new _CssStyleDeclarationSet(this);

  set classes(Iterable<String> value) {
    // TODO(sra): This might be faster for Sets:
    //
    //     new _MultiElementCssClassSet(this).writeClasses(value)
    //
    // as the code below converts the Iterable[value] to a string multiple
    // times.  Maybe compute the string and set className here.
    forEach((e) => e.classes = value);
  }

  CssRect get contentEdge => new _ContentCssListRect(this);

  CssRect get paddingEdge => this.first.paddingEdge;

  CssRect get borderEdge => this.first.borderEdge;

  CssRect get marginEdge => this.first.marginEdge;

  List<Node> get rawList => _nodeList;

  /// Stream of `abort` events handled by this [Element].
  @DomName('Element.onabort')
  @DocsEditable()
  ElementStream<Event> get onAbort => Element.abortEvent._forElementList(this);

  /// Stream of `beforecopy` events handled by this [Element].
  @DomName('Element.onbeforecopy')
  @DocsEditable()
  ElementStream<Event> get onBeforeCopy =>
      Element.beforeCopyEvent._forElementList(this);

  /// Stream of `beforecut` events handled by this [Element].
  @DomName('Element.onbeforecut')
  @DocsEditable()
  ElementStream<Event> get onBeforeCut =>
      Element.beforeCutEvent._forElementList(this);

  /// Stream of `beforepaste` events handled by this [Element].
  @DomName('Element.onbeforepaste')
  @DocsEditable()
  ElementStream<Event> get onBeforePaste =>
      Element.beforePasteEvent._forElementList(this);

  /// Stream of `blur` events handled by this [Element].
  @DomName('Element.onblur')
  @DocsEditable()
  ElementStream<Event> get onBlur => Element.blurEvent._forElementList(this);

  @DomName('Element.oncanplay')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onCanPlay =>
      Element.canPlayEvent._forElementList(this);

  @DomName('Element.oncanplaythrough')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onCanPlayThrough =>
      Element.canPlayThroughEvent._forElementList(this);

  /// Stream of `change` events handled by this [Element].
  @DomName('Element.onchange')
  @DocsEditable()
  ElementStream<Event> get onChange =>
      Element.changeEvent._forElementList(this);

  /// Stream of `click` events handled by this [Element].
  @DomName('Element.onclick')
  @DocsEditable()
  ElementStream<MouseEvent> get onClick =>
      Element.clickEvent._forElementList(this);

  /// Stream of `contextmenu` events handled by this [Element].
  @DomName('Element.oncontextmenu')
  @DocsEditable()
  ElementStream<MouseEvent> get onContextMenu =>
      Element.contextMenuEvent._forElementList(this);

  /// Stream of `copy` events handled by this [Element].
  @DomName('Element.oncopy')
  @DocsEditable()
  ElementStream<ClipboardEvent> get onCopy =>
      Element.copyEvent._forElementList(this);

  /// Stream of `cut` events handled by this [Element].
  @DomName('Element.oncut')
  @DocsEditable()
  ElementStream<ClipboardEvent> 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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.ondrop')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrop =>
      Element.dropEvent._forElementList(this);

  @DomName('Element.ondurationchange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onDurationChange =>
      Element.durationChangeEvent._forElementList(this);

  @DomName('Element.onemptied')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEmptied =>
      Element.emptiedEvent._forElementList(this);

  @DomName('Element.onended')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEnded => Element.endedEvent._forElementList(this);

  /// Stream of `error` events handled by this [Element].
  @DomName('Element.onerror')
  @DocsEditable()
  ElementStream<Event> get onError => Element.errorEvent._forElementList(this);

  /// Stream of `focus` events handled by this [Element].
  @DomName('Element.onfocus')
  @DocsEditable()
  ElementStream<Event> get onFocus => Element.focusEvent._forElementList(this);

  /// Stream of `input` events handled by this [Element].
  @DomName('Element.oninput')
  @DocsEditable()
  ElementStream<Event> get onInput => Element.inputEvent._forElementList(this);

  /// Stream of `invalid` events handled by this [Element].
  @DomName('Element.oninvalid')
  @DocsEditable()
  ElementStream<Event> get onInvalid =>
      Element.invalidEvent._forElementList(this);

  /// Stream of `keydown` events handled by this [Element].
  @DomName('Element.onkeydown')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyDown =>
      Element.keyDownEvent._forElementList(this);

  /// Stream of `keypress` events handled by this [Element].
  @DomName('Element.onkeypress')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyPress =>
      Element.keyPressEvent._forElementList(this);

  /// Stream of `keyup` events handled by this [Element].
  @DomName('Element.onkeyup')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyUp =>
      Element.keyUpEvent._forElementList(this);

  /// Stream of `load` events handled by this [Element].
  @DomName('Element.onload')
  @DocsEditable()
  ElementStream<Event> get onLoad => Element.loadEvent._forElementList(this);

  @DomName('Element.onloadeddata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedData =>
      Element.loadedDataEvent._forElementList(this);

  @DomName('Element.onloadedmetadata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedMetadata =>
      Element.loadedMetadataEvent._forElementList(this);

  /// Stream of `mousedown` events handled by this [Element].
  @DomName('Element.onmousedown')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseDown =>
      Element.mouseDownEvent._forElementList(this);

  /// Stream of `mouseenter` events handled by this [Element].
  @DomName('Element.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseEnter =>
      Element.mouseEnterEvent._forElementList(this);

  /// Stream of `mouseleave` events handled by this [Element].
  @DomName('Element.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseLeave =>
      Element.mouseLeaveEvent._forElementList(this);

  /// Stream of `mousemove` events handled by this [Element].
  @DomName('Element.onmousemove')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseMove =>
      Element.mouseMoveEvent._forElementList(this);

  /// Stream of `mouseout` events handled by this [Element].
  @DomName('Element.onmouseout')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOut =>
      Element.mouseOutEvent._forElementList(this);

  /// Stream of `mouseover` events handled by this [Element].
  @DomName('Element.onmouseover')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOver =>
      Element.mouseOverEvent._forElementList(this);

  /// Stream of `mouseup` events handled by this [Element].
  @DomName('Element.onmouseup')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseUp =>
      Element.mouseUpEvent._forElementList(this);

  /// Stream of `mousewheel` events handled by this [Element].
  @DomName('Element.onmousewheel')
  @DocsEditable()
  // http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents
  @Experimental() // non-standard
  ElementStream<WheelEvent> get onMouseWheel =>
      Element.mouseWheelEvent._forElementList(this);

  /// Stream of `paste` events handled by this [Element].
  @DomName('Element.onpaste')
  @DocsEditable()
  ElementStream<ClipboardEvent> get onPaste =>
      Element.pasteEvent._forElementList(this);

  @DomName('Element.onpause')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPause => Element.pauseEvent._forElementList(this);

  @DomName('Element.onplay')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPlay => Element.playEvent._forElementList(this);

  @DomName('Element.onplaying')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPlaying =>
      Element.playingEvent._forElementList(this);

  @DomName('Element.onratechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onRateChange =>
      Element.rateChangeEvent._forElementList(this);

  /// Stream of `reset` events handled by this [Element].
  @DomName('Element.onreset')
  @DocsEditable()
  ElementStream<Event> get onReset => Element.resetEvent._forElementList(this);

  @DomName('Element.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onResize =>
      Element.resizeEvent._forElementList(this);

  /// Stream of `scroll` events handled by this [Element].
  @DomName('Element.onscroll')
  @DocsEditable()
  ElementStream<Event> get onScroll =>
      Element.scrollEvent._forElementList(this);

  /// Stream of `search` events handled by this [Element].
  @DomName('Element.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  ElementStream<Event> get onSearch =>
      Element.searchEvent._forElementList(this);

  @DomName('Element.onseeked')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeked =>
      Element.seekedEvent._forElementList(this);

  @DomName('Element.onseeking')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeking =>
      Element.seekingEvent._forElementList(this);

  /// Stream of `select` events handled by this [Element].
  @DomName('Element.onselect')
  @DocsEditable()
  ElementStream<Event> get onSelect =>
      Element.selectEvent._forElementList(this);

  /// Stream of `selectstart` events handled by this [Element].
  @DomName('Element.onselectstart')
  @DocsEditable()
  @Experimental() // nonstandard
  ElementStream<Event> get onSelectStart =>
      Element.selectStartEvent._forElementList(this);

  @DomName('Element.onstalled')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onStalled =>
      Element.stalledEvent._forElementList(this);

  /// Stream of `submit` events handled by this [Element].
  @DomName('Element.onsubmit')
  @DocsEditable()
  ElementStream<Event> get onSubmit =>
      Element.submitEvent._forElementList(this);

  @DomName('Element.onsuspend')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSuspend =>
      Element.suspendEvent._forElementList(this);

  @DomName('Element.ontimeupdate')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onTimeUpdate =>
      Element.timeUpdateEvent._forElementList(this);

  /// Stream of `touchcancel` events handled by this [Element].
  @DomName('Element.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchCancel =>
      Element.touchCancelEvent._forElementList(this);

  /// Stream of `touchend` events handled by this [Element].
  @DomName('Element.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnd =>
      Element.touchEndEvent._forElementList(this);

  /// Stream of `touchenter` events handled by this [Element].
  @DomName('Element.ontouchenter')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnter =>
      Element.touchEnterEvent._forElementList(this);

  /// Stream of `touchleave` events handled by this [Element].
  @DomName('Element.ontouchleave')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchLeave =>
      Element.touchLeaveEvent._forElementList(this);

  /// Stream of `touchmove` events handled by this [Element].
  @DomName('Element.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchMove =>
      Element.touchMoveEvent._forElementList(this);

  /// Stream of `touchstart` events handled by this [Element].
  @DomName('Element.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchStart =>
      Element.touchStartEvent._forElementList(this);

  /// Stream of `transitionend` events handled by this [Element].
  @DomName('Element.ontransitionend')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  ElementStream<TransitionEvent> get onTransitionEnd =>
      Element.transitionEndEvent._forElementList(this);

  @DomName('Element.onvolumechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onVolumeChange =>
      Element.volumeChangeEvent._forElementList(this);

  @DomName('Element.onwaiting')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onWaiting =>
      Element.waitingEvent._forElementList(this);

  /// Stream of `fullscreenchange` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenchange')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenChange =>
      Element.fullscreenChangeEvent._forElementList(this);

  /// Stream of `fullscreenerror` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenError =>
      Element.fullscreenErrorEvent._forElementList(this);
}

@DocsEditable()
/**
 * An abstract class, which all HTML elements extend.
 */
@DomName('Element')
@Native("Element")
class Element extends Node
    implements
        NonDocumentTypeChildNode,
        GlobalEventHandlers,
        ParentNode,
        ChildNode {
  /**
   * Creates an HTML element from a valid fragment of HTML.
   *
   *     var element = new Element.html('<div class="foo">content</div>');
   *
   * The HTML fragment should contain only one single root element, any
   * leading or trailing text nodes will be removed.
   *
   * The HTML fragment is parsed as if it occurred within the context of a
   * `<body>` tag, this means that special elements such as `<caption>` which
   * must be parsed within the scope of a `<table>` element will be dropped. Use
   * [createFragment] to parse contextual HTML fragments.
   *
   * Unless a validator is provided this will perform the default validation
   * and remove all scriptable elements and attributes.
   *
   * See also:
   *
   * * [NodeValidator]
   *
   */
  factory Element.html(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    var fragment = document.body.createFragment(html,
        validator: validator, treeSanitizer: treeSanitizer);

    return fragment.nodes.where((e) => e is Element).single;
  }

  /**
   * Custom element creation constructor.
   *
   * This constructor is used by the DOM when a custom element has been
   * created. It can only be invoked by subclasses of Element from
   * that classes created constructor.
   *
   *     class CustomElement extends Element {
   *       factory CustomElement() => new Element.tag('x-custom');
   *
   *       CustomElement.created() : super.created() {
   *          // Perform any element initialization.
   *       }
   *     }
   *     document.registerElement('x-custom', CustomElement);
   */
  Element.created() : super._created();

  /**
   * Creates the HTML element specified by the tag name.
   *
   * This is similar to [Document.createElement].
   * [tag] should be a valid HTML tag name. If [tag] is an unknown tag then
   * this will create an [UnknownElement].
   *
   *     var divElement = new Element.tag('div');
   *     print(divElement is DivElement); // 'true'
   *     var myElement = new Element.tag('unknownTag');
   *     print(myElement is UnknownElement); // 'true'
   *
   * For standard elements it is better to use the element type constructors:
   *
   *     var element = new DivElement();
   *
   * It is better to use e.g `new CanvasElement()` because the type of the
   * expression is `CanvasElement`, whereas the type of `Element.tag` is the
   * less specific `Element`.
   *
   * See also:
   *
   * * [isTagSupported]
   */
  factory Element.tag(String tag, [String typeExtention]) =>
      _ElementFactoryProvider.createElement_tag(tag, typeExtention);

  /// Creates a new `<a>` element.
  ///
  /// This is equivalent to calling `new Element.tag('a')`.
  factory Element.a() => new AnchorElement();

  /// Creates a new `<article>` element.
  ///
  /// This is equivalent to calling `new Element.tag('article')`.
  factory Element.article() => new Element.tag('article');

  /// Creates a new `<aside>` element.
  ///
  /// This is equivalent to calling `new Element.tag('aside')`.
  factory Element.aside() => new Element.tag('aside');

  /// Creates a new `<audio>` element.
  ///
  /// This is equivalent to calling `new Element.tag('audio')`.
  factory Element.audio() => new Element.tag('audio');

  /// Creates a new `<br>` element.
  ///
  /// This is equivalent to calling `new Element.tag('br')`.
  factory Element.br() => new BRElement();

  /// Creates a new `<canvas>` element.
  ///
  /// This is equivalent to calling `new Element.tag('canvas')`.
  factory Element.canvas() => new CanvasElement();

  /// Creates a new `<div>` element.
  ///
  /// This is equivalent to calling `new Element.tag('div')`.
  factory Element.div() => new DivElement();

  /// Creates a new `<footer>` element.
  ///
  /// This is equivalent to calling `new Element.tag('footer')`.
  factory Element.footer() => new Element.tag('footer');

  /// Creates a new `<header>` element.
  ///
  /// This is equivalent to calling `new Element.tag('header')`.
  factory Element.header() => new Element.tag('header');

  /// Creates a new `<hr>` element.
  ///
  /// This is equivalent to calling `new Element.tag('hr')`.
  factory Element.hr() => new Element.tag('hr');

  /// Creates a new `<iframe>` element.
  ///
  /// This is equivalent to calling `new Element.tag('iframe')`.
  factory Element.iframe() => new Element.tag('iframe');

  /// Creates a new `<img>` element.
  ///
  /// This is equivalent to calling `new Element.tag('img')`.
  factory Element.img() => new Element.tag('img');

  /// Creates a new `<li>` element.
  ///
  /// This is equivalent to calling `new Element.tag('li')`.
  factory Element.li() => new Element.tag('li');

  /// Creates a new `<nav>` element.
  ///
  /// This is equivalent to calling `new Element.tag('nav')`.
  factory Element.nav() => new Element.tag('nav');

  /// Creates a new `<ol>` element.
  ///
  /// This is equivalent to calling `new Element.tag('ol')`.
  factory Element.ol() => new Element.tag('ol');

  /// Creates a new `<option>` element.
  ///
  /// This is equivalent to calling `new Element.tag('option')`.
  factory Element.option() => new Element.tag('option');

  /// Creates a new `<p>` element.
  ///
  /// This is equivalent to calling `new Element.tag('p')`.
  factory Element.p() => new Element.tag('p');

  /// Creates a new `<pre>` element.
  ///
  /// This is equivalent to calling `new Element.tag('pre')`.
  factory Element.pre() => new Element.tag('pre');

  /// Creates a new `<section>` element.
  ///
  /// This is equivalent to calling `new Element.tag('section')`.
  factory Element.section() => new Element.tag('section');

  /// Creates a new `<select>` element.
  ///
  /// This is equivalent to calling `new Element.tag('select')`.
  factory Element.select() => new Element.tag('select');

  /// Creates a new `<span>` element.
  ///
  /// This is equivalent to calling `new Element.tag('span')`.
  factory Element.span() => new Element.tag('span');

  /// Creates a new `<svg>` element.
  ///
  /// This is equivalent to calling `new Element.tag('svg')`.
  factory Element.svg() => new Element.tag('svg');

  /// Creates a new `<table>` element.
  ///
  /// This is equivalent to calling `new Element.tag('table')`.
  factory Element.table() => new Element.tag('table');

  /// Creates a new `<td>` element.
  ///
  /// This is equivalent to calling `new Element.tag('td')`.
  factory Element.td() => new Element.tag('td');

  /// Creates a new `<textarea>` element.
  ///
  /// This is equivalent to calling `new Element.tag('textarea')`.
  factory Element.textarea() => new Element.tag('textarea');

  /// Creates a new `<th>` element.
  ///
  /// This is equivalent to calling `new Element.tag('th')`.
  factory Element.th() => new Element.tag('th');

  /// Creates a new `<tr>` element.
  ///
  /// This is equivalent to calling `new Element.tag('tr')`.
  factory Element.tr() => new Element.tag('tr');

  /// Creates a new `<ul>` element.
  ///
  /// This is equivalent to calling `new Element.tag('ul')`.
  factory Element.ul() => new Element.tag('ul');

  /// Creates a new `<video>` element.
  ///
  /// This is equivalent to calling `new Element.tag('video')`.
  factory Element.video() => new Element.tag('video');

  /**
   * All attributes on this element.
   *
   * Any modifications to the attribute map will automatically be applied to
   * this element.
   *
   * This only includes attributes which are not in a namespace
   * (such as 'xlink:href'), additional attributes can be accessed via
   * [getNamespacedAttributes].
   */
  Map<String, String> get attributes => new _ElementAttributeMap(this);

  set attributes(Map<String, String> value) {
    Map<String, String> attributes = this.attributes;
    attributes.clear();
    for (String key in value.keys) {
      attributes[key] = value[key];
    }
  }

  /**
   * List of the direct children of this element.
   *
   * This collection can be used to add and remove elements from the document.
   *
   *     var item = new DivElement();
   *     item.text = 'Something';
   *     document.body.children.add(item) // Item is now displayed on the page.
   *     for (var element in document.body.children) {
   *       element.style.background = 'red'; // Turns every child of body red.
   *     }
   */
  List<Element> get children => new _ChildrenElementList._wrap(this);

  set children(List<Element> value) {
    // Copy list first since we don't want liveness during iteration.
    var copy = value.toList();
    var children = this.children;
    children.clear();
    children.addAll(copy);
  }

  /**
   * Finds all descendent elements of this element that match the specified
   * group of selectors.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var items = element.querySelectorAll('.itemClassName');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  @DomName('Element.querySelectorAll')
  ElementList<Element/*=T*/ > querySelectorAll/*<T extends Element>*/(
          String selectors) =>
      new _FrozenElementList/*<T>*/ ._wrap(_querySelectorAll(selectors));

  /**
   * Alias for [querySelector]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @DomName('Element.querySelector')
  @Experimental()
  Element query(String relativeSelectors) => querySelector(relativeSelectors);

  /**
   * Alias for [querySelectorAll]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @DomName('Element.querySelectorAll')
  @Experimental()
  ElementList<Element/*=T*/ > queryAll/*<T extends Element>*/(
          String relativeSelectors) =>
      querySelectorAll(relativeSelectors);

  /**
   * The set of CSS classes applied to this element.
   *
   * This set makes it easy to add, remove or toggle the classes applied to
   * this element.
   *
   *     element.classes.add('selected');
   *     element.classes.toggle('isOnline');
   *     element.classes.remove('selected');
   */
  CssClassSet get classes => new _ElementCssClassSet(this);

  set classes(Iterable<String> value) {
    // TODO(sra): Do this without reading the classes in clear() and addAll(),
    // or writing the classes in clear().
    CssClassSet classSet = classes;
    classSet.clear();
    classSet.addAll(value);
  }

  /**
   * Allows access to all custom data attributes (data-*) set on this element.
   *
   * The keys for the map must follow these rules:
   *
   * * The name must not begin with 'xml'.
   * * The name cannot contain a semi-colon (';').
   * * The name cannot contain any capital letters.
   *
   * Any keys from markup will be converted to camel-cased keys in the map.
   *
   * For example, HTML specified as:
   *
   *     <div data-my-random-value='value'></div>
   *
   * Would be accessed in Dart as:
   *
   *     var value = element.dataset['myRandomValue'];
   *
   * See also:
   *
   * * [Custom data
   *   attributes](http://dev.w3.org/html5/spec-preview/global-attributes.html#custom-data-attribute)
   */
  Map<String, String> get dataset => new _DataAttributeMap(attributes);

  set dataset(Map<String, String> value) {
    final data = this.dataset;
    data.clear();
    for (String key in value.keys) {
      data[key] = value[key];
    }
  }

  /**
   * Gets a map for manipulating the attributes of a particular namespace.
   *
   * This is primarily useful for SVG attributes such as xref:link.
   */
  Map<String, String> getNamespacedAttributes(String namespace) {
    return new _NamespacedAttributeMap(this, namespace);
  }

  /**
   * The set of all CSS values applied to this element, including inherited
   * and default values.
   *
   * The computedStyle contains values that are inherited from other
   * sources, such as parent elements or stylesheets. This differs from the
   * [style] property, which contains only the values specified directly on this
   * element.
   *
   * PseudoElement can be values such as `::after`, `::before`, `::marker`,
   * `::line-marker`.
   *
   * See also:
   *
   * * [CSS Inheritance and Cascade](http://docs.webplatform.org/wiki/tutorials/inheritance_and_cascade)
   * * [Pseudo-elements](http://docs.webplatform.org/wiki/css/selectors/pseudo-elements)
   */
  CssStyleDeclaration getComputedStyle([String pseudoElement]) {
    if (pseudoElement == null) {
      pseudoElement = '';
    }
    // TODO(jacobr): last param should be null, see b/5045788
    return window._getComputedStyle(this, pseudoElement);
  }

  /**
   * Gets the position of this element relative to the client area of the page.
   */
  Rectangle get client =>
      new Rectangle(clientLeft, clientTop, clientWidth, clientHeight);

  /**
   * Gets the offset of this element relative to its offsetParent.
   */
  Rectangle get offset =>
      new Rectangle(offsetLeft, offsetTop, offsetWidth, offsetHeight);

  /**
   * Adds the specified text after the last child of this element.
   */
  void appendText(String text) {
    this.append(new Text(text));
  }

  /**
   * Parses the specified text as HTML and adds the resulting node after the
   * last child of this element.
   */
  void appendHtml(String text,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    this.insertAdjacentHtml('beforeend', text,
        validator: validator, treeSanitizer: treeSanitizer);
  }

  /**
   * Checks to see if the tag name is supported by the current platform.
   *
   * The tag should be a valid HTML tag name.
   */
  static bool isTagSupported(String tag) {
    var e = _ElementFactoryProvider.createElement_tag(tag, null);
    return e is Element && !(e is UnknownElement);
  }

  /**
   * Called by the DOM when this element has been inserted into the live
   * document.
   *
   * More information can be found in the
   * [Custom Elements](http://w3c.github.io/webcomponents/spec/custom/#dfn-attached-callback)
   * draft specification.
   */
  @Experimental()
  void attached() {
    // For the deprecation period, call the old callback.
    enteredView();
  }

  /**
   * Called by the DOM when this element has been removed from the live
   * document.
   *
   * More information can be found in the
   * [Custom Elements](http://w3c.github.io/webcomponents/spec/custom/#dfn-detached-callback)
   * draft specification.
   */
  @Experimental()
  void detached() {
    // For the deprecation period, call the old callback.
    leftView();
  }

  /** *Deprecated*: override [attached] instead. */
  @Experimental()
  @deprecated
  void enteredView() {}

  /** *Deprecated*: override [detached] instead. */
  @Experimental()
  @deprecated
  void leftView() {}

  /**
   * Creates a new AnimationEffect object whose target element is the object
   * on which the method is called, and calls the play() method of the
   * AnimationTimeline object of the document timeline of the node document
   * of the element, passing the newly created AnimationEffect as the argument
   * to the method. Returns an Animation for the effect.
   *
   * Examples
   *
   *     var animation = elem.animate([{"opacity": 75}, {"opacity": 0}], 200);
   *
   *     var animation = elem.animate([
   *       {"transform": "translate(100px, -100%)"},
   *       {"transform" : "translate(400px, 500px)"}
   *     ], 1500);
   *
   * The [frames] parameter is an Iterable<Map>, where the
   * map entries specify CSS animation effects. The
   * [timing] paramter can be a double, representing the number of milliseconds
   * for the transition, or a Map with fields corresponding to those
   * of the [Timing] object.
  **/
  @Experimental()
  @SupportedBrowser(SupportedBrowser.CHROME, '36')
  Animation animate(Iterable<Map<String, dynamic>> frames, [timing]) {
    if (frames is! Iterable || !(frames.every((x) => x is Map))) {
      throw new ArgumentError("The frames parameter should be a List of Maps "
          "with frame information");
    }
    var convertedFrames;
    if (frames is Iterable) {
      convertedFrames = frames.map(convertDartToNative_Dictionary).toList();
    } else {
      convertedFrames = frames;
    }
    var convertedTiming =
        timing is Map ? convertDartToNative_Dictionary(timing) : timing;
    return convertedTiming == null
        ? _animate(convertedFrames)
        : _animate(convertedFrames, convertedTiming);
  }

  @DomName('Element.animate')
  @JSName('animate')
  @Experimental() // untriaged
  Animation _animate(Object effect, [timing]) native;
  /**
   * Called by the DOM whenever an attribute on this has been changed.
   */
  void attributeChanged(String name, String oldValue, String newValue) {}

  // Hooks to support custom WebComponents.

  @Creates('Null') // Set from Dart code; does not instantiate a native type.
  Element _xtag;

  /**
   * Experimental support for [web components][wc]. This field stores a
   * reference to the component implementation. It was inspired by Mozilla's
   * [x-tags][] project. Please note: in the future it may be possible to
   * `extend Element` from your class, in which case this field will be
   * deprecated.
   *
   * If xtag has not been set, it will simply return `this` [Element].
   *
   * [wc]: http://dvcs.w3.org/hg/webcomponents/raw-file/tip/explainer/index.html
   * [x-tags]: http://x-tags.org/
   */
  // Note: return type is `dynamic` for convenience to suppress warnings when
  // members of the component are used. The actual type is a subtype of Element.
  get xtag => _xtag != null ? _xtag : this;

  set xtag(Element value) {
    _xtag = value;
  }

  @DomName('Element.localName')
  @DocsEditable()
  @Returns('String')
  // Non-null for Elements.
  String get localName => JS('String', '#', _localName);

  /**
   * A URI that identifies the XML namespace of this element.
   *
   * `null` if no namespace URI is specified.
   *
   * ## Other resources
   *
   * * [Node.namespaceURI](http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-NodeNSname)
   *   from W3C.
   */
  @DomName('Element.namespaceUri')
  String get namespaceUri => _namespaceUri;

  /**
   * The string representation of this element.
   *
   * This is equivalent to reading the [localName] property.
   */
  String toString() => localName;

  /**
   * Scrolls this element into view.
   *
   * Only one of of the alignment options may be specified at a time.
   *
   * If no options are specified then this will attempt to scroll the minimum
   * amount needed to bring the element into view.
   *
   * Note that alignCenter is currently only supported on WebKit platforms. If
   * alignCenter is specified but not supported then this will fall back to
   * alignTop.
   *
   * See also:
   *
   * * [scrollIntoView](http://docs.webplatform.org/wiki/dom/methods/scrollIntoView)
   * * [scrollIntoViewIfNeeded](http://docs.webplatform.org/wiki/dom/methods/scrollIntoViewIfNeeded)
   */
  void scrollIntoView([ScrollAlignment alignment]) {
    var hasScrollIntoViewIfNeeded = true;
    hasScrollIntoViewIfNeeded =
        JS('bool', '!!(#.scrollIntoViewIfNeeded)', this);
    if (alignment == ScrollAlignment.TOP) {
      this._scrollIntoView(true);
    } else if (alignment == ScrollAlignment.BOTTOM) {
      this._scrollIntoView(false);
    } else if (hasScrollIntoViewIfNeeded) {
      if (alignment == ScrollAlignment.CENTER) {
        this._scrollIntoViewIfNeeded(true);
      } else {
        this._scrollIntoViewIfNeeded();
      }
    } else {
      this._scrollIntoView();
    }
  }

  /**
   * Static factory designed to expose `mousewheel` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mouseWheelEvent')
  static const EventStreamProvider<WheelEvent> mouseWheelEvent =
      const _CustomEventStreamProvider<WheelEvent>(
          Element._determineMouseWheelEventType);

  static String _determineMouseWheelEventType(EventTarget e) => 'wheel';

  /**
   * Static factory designed to expose `transitionend` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.transitionEndEvent')
  static const EventStreamProvider<TransitionEvent> transitionEndEvent =
      const _CustomEventStreamProvider<TransitionEvent>(
          Element._determineTransitionEventType);

  static String _determineTransitionEventType(EventTarget e) {
    // Unfortunately the normal 'ontransitionend' style checks don't work here.
    if (Device.isWebKit) {
      return 'webkitTransitionEnd';
    } else if (Device.isOpera) {
      return 'oTransitionEnd';
    }
    return 'transitionend';
  }

  /**
   * Inserts text into the DOM at the specified location.
   *
   * To see the possible values for [where], read the doc for
   * [insertAdjacentHtml].
   *
   * See also:
   *
   * * [insertAdjacentHtml]
   */
  void insertAdjacentText(String where, String text) {
    if (JS('bool', '!!#.insertAdjacentText', this)) {
      _insertAdjacentText(where, text);
    } else {
      _insertAdjacentNode(where, new Text(text));
    }
  }

  @JSName('insertAdjacentText')
  void _insertAdjacentText(String where, String text) native;

  /**
   * Parses text as an HTML fragment and inserts it into the DOM at the
   * specified location.
   *
   * The [where] parameter indicates where to insert the HTML fragment:
   *
   * * 'beforeBegin': Immediately before this element.
   * * 'afterBegin': As the first child of this element.
   * * 'beforeEnd': As the last child of this element.
   * * 'afterEnd': Immediately after this element.
   *
   *     var html = '<div class="something">content</div>';
   *     // Inserts as the first child
   *     document.body.insertAdjacentHtml('afterBegin', html);
   *     var createdElement = document.body.children[0];
   *     print(createdElement.classes[0]); // Prints 'something'
   *
   * See also:
   *
   * * [insertAdjacentText]
   * * [insertAdjacentElement]
   */
  void insertAdjacentHtml(String where, String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    if (treeSanitizer is _TrustedHtmlTreeSanitizer) {
      _insertAdjacentHtml(where, html);
    } else {
      _insertAdjacentNode(
          where,
          createFragment(html,
              validator: validator, treeSanitizer: treeSanitizer));
    }
  }

  @JSName('insertAdjacentHTML')
  void _insertAdjacentHtml(String where, String text) native;

  /**
   * Inserts [element] into the DOM at the specified location.
   *
   * To see the possible values for [where], read the doc for
   * [insertAdjacentHtml].
   *
   * See also:
   *
   * * [insertAdjacentHtml]
   */
  Element insertAdjacentElement(String where, Element element) {
    if (JS('bool', '!!#.insertAdjacentElement', this)) {
      _insertAdjacentElement(where, element);
    } else {
      _insertAdjacentNode(where, element);
    }
    return element;
  }

  @JSName('insertAdjacentElement')
  void _insertAdjacentElement(String where, Element element) native;

  void _insertAdjacentNode(String where, Node node) {
    switch (where.toLowerCase()) {
      case 'beforebegin':
        this.parentNode.insertBefore(node, this);
        break;
      case 'afterbegin':
        var first = this.nodes.length > 0 ? this.nodes[0] : null;
        this.insertBefore(node, first);
        break;
      case 'beforeend':
        this.append(node);
        break;
      case 'afterend':
        this.parentNode.insertBefore(node, this.nextNode);
        break;
      default:
        throw new ArgumentError("Invalid position ${where}");
    }
  }

  /**
   * Checks if this element matches the CSS selectors.
   */
  @Experimental()
  bool matches(String selectors) {
    if (JS('bool', '!!#.matches', this)) {
      return JS('bool', '#.matches(#)', this, selectors);
    } else if (JS('bool', '!!#.webkitMatchesSelector', this)) {
      return JS('bool', '#.webkitMatchesSelector(#)', this, selectors);
    } else if (JS('bool', '!!#.mozMatchesSelector', this)) {
      return JS('bool', '#.mozMatchesSelector(#)', this, selectors);
    } else if (JS('bool', '!!#.msMatchesSelector', this)) {
      return JS('bool', '#.msMatchesSelector(#)', this, selectors);
    } else if (JS('bool', '!!#.oMatchesSelector', this)) {
      return JS('bool', '#.oMatchesSelector(#)', this, selectors);
    } else {
      throw new UnsupportedError("Not supported on this platform");
    }
  }

  /** Checks if this element or any of its parents match the CSS selectors. */
  @Experimental()
  bool matchesWithAncestors(String selectors) {
    var elem = this;
    do {
      if (elem.matches(selectors)) return true;
      elem = elem.parent;
    } while (elem != null);
    return false;
  }

  /**
   * Creates a new shadow root for this shadow host.
   *
   * ## Other resources
   *
   * * [Shadow DOM 101](http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
   *   from HTML5Rocks.
   * * [Shadow DOM specification](http://www.w3.org/TR/shadow-dom/) from W3C.
   */
  @DomName('Element.createShadowRoot')
  @SupportedBrowser(SupportedBrowser.CHROME, '25')
  @Experimental()
  ShadowRoot createShadowRoot() {
    return JS(
        'ShadowRoot',
        '(#.createShadowRoot || #.webkitCreateShadowRoot).call(#)',
        this,
        this,
        this);
  }

  /**
   * The shadow root of this shadow host.
   *
   * ## Other resources
   *
   * * [Shadow DOM 101](http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/)
   *   from HTML5Rocks.
   * * [Shadow DOM specification](http://www.w3.org/TR/shadow-dom/)
   *   from W3C.
   */
  @DomName('Element.shadowRoot')
  @SupportedBrowser(SupportedBrowser.CHROME, '25')
  @Experimental()
  ShadowRoot get shadowRoot =>
      JS('ShadowRoot|Null', '#.shadowRoot || #.webkitShadowRoot', this, this);

  /**
   * Access this element's content position.
   *
   * This returns a rectangle with the dimensions 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 dimensions 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 dimensions 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 dimensions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's
   * [outerHeight](http://api.jquery.com/outerHeight/) value for an element.
   *
   * _Important_ _note_: use of this method will perform CSS calculations that
   * can trigger a browser reflow. Therefore, use of this property _during_ an
   * animation frame is discouraged. See also:
   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
   */
  @Experimental()
  CssRect get marginEdge => new _MarginCssRect(this);

  /**
   * Provides the coordinates of the element relative to the top of the
   * document.
   *
   * This method is the Dart equivalent to jQuery's
   * [offset](http://api.jquery.com/offset/) method.
   */
  @Experimental()
  Point get documentOffset => offsetTo(document.documentElement);

  /**
   * Provides the offset of this element's [borderEdge] relative to the
   * specified [parent].
   *
   * This is the Dart equivalent of jQuery's
   * [position](http://api.jquery.com/position/) method. Unlike jQuery's
   * position, however, [parent] can be any parent element of `this`,
   * rather than only `this`'s immediate [offsetParent]. If the specified
   * element is _not_ an offset parent or transitive offset parent to this
   * element, an [ArgumentError] is thrown.
   */
  @Experimental()
  Point offsetTo(Element parent) {
    return Element._offsetToHelper(this, parent);
  }

  static Point _offsetToHelper(Element current, Element parent) {
    // We're hopping from _offsetParent_ to offsetParent (not just parent), so
    // offsetParent, "tops out" at BODY. But people could conceivably pass in
    // the document.documentElement and I want it to return an absolute offset,
    // so we have the special case checking for HTML.
    bool sameAsParent = identical(current, parent);
    bool foundAsParent = sameAsParent || parent.tagName == 'HTML';
    if (current == null || sameAsParent) {
      if (foundAsParent) return new Point/*<num>*/(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/*<num>*/(
        p.x + current.offsetLeft, p.y + current.offsetTop);
  }

  static HtmlDocument _parseDocument;
  static Range _parseRange;
  static NodeValidatorBuilder _defaultValidator;
  static _ValidatingTreeSanitizer _defaultSanitizer;

  /**
   * Create a DocumentFragment from the HTML fragment and ensure that it follows
   * the sanitization rules specified by the validator or treeSanitizer.
   *
   * If the default validation behavior is too restrictive then a new
   * NodeValidator should be created, either extending or wrapping a default
   * validator and overriding the validation APIs.
   *
   * The treeSanitizer is used to walk the generated node tree and sanitize it.
   * A custom treeSanitizer can also be provided to perform special validation
   * rules but since the API is more complex to implement this is discouraged.
   *
   * The returned tree is guaranteed to only contain nodes and attributes which
   * are allowed by the provided validator.
   *
   * See also:
   *
   * * [NodeValidator]
   * * [NodeTreeSanitizer]
   */
  DocumentFragment createFragment(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    if (treeSanitizer == null) {
      if (validator == null) {
        if (_defaultValidator == null) {
          _defaultValidator = new NodeValidatorBuilder.common();
        }
        validator = _defaultValidator;
      }
      if (_defaultSanitizer == null) {
        _defaultSanitizer = new _ValidatingTreeSanitizer(validator);
      } else {
        _defaultSanitizer.validator = validator;
      }
      treeSanitizer = _defaultSanitizer;
    } else if (validator != null) {
      throw new ArgumentError(
          'validator can only be passed if treeSanitizer is null');
    }

    if (_parseDocument == null) {
      _parseDocument = document.implementation.createHtmlDocument('');
      _parseRange = _parseDocument.createRange();

      // Workaround for Safari bug. Was also previously Chrome bug 229142
      // - URIs are not resolved in new doc.
      BaseElement base = _parseDocument.createElement('base');
      base.href = document.baseUri;
      _parseDocument.head.append(base);
    }

    // TODO(terry): Fixes Chromium 50 change no body after createHtmlDocument()
    if (_parseDocument.body == null) {
      _parseDocument.body = _parseDocument.createElement("body");
    }

    var contextElement;
    if (this is BodyElement) {
      contextElement = _parseDocument.body;
    } else {
      contextElement = _parseDocument.createElement(tagName);
      _parseDocument.body.append(contextElement);
    }
    var fragment;
    if (Range.supportsCreateContextualFragment &&
        _canBeUsedToCreateContextualFragment) {
      _parseRange.selectNodeContents(contextElement);
      fragment = _parseRange.createContextualFragment(html);
    } else {
      contextElement._innerHtml = html;

      fragment = _parseDocument.createDocumentFragment();
      while (contextElement.firstChild != null) {
        fragment.append(contextElement.firstChild);
      }
    }
    if (contextElement != _parseDocument.body) {
      contextElement.remove();
    }

    treeSanitizer.sanitizeTree(fragment);
    // Copy the fragment over to the main document (fix for 14184)
    document.adoptNode(fragment);

    return fragment;
  }

  /** Test if createContextualFragment is supported for this element type */
  bool get _canBeUsedToCreateContextualFragment =>
      !_cannotBeUsedToCreateContextualFragment;

  /** Test if createContextualFragment is NOT supported for this element type */
  bool get _cannotBeUsedToCreateContextualFragment =>
      _tagsForWhichCreateContextualFragmentIsNotSupported.contains(tagName);

  /**
   * A hard-coded list of the tag names for which createContextualFragment
   * isn't supported.
   */
  static const _tagsForWhichCreateContextualFragmentIsNotSupported = const [
    'HEAD',
    'AREA',
    'BASE',
    'BASEFONT',
    'BR',
    'COL',
    'COLGROUP',
    'EMBED',
    'FRAME',
    'FRAMESET',
    'HR',
    'IMAGE',
    'IMG',
    'INPUT',
    'ISINDEX',
    'LINK',
    'META',
    'PARAM',
    'SOURCE',
    'STYLE',
    'TITLE',
    'WBR'
  ];

  /**
   * Parses the HTML fragment and sets it as the contents of this element.
   *
   * This uses the default sanitization behavior to sanitize the HTML fragment,
   * use [setInnerHtml] to override the default behavior.
   */
  set innerHtml(String html) {
    this.setInnerHtml(html);
  }

  /**
   * Parses the HTML fragment and sets it as the contents of this element.
   * This ensures that the generated content follows the sanitization rules
   * specified by the validator or treeSanitizer.
   *
   * If the default validation behavior is too restrictive then a new
   * NodeValidator should be created, either extending or wrapping a default
   * validator and overriding the validation APIs.
   *
   * The treeSanitizer is used to walk the generated node tree and sanitize it.
   * A custom treeSanitizer can also be provided to perform special validation
   * rules but since the API is more complex to implement this is discouraged.
   *
   * The resulting tree is guaranteed to only contain nodes and attributes which
   * are allowed by the provided validator.
   *
   * See also:
   *
   * * [NodeValidator]
   * * [NodeTreeSanitizer]
   */
  void setInnerHtml(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    text = null;
    if (treeSanitizer is _TrustedHtmlTreeSanitizer) {
      _innerHtml = html;
    } else {
      append(createFragment(html,
          validator: validator, treeSanitizer: treeSanitizer));
    }
  }

  String get innerHtml => _innerHtml;

  /**
   * This is an ease-of-use accessor for event streams which should only be
   * used when an explicit accessor is not available.
   */
  ElementEvents get on => new ElementEvents(this);

  /**
   * Verify if any of the attributes that we use in the sanitizer look unexpected,
   * possibly indicating DOM clobbering attacks.
   *
   * Those attributes are: attributes, lastChild, children, previousNode and tagName.
   */
  static bool _hasCorruptedAttributes(Element element) {
    return JS(
        'bool',
        r'''
       (function(element) {
         if (!(element.attributes instanceof NamedNodeMap)) {
	   return true;
	 }
	 var childNodes = element.childNodes;
	 if (element.lastChild &&
	     element.lastChild !== childNodes[childNodes.length -1]) {
	   return true;
	 }
	 if (element.children) { // On Safari, children can apparently be null.
  	   if (!((element.children instanceof HTMLCollection) ||
               (element.children instanceof NodeList))) {
	     return true;
	   }
	 }
         var length = 0;
         if (element.children) {
           length = element.children.length;
         }
         for (var i = 0; i < length; i++) {
           var child = element.children[i];
           // On IE it seems like we sometimes don't see the clobbered attribute,
           // perhaps as a result of an over-optimization. Also use another route
           // to check of attributes, children, or lastChild are clobbered. It may
           // seem silly to check children as we rely on children to do this iteration,
           // but it seems possible that the access to children might see the real thing,
           // allowing us to check for clobbering that may show up in other accesses.
           if (child["id"] == 'attributes' || child["name"] == 'attributes' ||
               child["id"] == 'lastChild'  || child["name"] == 'lastChild' ||
               child["id"] == 'children' || child["name"] == 'children') {
             return true;
           }
         }
	 return false;
          })(#)''',
        element);
  }

  /// A secondary check for corruption, needed on IE
  static bool _hasCorruptedAttributesAdditionalCheck(Element element) {
    return JS('bool', r'!(#.attributes instanceof NamedNodeMap)', element);
  }

  static String _safeTagName(element) {
    String result = 'element tag unavailable';
    try {
      if (element.tagName is String) {
        result = element.tagName;
      }
    } catch (e) {}
    return result;
  }

  @DomName('Element.offsetParent')
  @DocsEditable()
  final Element offsetParent;

  @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.scrollHeight')
  @DocsEditable()
  int get scrollHeight => JS('num', '#.scrollHeight', this).round();

  @DomName('Element.scrollLeft')
  @DocsEditable()
  int get scrollLeft => JS('num', '#.scrollLeft', this).round();

  @DomName('Element.scrollLeft')
  @DocsEditable()
  set scrollLeft(int value) {
    JS("void", "#.scrollLeft = #", this, value.round());
  }

  @DomName('Element.scrollTop')
  @DocsEditable()
  int get scrollTop => JS('num', '#.scrollTop', this).round();

  @DomName('Element.scrollTop')
  @DocsEditable()
  set scrollTop(int value) {
    JS("void", "#.scrollTop = #", this, value.round());
  }

  @DomName('Element.scrollWidth')
  @DocsEditable()
  int get scrollWidth => JS('num', '#.scrollWidth', this).round();

  // To suppress missing implicit constructor warnings.
  factory Element._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `abort` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.abortEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> abortEvent =
      const EventStreamProvider<Event>('abort');

  /**
   * Static factory designed to expose `beforecopy` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.beforecopyEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> beforeCopyEvent =
      const EventStreamProvider<Event>('beforecopy');

  /**
   * Static factory designed to expose `beforecut` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.beforecutEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> beforeCutEvent =
      const EventStreamProvider<Event>('beforecut');

  /**
   * Static factory designed to expose `beforepaste` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.beforepasteEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> beforePasteEvent =
      const EventStreamProvider<Event>('beforepaste');

  /**
   * Static factory designed to expose `blur` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.blurEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> blurEvent =
      const EventStreamProvider<Event>('blur');

  @DomName('Element.canplayEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> canPlayEvent =
      const EventStreamProvider<Event>('canplay');

  @DomName('Element.canplaythroughEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> canPlayThroughEvent =
      const EventStreamProvider<Event>('canplaythrough');

  /**
   * Static factory designed to expose `change` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.changeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  /**
   * Static factory designed to expose `click` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.clickEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> clickEvent =
      const EventStreamProvider<MouseEvent>('click');

  /**
   * Static factory designed to expose `contextmenu` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.contextmenuEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> contextMenuEvent =
      const EventStreamProvider<MouseEvent>('contextmenu');

  /**
   * Static factory designed to expose `copy` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.copyEvent')
  @DocsEditable()
  static const EventStreamProvider<ClipboardEvent> copyEvent =
      const EventStreamProvider<ClipboardEvent>('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<ClipboardEvent> cutEvent =
      const EventStreamProvider<ClipboardEvent>('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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.dropEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dropEvent =
      const EventStreamProvider<MouseEvent>('drop');

  @DomName('Element.durationchangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> durationChangeEvent =
      const EventStreamProvider<Event>('durationchange');

  @DomName('Element.emptiedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> emptiedEvent =
      const EventStreamProvider<Event>('emptied');

  @DomName('Element.endedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> endedEvent =
      const EventStreamProvider<Event>('ended');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `focus` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.focusEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> focusEvent =
      const EventStreamProvider<Event>('focus');

  /**
   * Static factory designed to expose `input` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.inputEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> inputEvent =
      const EventStreamProvider<Event>('input');

  /**
   * Static factory designed to expose `invalid` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.invalidEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> invalidEvent =
      const EventStreamProvider<Event>('invalid');

  /**
   * Static factory designed to expose `keydown` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.keydownEvent')
  @DocsEditable()
  static const EventStreamProvider<KeyboardEvent> keyDownEvent =
      const EventStreamProvider<KeyboardEvent>('keydown');

  /**
   * Static factory designed to expose `keypress` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.keypressEvent')
  @DocsEditable()
  static const EventStreamProvider<KeyboardEvent> keyPressEvent =
      const EventStreamProvider<KeyboardEvent>('keypress');

  /**
   * Static factory designed to expose `keyup` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.keyupEvent')
  @DocsEditable()
  static const EventStreamProvider<KeyboardEvent> keyUpEvent =
      const EventStreamProvider<KeyboardEvent>('keyup');

  /**
   * Static factory designed to expose `load` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.loadEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> loadEvent =
      const EventStreamProvider<Event>('load');

  @DomName('Element.loadeddataEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadedDataEvent =
      const EventStreamProvider<Event>('loadeddata');

  @DomName('Element.loadedmetadataEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadedMetadataEvent =
      const EventStreamProvider<Event>('loadedmetadata');

  /**
   * Static factory designed to expose `mousedown` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mousedownEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> mouseDownEvent =
      const EventStreamProvider<MouseEvent>('mousedown');

  /**
   * Static factory designed to expose `mouseenter` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mouseenterEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseEnterEvent =
      const EventStreamProvider<MouseEvent>('mouseenter');

  /**
   * Static factory designed to expose `mouseleave` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mouseleaveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseLeaveEvent =
      const EventStreamProvider<MouseEvent>('mouseleave');

  /**
   * Static factory designed to expose `mousemove` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mousemoveEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> mouseMoveEvent =
      const EventStreamProvider<MouseEvent>('mousemove');

  /**
   * Static factory designed to expose `mouseout` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mouseoutEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> mouseOutEvent =
      const EventStreamProvider<MouseEvent>('mouseout');

  /**
   * Static factory designed to expose `mouseover` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mouseoverEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> mouseOverEvent =
      const EventStreamProvider<MouseEvent>('mouseover');

  /**
   * Static factory designed to expose `mouseup` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mouseupEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> mouseUpEvent =
      const EventStreamProvider<MouseEvent>('mouseup');

  /**
   * Static factory designed to expose `paste` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.pasteEvent')
  @DocsEditable()
  static const EventStreamProvider<ClipboardEvent> pasteEvent =
      const EventStreamProvider<ClipboardEvent>('paste');

  @DomName('Element.pauseEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> pauseEvent =
      const EventStreamProvider<Event>('pause');

  @DomName('Element.playEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> playEvent =
      const EventStreamProvider<Event>('play');

  @DomName('Element.playingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> playingEvent =
      const EventStreamProvider<Event>('playing');

  @DomName('Element.ratechangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> rateChangeEvent =
      const EventStreamProvider<Event>('ratechange');

  /**
   * Static factory designed to expose `reset` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.resetEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> resetEvent =
      const EventStreamProvider<Event>('reset');

  @DomName('Element.resizeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> resizeEvent =
      const EventStreamProvider<Event>('resize');

  /**
   * Static factory designed to expose `scroll` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.scrollEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> scrollEvent =
      const EventStreamProvider<Event>('scroll');

  /**
   * Static factory designed to expose `search` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.searchEvent')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  static const EventStreamProvider<Event> searchEvent =
      const EventStreamProvider<Event>('search');

  @DomName('Element.seekedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> seekedEvent =
      const EventStreamProvider<Event>('seeked');

  @DomName('Element.seekingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> seekingEvent =
      const EventStreamProvider<Event>('seeking');

  /**
   * Static factory designed to expose `select` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.selectEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> selectEvent =
      const EventStreamProvider<Event>('select');

  /**
   * Static factory designed to expose `selectstart` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.selectstartEvent')
  @DocsEditable()
  @Experimental() // nonstandard
  static const EventStreamProvider<Event> selectStartEvent =
      const EventStreamProvider<Event>('selectstart');

  @DomName('Element.stalledEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> stalledEvent =
      const EventStreamProvider<Event>('stalled');

  /**
   * Static factory designed to expose `submit` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.submitEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> submitEvent =
      const EventStreamProvider<Event>('submit');

  @DomName('Element.suspendEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> suspendEvent =
      const EventStreamProvider<Event>('suspend');

  @DomName('Element.timeupdateEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> timeUpdateEvent =
      const EventStreamProvider<Event>('timeupdate');

  /**
   * Static factory designed to expose `touchcancel` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchcancelEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchCancelEvent =
      const EventStreamProvider<TouchEvent>('touchcancel');

  /**
   * Static factory designed to expose `touchend` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchendEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchEndEvent =
      const EventStreamProvider<TouchEvent>('touchend');

  /**
   * Static factory designed to expose `touchenter` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchenterEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchEnterEvent =
      const EventStreamProvider<TouchEvent>('touchenter');

  /**
   * Static factory designed to expose `touchleave` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchleaveEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchLeaveEvent =
      const EventStreamProvider<TouchEvent>('touchleave');

  /**
   * Static factory designed to expose `touchmove` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchmoveEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchMoveEvent =
      const EventStreamProvider<TouchEvent>('touchmove');

  /**
   * Static factory designed to expose `touchstart` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchstartEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchStartEvent =
      const EventStreamProvider<TouchEvent>('touchstart');

  @DomName('Element.volumechangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> volumeChangeEvent =
      const EventStreamProvider<Event>('volumechange');

  @DomName('Element.waitingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> waitingEvent =
      const EventStreamProvider<Event>('waiting');

  /**
   * Static factory designed to expose `fullscreenchange` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.webkitfullscreenchangeEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  static const EventStreamProvider<Event> fullscreenChangeEvent =
      const EventStreamProvider<Event>('webkitfullscreenchange');

  /**
   * Static factory designed to expose `fullscreenerror` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.webkitfullscreenerrorEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  static const EventStreamProvider<Event> fullscreenErrorEvent =
      const EventStreamProvider<Event>('webkitfullscreenerror');

  @DomName('Element.contentEditable')
  @DocsEditable()
  String contentEditable;

  @DomName('Element.contextMenu')
  @DocsEditable()
  @Experimental() // untriaged
  MenuElement contextMenu;

  @DomName('Element.dir')
  @DocsEditable()
  String dir;

  /**
   * Indicates whether the element can be dragged and dropped.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.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](https://html.spec.whatwg.org/multipage/interaction.html#the-hidden-attribute)
   *   from WHATWG.
   */
  @DomName('Element.hidden')
  @DocsEditable()
  bool hidden;

  // Using property as subclass shadows.
  bool get isContentEditable => JS("bool", "#.isContentEditable", this);

  @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.style')
  @DocsEditable()
  final CssStyleDeclaration style;

  @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](https://html.spec.whatwg.org/multipage/dom.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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.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.blur')
  @DocsEditable()
  void blur() native;

  @DomName('Element.click')
  @DocsEditable()
  void click() native;

  @DomName('Element.focus')
  @DocsEditable()
  void focus() native;

  @DomName('Element.assignedSlot')
  @DocsEditable()
  @Experimental() // untriaged
  final SlotElement assignedSlot;

  @JSName('attributes')
  @DomName('Element.attributes')
  @DocsEditable()
  final _NamedNodeMap _attributes;

  @DomName('Element.className')
  @DocsEditable()
  String className;

  @DomName('Element.clientHeight')
  @DocsEditable()
  final int clientHeight;

  @DomName('Element.clientLeft')
  @DocsEditable()
  final int clientLeft;

  @DomName('Element.clientTop')
  @DocsEditable()
  final int clientTop;

  @DomName('Element.clientWidth')
  @DocsEditable()
  final int clientWidth;

  @DomName('Element.computedName')
  @DocsEditable()
  @Experimental() // untriaged
  final String computedName;

  @DomName('Element.computedRole')
  @DocsEditable()
  @Experimental() // untriaged
  final String computedRole;

  @DomName('Element.id')
  @DocsEditable()
  String id;

  @JSName('innerHTML')
  @DomName('Element.innerHTML')
  @DocsEditable()
  String _innerHtml;

  @JSName('localName')
  @DomName('Element.localName')
  @DocsEditable()
  @Experimental() // untriaged
  final String _localName;

  @JSName('namespaceURI')
  @DomName('Element.namespaceURI')
  @DocsEditable()
  @Experimental() // untriaged
  final String _namespaceUri;

  // Using property as subclass shadows.
  String get outerHtml => JS("String", "#.outerHTML", this);

  @JSName('scrollHeight')
  @DomName('Element.scrollHeight')
  @DocsEditable()
  final int _scrollHeight;

  @JSName('scrollLeft')
  @DomName('Element.scrollLeft')
  @DocsEditable()
  num _scrollLeft;

  @JSName('scrollTop')
  @DomName('Element.scrollTop')
  @DocsEditable()
  num _scrollTop;

  @JSName('scrollWidth')
  @DomName('Element.scrollWidth')
  @DocsEditable()
  final int _scrollWidth;

  @DomName('Element.slot')
  @DocsEditable()
  @Experimental() // untriaged
  String slot;

  @DomName('Element.tagName')
  @DocsEditable()
  final String tagName;

  @DomName('Element.attachShadow')
  @DocsEditable()
  @Experimental() // untriaged
  ShadowRoot attachShadow(Map shadowRootInitDict) {
    var shadowRootInitDict_1 =
        convertDartToNative_Dictionary(shadowRootInitDict);
    return _attachShadow_1(shadowRootInitDict_1);
  }

  @JSName('attachShadow')
  @DomName('Element.attachShadow')
  @DocsEditable()
  @Experimental() // untriaged
  ShadowRoot _attachShadow_1(shadowRootInitDict) native;

  @DomName('Element.closest')
  @DocsEditable()
  @Experimental() // untriaged
  Element closest(String selectors) native;

  @DomName('Element.getAnimations')
  @DocsEditable()
  @Experimental() // untriaged
  List<Animation> getAnimations() 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()
  @Creates('_ClientRect')
  @Returns('_ClientRect|Null')
  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|Null')
  @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|Null')
  @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 localName) native;

  @JSName('hasAttribute')
  @DomName('Element.hasAttribute')
  @DocsEditable()
  bool _hasAttribute(String name) native;

  @JSName('hasAttributeNS')
  @DomName('Element.hasAttributeNS')
  @DocsEditable()
  bool _hasAttributeNS(String namespaceURI, String localName) native;

  @JSName('removeAttribute')
  @DomName('Element.removeAttribute')
  @DocsEditable()
  void _removeAttribute(String name) native;

  @JSName('removeAttributeNS')
  @DomName('Element.removeAttributeNS')
  @DocsEditable()
  void _removeAttributeNS(String namespaceURI, String localName) native;

  @DomName('Element.requestFullscreen')
  @DocsEditable()
  @Experimental() // untriaged
  void requestFullscreen() native;

  @DomName('Element.requestPointerLock')
  @DocsEditable()
  @Experimental() // untriaged
  void requestPointerLock() native;

  @DomName('Element.scroll')
  @DocsEditable()
  @Experimental() // untriaged
  void scroll([options_OR_x, num y]) {
    if (options_OR_x == null && y == null) {
      _scroll_1();
      return;
    }
    if ((options_OR_x is Map) && y == null) {
      var options_1 = convertDartToNative_Dictionary(options_OR_x);
      _scroll_2(options_1);
      return;
    }
    if (y != null && (options_OR_x is num)) {
      _scroll_3(options_OR_x, y);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('scroll')
  @DomName('Element.scroll')
  @DocsEditable()
  @Experimental() // untriaged
  void _scroll_1() native;
  @JSName('scroll')
  @DomName('Element.scroll')
  @DocsEditable()
  @Experimental() // untriaged
  void _scroll_2(options) native;
  @JSName('scroll')
  @DomName('Element.scroll')
  @DocsEditable()
  @Experimental() // untriaged
  void _scroll_3(num x, y) native;

  @DomName('Element.scrollBy')
  @DocsEditable()
  @Experimental() // untriaged
  void scrollBy([options_OR_x, num y]) {
    if (options_OR_x == null && y == null) {
      _scrollBy_1();
      return;
    }
    if ((options_OR_x is Map) && y == null) {
      var options_1 = convertDartToNative_Dictionary(options_OR_x);
      _scrollBy_2(options_1);
      return;
    }
    if (y != null && (options_OR_x is num)) {
      _scrollBy_3(options_OR_x, y);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('scrollBy')
  @DomName('Element.scrollBy')
  @DocsEditable()
  @Experimental() // untriaged
  void _scrollBy_1() native;
  @JSName('scrollBy')
  @DomName('Element.scrollBy')
  @DocsEditable()
  @Experimental() // untriaged
  void _scrollBy_2(options) native;
  @JSName('scrollBy')
  @DomName('Element.scrollBy')
  @DocsEditable()
  @Experimental() // untriaged
  void _scrollBy_3(num x, y) 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.scrollTo')
  @DocsEditable()
  @Experimental() // untriaged
  void scrollTo([options_OR_x, num y]) {
    if (options_OR_x == null && y == null) {
      _scrollTo_1();
      return;
    }
    if ((options_OR_x is Map) && y == null) {
      var options_1 = convertDartToNative_Dictionary(options_OR_x);
      _scrollTo_2(options_1);
      return;
    }
    if (y != null && (options_OR_x is num)) {
      _scrollTo_3(options_OR_x, y);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('scrollTo')
  @DomName('Element.scrollTo')
  @DocsEditable()
  @Experimental() // untriaged
  void _scrollTo_1() native;
  @JSName('scrollTo')
  @DomName('Element.scrollTo')
  @DocsEditable()
  @Experimental() // untriaged
  void _scrollTo_2(options) native;
  @JSName('scrollTo')
  @DomName('Element.scrollTo')
  @DocsEditable()
  @Experimental() // untriaged
  void _scrollTo_3(num x, y) native;

  @DomName('Element.setApplyScroll')
  @DocsEditable()
  @Experimental() // untriaged
  void setApplyScroll(ScrollStateCallback scrollStateCallback,
      String nativeScrollBehavior) native;

  @DomName('Element.setAttribute')
  @DocsEditable()
  void setAttribute(String name, String value) native;

  @DomName('Element.setAttributeNS')
  @DocsEditable()
  void setAttributeNS(String namespaceURI, String name, String value) native;

  @DomName('Element.setDistributeScroll')
  @DocsEditable()
  @Experimental() // untriaged
  void setDistributeScroll(ScrollStateCallback scrollStateCallback,
      String nativeScrollBehavior) native;

  // From ChildNode

  // From NonDocumentTypeChildNode

  @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|Null')
  @Creates('HtmlCollection')
  final List<Node> _children;

  @JSName('firstElementChild')
  @DomName('Element.firstElementChild')
  @DocsEditable()
  final Element _firstElementChild;

  @JSName('lastElementChild')
  @DomName('Element.lastElementChild')
  @DocsEditable()
  final Element _lastElementChild;

  /**
   * Finds the first descendant element of this element that matches the
   * specified group of selectors.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     // Gets the first descendant with the class 'classname'
   *     var element = element.querySelector('.className');
   *     // Gets the element with id 'id'
   *     var element = element.querySelector('#id');
   *     // Gets the first descendant [ImageElement]
   *     var img = element.querySelector('img');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  @DomName('Element.querySelector')
  @DocsEditable()
  Element querySelector(String selectors) native;

  @JSName('querySelectorAll')
  @DomName('Element.querySelectorAll')
  @DocsEditable()
  @Creates('NodeList')
  @Returns('NodeList')
  List<Node> _querySelectorAll(String selectors) native;

  /// Stream of `abort` events handled by this [Element].
  @DomName('Element.onabort')
  @DocsEditable()
  ElementStream<Event> get onAbort => abortEvent.forElement(this);

  /// Stream of `beforecopy` events handled by this [Element].
  @DomName('Element.onbeforecopy')
  @DocsEditable()
  ElementStream<Event> get onBeforeCopy => beforeCopyEvent.forElement(this);

  /// Stream of `beforecut` events handled by this [Element].
  @DomName('Element.onbeforecut')
  @DocsEditable()
  ElementStream<Event> get onBeforeCut => beforeCutEvent.forElement(this);

  /// Stream of `beforepaste` events handled by this [Element].
  @DomName('Element.onbeforepaste')
  @DocsEditable()
  ElementStream<Event> get onBeforePaste => beforePasteEvent.forElement(this);

  /// Stream of `blur` events handled by this [Element].
  @DomName('Element.onblur')
  @DocsEditable()
  ElementStream<Event> get onBlur => blurEvent.forElement(this);

  @DomName('Element.oncanplay')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onCanPlay => canPlayEvent.forElement(this);

  @DomName('Element.oncanplaythrough')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onCanPlayThrough =>
      canPlayThroughEvent.forElement(this);

  /// Stream of `change` events handled by this [Element].
  @DomName('Element.onchange')
  @DocsEditable()
  ElementStream<Event> get onChange => changeEvent.forElement(this);

  /// Stream of `click` events handled by this [Element].
  @DomName('Element.onclick')
  @DocsEditable()
  ElementStream<MouseEvent> get onClick => clickEvent.forElement(this);

  /// Stream of `contextmenu` events handled by this [Element].
  @DomName('Element.oncontextmenu')
  @DocsEditable()
  ElementStream<MouseEvent> get onContextMenu =>
      contextMenuEvent.forElement(this);

  /// Stream of `copy` events handled by this [Element].
  @DomName('Element.oncopy')
  @DocsEditable()
  ElementStream<ClipboardEvent> get onCopy => copyEvent.forElement(this);

  /// Stream of `cut` events handled by this [Element].
  @DomName('Element.oncut')
  @DocsEditable()
  ElementStream<ClipboardEvent> 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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.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/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.ondrop')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrop => dropEvent.forElement(this);

  @DomName('Element.ondurationchange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onDurationChange =>
      durationChangeEvent.forElement(this);

  @DomName('Element.onemptied')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEmptied => emptiedEvent.forElement(this);

  @DomName('Element.onended')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEnded => endedEvent.forElement(this);

  /// Stream of `error` events handled by this [Element].
  @DomName('Element.onerror')
  @DocsEditable()
  ElementStream<Event> get onError => errorEvent.forElement(this);

  /// Stream of `focus` events handled by this [Element].
  @DomName('Element.onfocus')
  @DocsEditable()
  ElementStream<Event> get onFocus => focusEvent.forElement(this);

  /// Stream of `input` events handled by this [Element].
  @DomName('Element.oninput')
  @DocsEditable()
  ElementStream<Event> get onInput => inputEvent.forElement(this);

  /// Stream of `invalid` events handled by this [Element].
  @DomName('Element.oninvalid')
  @DocsEditable()
  ElementStream<Event> get onInvalid => invalidEvent.forElement(this);

  /// Stream of `keydown` events handled by this [Element].
  @DomName('Element.onkeydown')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyDown => keyDownEvent.forElement(this);

  /// Stream of `keypress` events handled by this [Element].
  @DomName('Element.onkeypress')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyPress => keyPressEvent.forElement(this);

  /// Stream of `keyup` events handled by this [Element].
  @DomName('Element.onkeyup')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyUp => keyUpEvent.forElement(this);

  /// Stream of `load` events handled by this [Element].
  @DomName('Element.onload')
  @DocsEditable()
  ElementStream<Event> get onLoad => loadEvent.forElement(this);

  @DomName('Element.onloadeddata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedData => loadedDataEvent.forElement(this);

  @DomName('Element.onloadedmetadata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedMetadata =>
      loadedMetadataEvent.forElement(this);

  /// Stream of `mousedown` events handled by this [Element].
  @DomName('Element.onmousedown')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseDown => mouseDownEvent.forElement(this);

  /// Stream of `mouseenter` events handled by this [Element].
  @DomName('Element.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseEnter =>
      mouseEnterEvent.forElement(this);

  /// Stream of `mouseleave` events handled by this [Element].
  @DomName('Element.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseLeave =>
      mouseLeaveEvent.forElement(this);

  /// Stream of `mousemove` events handled by this [Element].
  @DomName('Element.onmousemove')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseMove => mouseMoveEvent.forElement(this);

  /// Stream of `mouseout` events handled by this [Element].
  @DomName('Element.onmouseout')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOut => mouseOutEvent.forElement(this);

  /// Stream of `mouseover` events handled by this [Element].
  @DomName('Element.onmouseover')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOver => mouseOverEvent.forElement(this);

  /// Stream of `mouseup` events handled by this [Element].
  @DomName('Element.onmouseup')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseUp => mouseUpEvent.forElement(this);

  /// Stream of `mousewheel` events handled by this [Element].
  @DomName('Element.onmousewheel')
  @DocsEditable()
  // http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents
  @Experimental() // non-standard
  ElementStream<WheelEvent> get onMouseWheel =>
      mouseWheelEvent.forElement(this);

  /// Stream of `paste` events handled by this [Element].
  @DomName('Element.onpaste')
  @DocsEditable()
  ElementStream<ClipboardEvent> get onPaste => pasteEvent.forElement(this);

  @DomName('Element.onpause')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPause => pauseEvent.forElement(this);

  @DomName('Element.onplay')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPlay => playEvent.forElement(this);

  @DomName('Element.onplaying')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPlaying => playingEvent.forElement(this);

  @DomName('Element.onratechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onRateChange => rateChangeEvent.forElement(this);

  /// Stream of `reset` events handled by this [Element].
  @DomName('Element.onreset')
  @DocsEditable()
  ElementStream<Event> get onReset => resetEvent.forElement(this);

  @DomName('Element.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onResize => resizeEvent.forElement(this);

  /// Stream of `scroll` events handled by this [Element].
  @DomName('Element.onscroll')
  @DocsEditable()
  ElementStream<Event> get onScroll => scrollEvent.forElement(this);

  /// Stream of `search` events handled by this [Element].
  @DomName('Element.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  ElementStream<Event> get onSearch => searchEvent.forElement(this);

  @DomName('Element.onseeked')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeked => seekedEvent.forElement(this);

  @DomName('Element.onseeking')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeking => seekingEvent.forElement(this);

  /// Stream of `select` events handled by this [Element].
  @DomName('Element.onselect')
  @DocsEditable()
  ElementStream<Event> get onSelect => selectEvent.forElement(this);

  /// Stream of `selectstart` events handled by this [Element].
  @DomName('Element.onselectstart')
  @DocsEditable()
  @Experimental() // nonstandard
  ElementStream<Event> get onSelectStart => selectStartEvent.forElement(this);

  @DomName('Element.onstalled')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onStalled => stalledEvent.forElement(this);

  /// Stream of `submit` events handled by this [Element].
  @DomName('Element.onsubmit')
  @DocsEditable()
  ElementStream<Event> get onSubmit => submitEvent.forElement(this);

  @DomName('Element.onsuspend')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSuspend => suspendEvent.forElement(this);

  @DomName('Element.ontimeupdate')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onTimeUpdate => timeUpdateEvent.forElement(this);

  /// Stream of `touchcancel` events handled by this [Element].
  @DomName('Element.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchCancel =>
      touchCancelEvent.forElement(this);

  /// Stream of `touchend` events handled by this [Element].
  @DomName('Element.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnd => touchEndEvent.forElement(this);

  /// Stream of `touchenter` events handled by this [Element].
  @DomName('Element.ontouchenter')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnter =>
      touchEnterEvent.forElement(this);

  /// Stream of `touchleave` events handled by this [Element].
  @DomName('Element.ontouchleave')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchLeave =>
      touchLeaveEvent.forElement(this);

  /// Stream of `touchmove` events handled by this [Element].
  @DomName('Element.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchMove => touchMoveEvent.forElement(this);

  /// Stream of `touchstart` events handled by this [Element].
  @DomName('Element.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchStart =>
      touchStartEvent.forElement(this);

  /// Stream of `transitionend` events handled by this [Element].
  @DomName('Element.ontransitionend')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  ElementStream<TransitionEvent> get onTransitionEnd =>
      transitionEndEvent.forElement(this);

  @DomName('Element.onvolumechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onVolumeChange => volumeChangeEvent.forElement(this);

  @DomName('Element.onwaiting')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onWaiting => waitingEvent.forElement(this);

  /// Stream of `fullscreenchange` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenchange')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenChange =>
      fullscreenChangeEvent.forElement(this);

  /// Stream of `fullscreenerror` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenError =>
      fullscreenErrorEvent.forElement(this);
}

class _ElementFactoryProvider {
  @DomName('Document.createElement')
  // Optimization to improve performance until the dart2js compiler inlines this
  // method.
  static dynamic createElement_tag(String tag, String typeExtension) {
    // Firefox may return a JS function for some types (Embed, Object).
    if (typeExtension != null) {
      return JS('Element|=Object', 'document.createElement(#, #)', tag,
          typeExtension);
    }
    // Should be able to eliminate this and just call the two-arg version above
    // with null typeExtension, but Chrome treats the tag as case-sensitive if
    // typeExtension is null.
    // https://code.google.com/p/chromium/issues/detail?id=282467
    return JS('Element|=Object', 'document.createElement(#)', tag);
  }
}

/**
 * Options for Element.scrollIntoView.
 */
class ScrollAlignment {
  final _value;
  const ScrollAlignment._internal(this._value);
  toString() => 'ScrollAlignment.$_value';

  /// Attempt to align the element to the top of the scrollable area.
  static const TOP = const ScrollAlignment._internal('TOP');

  /// Attempt to center the element in the scrollable area.
  static const CENTER = const ScrollAlignment._internal('CENTER');

  /// Attempt to align the element to the bottom of the scrollable area.
  static const BOTTOM = const ScrollAlignment._internal('BOTTOM');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLEmbedElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
@Native("HTMLEmbedElement")
class EmbedElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory EmbedElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLEmbedElement.HTMLEmbedElement')
  @DocsEditable()
  factory EmbedElement() => document.createElement("embed");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  EmbedElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('embed');

  @DomName('HTMLEmbedElement.height')
  @DocsEditable()
  String height;

  @DomName('HTMLEmbedElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLEmbedElement.src')
  @DocsEditable()
  String src;

  @DomName('HTMLEmbedElement.type')
  @DocsEditable()
  String type;

  @DomName('HTMLEmbedElement.width')
  @DocsEditable()
  String width;

  @DomName('HTMLEmbedElement.__getter__')
  @DocsEditable()
  bool __getter__(index_OR_name) native;

  @DomName('HTMLEmbedElement.__setter__')
  @DocsEditable()
  void __setter__(index_OR_name, Node value) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('EntriesCallback')
// http://www.w3.org/TR/file-system-api/#the-entriescallback-interface
@Experimental()
typedef void _EntriesCallback(List<Entry> entries);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('Entry')
// http://www.w3.org/TR/file-system-api/#the-entry-interface
@Experimental()
@Native("Entry")
class Entry extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Entry._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Entry.filesystem')
  @DocsEditable()
  final FileSystem filesystem;

  @DomName('Entry.fullPath')
  @DocsEditable()
  final String fullPath;

  @DomName('Entry.isDirectory')
  @DocsEditable()
  final bool isDirectory;

  @DomName('Entry.isFile')
  @DocsEditable()
  final bool isFile;

  @DomName('Entry.name')
  @DocsEditable()
  final String name;

  @JSName('copyTo')
  @DomName('Entry.copyTo')
  @DocsEditable()
  void _copyTo(DirectoryEntry parent,
      {String name,
      _EntryCallback successCallback,
      _ErrorCallback errorCallback}) native;

  @JSName('copyTo')
  @DomName('Entry.copyTo')
  @DocsEditable()
  Future<Entry> copyTo(DirectoryEntry parent, {String name}) {
    var completer = new Completer<Entry>();
    _copyTo(parent, name: name, successCallback: (value) {
      completer.complete(value);
    }, errorCallback: (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  @JSName('getMetadata')
  @DomName('Entry.getMetadata')
  @DocsEditable()
  void _getMetadata(MetadataCallback successCallback,
      [_ErrorCallback errorCallback]) native;

  @JSName('getMetadata')
  @DomName('Entry.getMetadata')
  @DocsEditable()
  Future<Metadata> getMetadata() {
    var completer = new Completer<Metadata>();
    _getMetadata((value) {
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  @JSName('getParent')
  @DomName('Entry.getParent')
  @DocsEditable()
  void _getParent(
      [_EntryCallback successCallback, _ErrorCallback errorCallback]) native;

  @JSName('getParent')
  @DomName('Entry.getParent')
  @DocsEditable()
  Future<Entry> getParent() {
    var completer = new Completer<Entry>();
    _getParent((value) {
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  @JSName('moveTo')
  @DomName('Entry.moveTo')
  @DocsEditable()
  void _moveTo(DirectoryEntry parent,
      {String name,
      _EntryCallback successCallback,
      _ErrorCallback errorCallback}) native;

  @JSName('moveTo')
  @DomName('Entry.moveTo')
  @DocsEditable()
  Future<Entry> moveTo(DirectoryEntry parent, {String name}) {
    var completer = new Completer<Entry>();
    _moveTo(parent, name: name, successCallback: (value) {
      completer.complete(value);
    }, errorCallback: (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  @JSName('remove')
  @DomName('Entry.remove')
  @DocsEditable()
  void _remove(VoidCallback successCallback, [_ErrorCallback errorCallback])
      native;

  @JSName('remove')
  @DomName('Entry.remove')
  @DocsEditable()
  Future remove() {
    var completer = new Completer();
    _remove(() {
      completer.complete();
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  @JSName('toURL')
  @DomName('Entry.toURL')
  @DocsEditable()
  String toUrl() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('EntryCallback')
// http://www.w3.org/TR/file-system-api/#the-entrycallback-interface
@Experimental()
typedef void _EntryCallback(Entry entry);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('ErrorCallback')
// http://www.w3.org/TR/file-system-api/#the-errorcallback-interface
@Experimental()
typedef void _ErrorCallback(FileError error);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('ErrorEvent')
@Unstable()
@Native("ErrorEvent")
class ErrorEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory ErrorEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('ErrorEvent.ErrorEvent')
  @DocsEditable()
  factory ErrorEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return ErrorEvent._create_1(type, eventInitDict_1);
    }
    return ErrorEvent._create_2(type);
  }
  static ErrorEvent _create_1(type, eventInitDict) =>
      JS('ErrorEvent', 'new ErrorEvent(#,#)', type, eventInitDict);
  static ErrorEvent _create_2(type) =>
      JS('ErrorEvent', 'new ErrorEvent(#)', type);

  @DomName('ErrorEvent.colno')
  @DocsEditable()
  @Experimental() // untriaged
  final int colno;

  @DomName('ErrorEvent.error')
  @DocsEditable()
  @Experimental() // untriaged
  @Creates('Null')
  final Object error;

  @DomName('ErrorEvent.filename')
  @DocsEditable()
  final String filename;

  @DomName('ErrorEvent.lineno')
  @DocsEditable()
  final int lineno;

  @DomName('ErrorEvent.message')
  @DocsEditable()
  final String message;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('Event')
@Native("Event,InputEvent")
class Event extends Interceptor {
  // In JS, canBubble and cancelable are technically required parameters to
  // init*Event. In practice, though, if they aren't provided they simply
  // default to false (since that's Boolean(undefined)).
  //
  // Contrary to JS, we default canBubble and cancelable to true, since that's
  // what people want most of the time anyway.
  factory Event(String type, {bool canBubble: true, bool cancelable: true}) {
    return new Event.eventType('Event', type,
        canBubble: canBubble, cancelable: cancelable);
  }

  /**
   * Creates a new Event object of the specified type.
   *
   * This is analogous to document.createEvent.
   * Normally events should be created via their constructors, if available.
   *
   *     var e = new Event.type('MouseEvent', 'mousedown', true, true);
   */
  factory Event.eventType(String type, String name,
      {bool canBubble: true, bool cancelable: true}) {
    final Event e = document._createEvent(type);
    e._initEvent(name, canBubble, cancelable);
    return e;
  }

  /** The CSS selector involved with event delegation. */
  String _selector;

  /**
   * A pointer to the element whose CSS selector matched within which an event
   * was fired. If this Event was not associated with any Event delegation,
   * accessing this value will throw an [UnsupportedError].
   */
  Element get matchingTarget {
    if (_selector == null) {
      throw new UnsupportedError('Cannot call matchingTarget if this Event did'
          ' not arise as a result of event delegation.');
    }
    Element currentTarget = this.currentTarget;
    Element 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.');
  }

  @DomName('Event.Event')
  @DocsEditable()
  factory Event._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return Event._create_1(type, eventInitDict_1);
    }
    return Event._create_2(type);
  }
  static Event _create_1(type, eventInitDict) =>
      JS('Event', 'new Event(#,#)', type, eventInitDict);
  static Event _create_2(type) => JS('Event', 'new Event(#)', type);

  /**
   * 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;

  @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;

  @DomName('Event.isTrusted')
  @DocsEditable()
  @Experimental() // untriaged
  final bool isTrusted;

  /**
   * 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()
  final List<EventTarget> path;

  @DomName('Event.scoped')
  @DocsEditable()
  @Experimental() // untriaged
  final bool scoped;

  @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 double timeStamp;

  @DomName('Event.type')
  @DocsEditable()
  final String type;

  @DomName('Event.deepPath')
  @DocsEditable()
  @Experimental() // untriaged
  List<EventTarget> deepPath() native;

  @JSName('initEvent')
  @DomName('Event.initEvent')
  @DocsEditable()
  void _initEvent(String type, bool bubbles, bool cancelable) native;

  @DomName('Event.preventDefault')
  @DocsEditable()
  void preventDefault() native;

  @DomName('Event.stopImmediatePropagation')
  @DocsEditable()
  void stopImmediatePropagation() native;

  @DomName('Event.stopPropagation')
  @DocsEditable()
  void stopPropagation() native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DomName('EventSource')
// http://www.w3.org/TR/eventsource/#the-eventsource-interface
@Experimental() // stable
@Native("EventSource")
class EventSource extends EventTarget {
  factory EventSource(String url, {withCredentials: false}) {
    var parsedOptions = {
      'withCredentials': withCredentials,
    };
    return EventSource._factoryEventSource(url, parsedOptions);
  }
  // To suppress missing implicit constructor warnings.
  factory EventSource._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [EventSource].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('EventSource.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [EventSource].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('EventSource.messageEvent')
  @DocsEditable()
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  /**
   * Static factory designed to expose `open` events to event
   * handlers that are not necessarily instances of [EventSource].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('EventSource.openEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> openEvent =
      const EventStreamProvider<Event>('open');

  @DomName('EventSource.EventSource')
  @DocsEditable()
  static EventSource _factoryEventSource(String url,
      [Map eventSourceInitDict]) {
    if (eventSourceInitDict != null) {
      var eventSourceInitDict_1 =
          convertDartToNative_Dictionary(eventSourceInitDict);
      return EventSource._create_1(url, eventSourceInitDict_1);
    }
    return EventSource._create_2(url);
  }

  static EventSource _create_1(url, eventSourceInitDict) =>
      JS('EventSource', 'new EventSource(#,#)', url, eventSourceInitDict);
  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<Event> operator [](String type) {
    return new _EventStream(_ptr, type, false);
  }
}

class ElementEvents extends Events {
  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) : super(ptr);

  Stream<Event> operator [](String type) {
    if (webkitEvents.keys.contains(type.toLowerCase())) {
      if (Device.isWebKit) {
        return new _ElementEventStreamImpl(
            _ptr, webkitEvents[type.toLowerCase()], false);
      }
    }
    return new _ElementEventStreamImpl(_ptr, type, false);
  }
}

/**
 * Base class for all browser objects that support events.
 *
 * Use the [on] property to add, and remove events
 * for compile-time type checks and a more concise API.
 */
@DomName('EventTarget')
@Native("EventTarget")
class EventTarget extends Interceptor {
  // Custom element created callback.
  EventTarget._created();

  /**
   * This is an ease-of-use accessor for event streams which should only be
   * used when an explicit accessor is not available.
   */
  Events get on => new Events(this);

  void addEventListener(String type, EventListener listener,
      [bool useCapture]) {
    // TODO(leafp): This check is avoid a bug in our dispatch code when
    // listener is null.  The browser treats this call as a no-op in this
    // case, so it's fine to short-circuit it, but we should not have to.
    if (listener != null) {
      _addEventListener(type, listener, useCapture);
    }
  }

  void removeEventListener(String type, EventListener listener,
      [bool useCapture]) {
    // TODO(leafp): This check is avoid a bug in our dispatch code when
    // listener is null.  The browser treats this call as a no-op in this
    // case, so it's fine to short-circuit it, but we should not have to.
    if (listener != null) {
      _removeEventListener(type, listener, useCapture);
    }
  }

  // To suppress missing implicit constructor warnings.
  factory EventTarget._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('addEventListener')
  @DomName('EventTarget.addEventListener')
  @DocsEditable()
  void _addEventListener(String type, EventListener listener, [bool options])
      native;

  @DomName('EventTarget.dispatchEvent')
  @DocsEditable()
  bool dispatchEvent(Event event) native;

  @JSName('removeEventListener')
  @DomName('EventTarget.removeEventListener')
  @DocsEditable()
  void _removeEventListener(String type, EventListener listener, [bool options])
      native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('ExtendableEvent')
@Experimental() // untriaged
@Native("ExtendableEvent")
class ExtendableEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory ExtendableEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('ExtendableEvent.ExtendableEvent')
  @DocsEditable()
  factory ExtendableEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return ExtendableEvent._create_1(type, eventInitDict_1);
    }
    return ExtendableEvent._create_2(type);
  }
  static ExtendableEvent _create_1(type, eventInitDict) =>
      JS('ExtendableEvent', 'new ExtendableEvent(#,#)', type, eventInitDict);
  static ExtendableEvent _create_2(type) =>
      JS('ExtendableEvent', 'new ExtendableEvent(#)', type);

  @DomName('ExtendableEvent.waitUntil')
  @DocsEditable()
  @Experimental() // untriaged
  void waitUntil(Future f) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('ExtendableMessageEvent')
@Experimental() // untriaged
@Native("ExtendableMessageEvent")
class ExtendableMessageEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory ExtendableMessageEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('ExtendableMessageEvent.data')
  @DocsEditable()
  @Experimental() // untriaged
  @annotation_Creates_SerializedScriptValue
  @annotation_Returns_SerializedScriptValue
  final Object data;

  @DomName('ExtendableMessageEvent.lastEventId')
  @DocsEditable()
  @Experimental() // untriaged
  final String lastEventId;

  @DomName('ExtendableMessageEvent.origin')
  @DocsEditable()
  @Experimental() // untriaged
  final String origin;

  @DomName('ExtendableMessageEvent.ports')
  @DocsEditable()
  @Experimental() // untriaged
  final List<MessagePort> ports;

  @DomName('ExtendableMessageEvent.source')
  @DocsEditable()
  @Experimental() // untriaged
  @Creates('Client|_ServiceWorker|MessagePort')
  @Returns('Client|_ServiceWorker|MessagePort|Null')
  final Object source;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('FederatedCredential')
@Experimental() // untriaged
@Native("FederatedCredential")
class FederatedCredential extends Credential {
  // To suppress missing implicit constructor warnings.
  factory FederatedCredential._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('FederatedCredential.FederatedCredential')
  @DocsEditable()
  factory FederatedCredential(Map data) {
    var data_1 = convertDartToNative_Dictionary(data);
    return FederatedCredential._create_1(data_1);
  }
  static FederatedCredential _create_1(data) =>
      JS('FederatedCredential', 'new FederatedCredential(#)', data);

  @DomName('FederatedCredential.protocol')
  @DocsEditable()
  @Experimental() // untriaged
  final String protocol;

  @DomName('FederatedCredential.provider')
  @DocsEditable()
  @Experimental() // untriaged
  final String provider;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('FetchEvent')
@Experimental() // untriaged
@Native("FetchEvent")
class FetchEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory FetchEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('FetchEvent.FetchEvent')
  @DocsEditable()
  factory FetchEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return FetchEvent._create_1(type, eventInitDict_1);
  }
  static FetchEvent _create_1(type, eventInitDict) =>
      JS('FetchEvent', 'new FetchEvent(#,#)', type, eventInitDict);

  @DomName('FetchEvent.clientId')
  @DocsEditable()
  @Experimental() // untriaged
  final String clientId;

  @DomName('FetchEvent.isReload')
  @DocsEditable()
  @Experimental() // untriaged
  final bool isReload;

  @DomName('FetchEvent.request')
  @DocsEditable()
  @Experimental() // untriaged
  final _Request request;

  @DomName('FetchEvent.respondWith')
  @DocsEditable()
  @Experimental() // untriaged
  void respondWith(Future r) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLFieldSetElement')
@Unstable()
@Native("HTMLFieldSetElement")
class FieldSetElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory FieldSetElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLFieldSetElement.HTMLFieldSetElement')
  @DocsEditable()
  factory FieldSetElement() => JS(
      'returns:FieldSetElement;creates:FieldSetElement;new:true',
      '#.createElement(#)',
      document,
      "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()
  final HtmlFormControlsCollection 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.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() native;

  @DomName('HTMLFieldSetElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('File')
@Native("File")
class File extends Blob {
  // To suppress missing implicit constructor warnings.
  factory File._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('File.File')
  @DocsEditable()
  factory File(List<Object> fileBits, String fileName, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return File._create_1(fileBits, fileName, options_1);
    }
    return File._create_2(fileBits, fileName);
  }
  static File _create_1(fileBits, fileName, options) =>
      JS('File', 'new File(#,#,#)', fileBits, fileName, options);
  static File _create_2(fileBits, fileName) =>
      JS('File', 'new File(#,#)', fileBits, fileName);

  @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.

@DocsEditable()
@DomName('FileEntry')
// http://www.w3.org/TR/file-system-api/#the-fileentry-interface
@Experimental()
@Native("FileEntry")
class FileEntry extends Entry {
  // To suppress missing implicit constructor warnings.
  factory FileEntry._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('createWriter')
  @DomName('FileEntry.createWriter')
  @DocsEditable()
  void _createWriter(_FileWriterCallback successCallback,
      [_ErrorCallback errorCallback]) native;

  @JSName('createWriter')
  @DomName('FileEntry.createWriter')
  @DocsEditable()
  Future<FileWriter> createWriter() {
    var completer = new Completer<FileWriter>();
    _createWriter((value) {
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  @JSName('file')
  @DomName('FileEntry.file')
  @DocsEditable()
  void _file(BlobCallback successCallback, [_ErrorCallback errorCallback])
      native;

  @JSName('file')
  @DomName('FileEntry.file')
  @DocsEditable()
  Future<Blob> file() {
    var completer = new Completer<Blob>();
    _file((value) {
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('FileError')
// http://dev.w3.org/2009/dap/file-system/pub/FileSystem/
@Experimental()
@Native("FileError")
class FileError extends DomError {
  // To suppress missing implicit constructor warnings.
  factory FileError._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('FileError.ABORT_ERR')
  @DocsEditable()
  static const int ABORT_ERR = 3;

  @DomName('FileError.ENCODING_ERR')
  @DocsEditable()
  static const int ENCODING_ERR = 5;

  @DomName('FileError.INVALID_MODIFICATION_ERR')
  @DocsEditable()
  static const int INVALID_MODIFICATION_ERR = 9;

  @DomName('FileError.INVALID_STATE_ERR')
  @DocsEditable()
  static const int INVALID_STATE_ERR = 7;

  @DomName('FileError.NOT_FOUND_ERR')
  @DocsEditable()
  static const int NOT_FOUND_ERR = 1;

  @DomName('FileError.NOT_READABLE_ERR')
  @DocsEditable()
  static const int NOT_READABLE_ERR = 4;

  @DomName('FileError.NO_MODIFICATION_ALLOWED_ERR')
  @DocsEditable()
  static const int NO_MODIFICATION_ALLOWED_ERR = 6;

  @DomName('FileError.PATH_EXISTS_ERR')
  @DocsEditable()
  static const int PATH_EXISTS_ERR = 12;

  @DomName('FileError.QUOTA_EXCEEDED_ERR')
  @DocsEditable()
  static const int QUOTA_EXCEEDED_ERR = 10;

  @DomName('FileError.SECURITY_ERR')
  @DocsEditable()
  static const int SECURITY_ERR = 2;

  @DomName('FileError.SYNTAX_ERR')
  @DocsEditable()
  static const int SYNTAX_ERR = 8;

  @DomName('FileError.TYPE_MISMATCH_ERR')
  @DocsEditable()
  static const int TYPE_MISMATCH_ERR = 11;

  @DomName('FileError.code')
  @DocsEditable()
  final int code;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('FileList')
@Native("FileList")
class FileList extends Interceptor
    with ListMixin<File>, ImmutableListMixin<File>
    implements List<File>, JavaScriptIndexingBehavior<File> {
  // To suppress missing implicit constructor warnings.
  factory FileList._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('FileList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  File operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("File", "#[#]", this, index);
  }

  void operator []=(int index, File value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<File> mixins.
  // File is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  File get first {
    if (this.length > 0) {
      return JS('File', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  File get last {
    int len = this.length;
    if (len > 0) {
      return JS('File', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  File get single {
    int len = this.length;
    if (len == 1) {
      return JS('File', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  File elementAt(int index) => this[index];
  // -- end List<File> mixins.

  @DomName('FileList.item')
  @DocsEditable()
  File item(int index) native;
}
// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('FileReader')
@Native("FileReader")
class FileReader extends EventTarget {
  @DomName('FileReader.result')
  @DocsEditable()
  Object get result {
    var res = JS('Null|String|NativeByteBuffer', '#.result', this);
    if (res is ByteBuffer) {
      return new Uint8List.view(res);
    }
    return res;
  }

  // To suppress missing implicit constructor warnings.
  factory FileReader._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `abort` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileReader.abortEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> abortEvent =
      const EventStreamProvider<ProgressEvent>('abort');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileReader.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `load` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileReader.loadEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> loadEvent =
      const EventStreamProvider<ProgressEvent>('load');

  /**
   * Static factory designed to expose `loadend` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileReader.loadendEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> loadEndEvent =
      const EventStreamProvider<ProgressEvent>('loadend');

  /**
   * Static factory designed to expose `loadstart` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileReader.loadstartEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> loadStartEvent =
      const EventStreamProvider<ProgressEvent>('loadstart');

  /**
   * Static factory designed to expose `progress` events to event
   * handlers that are not necessarily instances of [FileReader].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileReader.progressEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> progressEvent =
      const EventStreamProvider<ProgressEvent>('progress');

  @DomName('FileReader.FileReader')
  @DocsEditable()
  factory FileReader() {
    return FileReader._create_1();
  }
  static FileReader _create_1() => JS('FileReader', 'new FileReader()');

  @DomName('FileReader.DONE')
  @DocsEditable()
  static const int DONE = 2;

  @DomName('FileReader.EMPTY')
  @DocsEditable()
  static const int EMPTY = 0;

  @DomName('FileReader.LOADING')
  @DocsEditable()
  static const int LOADING = 1;

  @DomName('FileReader.error')
  @DocsEditable()
  final FileError error;

  @DomName('FileReader.readyState')
  @DocsEditable()
  final int readyState;

  @DomName('FileReader.abort')
  @DocsEditable()
  void abort() native;

  @DomName('FileReader.readAsArrayBuffer')
  @DocsEditable()
  void readAsArrayBuffer(Blob blob) native;

  @JSName('readAsDataURL')
  @DomName('FileReader.readAsDataURL')
  @DocsEditable()
  void readAsDataUrl(Blob blob) native;

  @DomName('FileReader.readAsText')
  @DocsEditable()
  void readAsText(Blob blob, [String label]) native;

  /// Stream of `abort` events handled by this [FileReader].
  @DomName('FileReader.onabort')
  @DocsEditable()
  Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);

  /// Stream of `error` events handled by this [FileReader].
  @DomName('FileReader.onerror')
  @DocsEditable()
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `load` events handled by this [FileReader].
  @DomName('FileReader.onload')
  @DocsEditable()
  Stream<ProgressEvent> get onLoad => loadEvent.forTarget(this);

  /// Stream of `loadend` events handled by this [FileReader].
  @DomName('FileReader.onloadend')
  @DocsEditable()
  Stream<ProgressEvent> get onLoadEnd => loadEndEvent.forTarget(this);

  /// Stream of `loadstart` events handled by this [FileReader].
  @DomName('FileReader.onloadstart')
  @DocsEditable()
  Stream<ProgressEvent> get onLoadStart => loadStartEvent.forTarget(this);

  /// Stream of `progress` events handled by this [FileReader].
  @DomName('FileReader.onprogress')
  @DocsEditable()
  Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('Stream')
@Experimental() // untriaged
@Native("Stream")
class FileStream extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory FileStream._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Stream.type')
  @DocsEditable()
  @Experimental() // untriaged
  final String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('DOMFileSystem')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://www.w3.org/TR/file-system-api/
@Native("DOMFileSystem")
class FileSystem extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory FileSystem._() {
    throw new UnsupportedError("Not supported");
  }

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.webkitRequestFileSystem)');

  @DomName('DOMFileSystem.name')
  @DocsEditable()
  final String name;

  @DomName('DOMFileSystem.root')
  @DocsEditable()
  final DirectoryEntry root;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('FileSystemCallback')
// http://www.w3.org/TR/file-system-api/#the-filesystemcallback-interface
@Experimental()
typedef void _FileSystemCallback(FileSystem fileSystem);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('FileWriter')
// http://www.w3.org/TR/file-writer-api/#the-filewriter-interface
@Experimental()
@Native("FileWriter")
class FileWriter extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory FileWriter._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `abort` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileWriter.abortEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> abortEvent =
      const EventStreamProvider<ProgressEvent>('abort');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileWriter.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `progress` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileWriter.progressEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> progressEvent =
      const EventStreamProvider<ProgressEvent>('progress');

  /**
   * Static factory designed to expose `write` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileWriter.writeEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> writeEvent =
      const EventStreamProvider<ProgressEvent>('write');

  /**
   * Static factory designed to expose `writeend` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileWriter.writeendEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> writeEndEvent =
      const EventStreamProvider<ProgressEvent>('writeend');

  /**
   * Static factory designed to expose `writestart` events to event
   * handlers that are not necessarily instances of [FileWriter].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('FileWriter.writestartEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> writeStartEvent =
      const EventStreamProvider<ProgressEvent>('writestart');

  @DomName('FileWriter.DONE')
  @DocsEditable()
  static const int DONE = 2;

  @DomName('FileWriter.INIT')
  @DocsEditable()
  static const int INIT = 0;

  @DomName('FileWriter.WRITING')
  @DocsEditable()
  static const int WRITING = 1;

  @DomName('FileWriter.error')
  @DocsEditable()
  final FileError error;

  @DomName('FileWriter.length')
  @DocsEditable()
  final int length;

  @DomName('FileWriter.position')
  @DocsEditable()
  final int position;

  @DomName('FileWriter.readyState')
  @DocsEditable()
  final int readyState;

  @DomName('FileWriter.abort')
  @DocsEditable()
  void abort() native;

  @DomName('FileWriter.seek')
  @DocsEditable()
  void seek(int position) native;

  @DomName('FileWriter.truncate')
  @DocsEditable()
  void truncate(int size) native;

  @DomName('FileWriter.write')
  @DocsEditable()
  void write(Blob data) native;

  /// Stream of `abort` events handled by this [FileWriter].
  @DomName('FileWriter.onabort')
  @DocsEditable()
  Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);

  /// Stream of `error` events handled by this [FileWriter].
  @DomName('FileWriter.onerror')
  @DocsEditable()
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `progress` events handled by this [FileWriter].
  @DomName('FileWriter.onprogress')
  @DocsEditable()
  Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);

  /// Stream of `write` events handled by this [FileWriter].
  @DomName('FileWriter.onwrite')
  @DocsEditable()
  Stream<ProgressEvent> get onWrite => writeEvent.forTarget(this);

  /// Stream of `writeend` events handled by this [FileWriter].
  @DomName('FileWriter.onwriteend')
  @DocsEditable()
  Stream<ProgressEvent> get onWriteEnd => writeEndEvent.forTarget(this);

  /// Stream of `writestart` events handled by this [FileWriter].
  @DomName('FileWriter.onwritestart')
  @DocsEditable()
  Stream<ProgressEvent> get onWriteStart => writeStartEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('FileWriterCallback')
// http://www.w3.org/TR/file-writer-api/#idl-def-FileWriter
@Experimental()
typedef void _FileWriterCallback(FileWriter fileWriter);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('FocusEvent')
@Native("FocusEvent")
class FocusEvent extends UIEvent {
  // To suppress missing implicit constructor warnings.
  factory FocusEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('FocusEvent.FocusEvent')
  @DocsEditable()
  factory FocusEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return FocusEvent._create_1(type, eventInitDict_1);
    }
    return FocusEvent._create_2(type);
  }
  static FocusEvent _create_1(type, eventInitDict) =>
      JS('FocusEvent', 'new FocusEvent(#,#)', type, eventInitDict);
  static FocusEvent _create_2(type) =>
      JS('FocusEvent', 'new FocusEvent(#)', type);

  @DomName('FocusEvent.relatedTarget')
  @DocsEditable()
  EventTarget get relatedTarget =>
      _convertNativeToDart_EventTarget(this._get_relatedTarget);
  @JSName('relatedTarget')
  @DomName('FocusEvent.relatedTarget')
  @DocsEditable()
  @Creates('Null')
  final dynamic _get_relatedTarget;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('FontFace')
@Experimental() // untriaged
@Native("FontFace")
class FontFace extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory FontFace._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('FontFace.FontFace')
  @DocsEditable()
  factory FontFace(String family, Object source, [Map descriptors]) {
    if (descriptors != null) {
      var descriptors_1 = convertDartToNative_Dictionary(descriptors);
      return FontFace._create_1(family, source, descriptors_1);
    }
    return FontFace._create_2(family, source);
  }
  static FontFace _create_1(family, source, descriptors) =>
      JS('FontFace', 'new FontFace(#,#,#)', family, source, descriptors);
  static FontFace _create_2(family, source) =>
      JS('FontFace', 'new FontFace(#,#)', family, source);

  @DomName('FontFace.family')
  @DocsEditable()
  @Experimental() // untriaged
  String family;

  @DomName('FontFace.featureSettings')
  @DocsEditable()
  @Experimental() // untriaged
  String featureSettings;

  @DomName('FontFace.loaded')
  @DocsEditable()
  @Experimental() // untriaged
  final Future loaded;

  @DomName('FontFace.status')
  @DocsEditable()
  @Experimental() // untriaged
  final String status;

  @DomName('FontFace.stretch')
  @DocsEditable()
  @Experimental() // untriaged
  String stretch;

  @DomName('FontFace.style')
  @DocsEditable()
  @Experimental() // untriaged
  String style;

  @DomName('FontFace.unicodeRange')
  @DocsEditable()
  @Experimental() // untriaged
  String unicodeRange;

  @DomName('FontFace.variant')
  @DocsEditable()
  @Experimental() // untriaged
  String variant;

  @DomName('FontFace.weight')
  @DocsEditable()
  @Experimental() // untriaged
  String weight;

  @DomName('FontFace.load')
  @DocsEditable()
  @Experimental() // untriaged
  Future load() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('FontFaceSet')
@Experimental() // untriaged
@Native("FontFaceSet")
class FontFaceSet extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory FontFaceSet._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('FontFaceSet.size')
  @DocsEditable()
  @Experimental() // untriaged
  final int size;

  @DomName('FontFaceSet.status')
  @DocsEditable()
  @Experimental() // untriaged
  final String status;

  @DomName('FontFaceSet.add')
  @DocsEditable()
  @Experimental() // untriaged
  FontFaceSet add(FontFace arg) 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 arg) native;

  @DomName('FontFaceSet.forEach')
  @DocsEditable()
  @Experimental() // untriaged
  void forEach(FontFaceSetForEachCallback callback, [Object thisArg]) native;

  @DomName('FontFaceSet.has')
  @DocsEditable()
  @Experimental() // untriaged
  bool has(FontFace arg) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('FontFaceSetLoadEvent')
@Experimental() // untriaged
@Native("FontFaceSetLoadEvent")
class FontFaceSetLoadEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory FontFaceSetLoadEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('FontFaceSetLoadEvent.fontfaces')
  @DocsEditable()
  @Experimental() // untriaged
  final List<FontFace> fontfaces;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('FormData')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
@Native("FormData")
class FormData extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory FormData._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('FormData.FormData')
  @DocsEditable()
  factory FormData([FormElement form]) {
    if (form != null) {
      return FormData._create_1(form);
    }
    return FormData._create_2();
  }
  static FormData _create_1(form) => JS('FormData', 'new FormData(#)', form);
  static FormData _create_2() => JS('FormData', 'new FormData()');

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.FormData)');

  @DomName('FormData.append')
  @DocsEditable()
  void append(String name, String value) native;

  @JSName('append')
  @DomName('FormData.append')
  @DocsEditable()
  void appendBlob(String name, Blob value, [String filename]) native;

  @DomName('FormData.delete')
  @DocsEditable()
  @Experimental() // untriaged
  void delete(String name) native;

  @DomName('FormData.get')
  @DocsEditable()
  @Experimental() // untriaged
  Object get(String name) native;

  @DomName('FormData.getAll')
  @DocsEditable()
  @Experimental() // untriaged
  List<Object> getAll(String name) native;

  @DomName('FormData.has')
  @DocsEditable()
  @Experimental() // untriaged
  bool has(String name) native;

  @DomName('FormData.set')
  @DocsEditable()
  @Experimental() // untriaged
  void set(String name, value, [String filename]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLFormElement')
@Native("HTMLFormElement")
class FormElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory FormElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLFormElement.HTMLFormElement')
  @DocsEditable()
  factory FormElement() => JS(
      'returns:FormElement;creates:FormElement;new:true',
      '#.createElement(#)',
      document,
      "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()
  Object __getter__(String name) native;

  @DomName('HTMLFormElement.checkValidity')
  @DocsEditable()
  bool checkValidity() native;

  @DomName('HTMLFormElement.item')
  @DocsEditable()
  @Experimental() // untriaged
  Element item(int index) native;

  @DomName('HTMLFormElement.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() native;

  @DomName('HTMLFormElement.requestAutocomplete')
  @DocsEditable()
  // http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2012-October/037711.html
  @Experimental()
  void requestAutocomplete(Map details) {
    var details_1 = convertDartToNative_Dictionary(details);
    _requestAutocomplete_1(details_1);
    return;
  }

  @JSName('requestAutocomplete')
  @DomName('HTMLFormElement.requestAutocomplete')
  @DocsEditable()
  // http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2012-October/037711.html
  @Experimental()
  void _requestAutocomplete_1(details) native;

  @DomName('HTMLFormElement.reset')
  @DocsEditable()
  void reset() native;

  @DomName('HTMLFormElement.submit')
  @DocsEditable()
  void submit() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('FrameRequestCallback')
@Experimental() // untriaged
typedef void FrameRequestCallback(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('Gamepad')
// https://dvcs.w3.org/hg/gamepad/raw-file/default/gamepad.html#gamepad-interface
@Experimental()
@Native("Gamepad")
class Gamepad extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Gamepad._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Gamepad.axes')
  @DocsEditable()
  final List<num> axes;

  @DomName('Gamepad.buttons')
  @DocsEditable()
  @Creates('JSExtendableArray|GamepadButton')
  @Returns('JSExtendableArray')
  final List<GamepadButton> buttons;

  @DomName('Gamepad.connected')
  @DocsEditable()
  @Experimental() // untriaged
  final bool connected;

  @DomName('Gamepad.id')
  @DocsEditable()
  final String id;

  @DomName('Gamepad.index')
  @DocsEditable()
  final int index;

  @DomName('Gamepad.mapping')
  @DocsEditable()
  @Experimental() // untriaged
  final String mapping;

  @DomName('Gamepad.timestamp')
  @DocsEditable()
  final int timestamp;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('GamepadButton')
@Experimental() // untriaged
@Native("GamepadButton")
class GamepadButton extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory GamepadButton._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('GamepadButton.pressed')
  @DocsEditable()
  @Experimental() // untriaged
  final bool pressed;

  @DomName('GamepadButton.value')
  @DocsEditable()
  @Experimental() // untriaged
  final double value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('GamepadEvent')
@Experimental() // untriaged
@Native("GamepadEvent")
class GamepadEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory GamepadEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('GamepadEvent.GamepadEvent')
  @DocsEditable()
  factory GamepadEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return GamepadEvent._create_1(type, eventInitDict_1);
    }
    return GamepadEvent._create_2(type);
  }
  static GamepadEvent _create_1(type, eventInitDict) =>
      JS('GamepadEvent', 'new GamepadEvent(#,#)', type, eventInitDict);
  static GamepadEvent _create_2(type) =>
      JS('GamepadEvent', 'new GamepadEvent(#)', type);

  @DomName('GamepadEvent.gamepad')
  @DocsEditable()
  @Experimental() // untriaged
  final Gamepad gamepad;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('Geofencing')
@Experimental() // untriaged
@Native("Geofencing")
class Geofencing extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Geofencing._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Geofencing.getRegisteredRegions')
  @DocsEditable()
  @Experimental() // untriaged
  Future getRegisteredRegions() native;

  @DomName('Geofencing.registerRegion')
  @DocsEditable()
  @Experimental() // untriaged
  Future registerRegion(GeofencingRegion region) native;

  @DomName('Geofencing.unregisterRegion')
  @DocsEditable()
  @Experimental() // untriaged
  Future unregisterRegion(String regionId) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('GeofencingEvent')
@Experimental() // untriaged
@Native("GeofencingEvent")
class GeofencingEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory GeofencingEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('GeofencingEvent.id')
  @DocsEditable()
  @Experimental() // untriaged
  final String id;

  @DomName('GeofencingEvent.region')
  @DocsEditable()
  @Experimental() // untriaged
  final GeofencingRegion region;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('GeofencingRegion')
@Experimental() // untriaged
@Native("GeofencingRegion")
class GeofencingRegion extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory GeofencingRegion._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('GeofencingRegion.id')
  @DocsEditable()
  @Experimental() // untriaged
  final String id;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('Geolocation')
@Unstable()
@Native("Geolocation")
class Geolocation extends Interceptor {
  @DomName('Geolocation.getCurrentPosition')
  Future<Geoposition> getCurrentPosition(
      {bool enableHighAccuracy, Duration timeout, Duration maximumAge}) {
    var options = {};
    if (enableHighAccuracy != null) {
      options['enableHighAccuracy'] = enableHighAccuracy;
    }
    if (timeout != null) {
      options['timeout'] = timeout.inMilliseconds;
    }
    if (maximumAge != null) {
      options['maximumAge'] = maximumAge.inMilliseconds;
    }
    var completer = new Completer<Geoposition>();
    try {
      _getCurrentPosition((position) {
        completer.complete(_ensurePosition(position));
      }, (error) {
        completer.completeError(error);
      }, options);
    } catch (e, stacktrace) {
      completer.completeError(e, stacktrace);
    }
    return completer.future;
  }

  @DomName('Geolocation.watchPosition')
  Stream<Geoposition> watchPosition(
      {bool enableHighAccuracy, Duration timeout, Duration maximumAge}) {
    var options = {};
    if (enableHighAccuracy != null) {
      options['enableHighAccuracy'] = enableHighAccuracy;
    }
    if (timeout != null) {
      options['timeout'] = timeout.inMilliseconds;
    }
    if (maximumAge != null) {
      options['maximumAge'] = maximumAge.inMilliseconds;
    }

    int watchId;
    // TODO(jacobr): it seems like a bug that we have to specifiy the static
    // type here for controller.stream to have the right type.
    // dartbug.com/26278
    StreamController<Geoposition> controller;
    controller = new StreamController<Geoposition>(
        sync: true,
        onListen: () {
          assert(watchId == null);
          watchId = _watchPosition((position) {
            controller.add(_ensurePosition(position));
          }, (error) {
            controller.addError(error);
          }, options);
        },
        onCancel: () {
          assert(watchId != null);
          _clearWatch(watchId);
        });

    return controller.stream;
  }

  Geoposition _ensurePosition(domPosition) {
    try {
      // Firefox may throw on this.
      if (domPosition is Geoposition) {
        return domPosition;
      }
    } catch (e) {}
    return new _GeopositionWrapper(domPosition);
  }

  // To suppress missing implicit constructor warnings.
  factory Geolocation._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('clearWatch')
  @DomName('Geolocation.clearWatch')
  @DocsEditable()
  void _clearWatch(int watchID) native;

  @DomName('Geolocation.getCurrentPosition')
  @DocsEditable()
  void _getCurrentPosition(_PositionCallback successCallback,
      [_PositionErrorCallback errorCallback, Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      _getCurrentPosition_1(successCallback, errorCallback, options_1);
      return;
    }
    if (errorCallback != null) {
      _getCurrentPosition_2(successCallback, errorCallback);
      return;
    }
    _getCurrentPosition_3(successCallback);
    return;
  }

  @JSName('getCurrentPosition')
  @DomName('Geolocation.getCurrentPosition')
  @DocsEditable()
  void _getCurrentPosition_1(_PositionCallback successCallback,
      _PositionErrorCallback errorCallback, options) native;
  @JSName('getCurrentPosition')
  @DomName('Geolocation.getCurrentPosition')
  @DocsEditable()
  void _getCurrentPosition_2(_PositionCallback successCallback,
      _PositionErrorCallback errorCallback) native;
  @JSName('getCurrentPosition')
  @DomName('Geolocation.getCurrentPosition')
  @DocsEditable()
  void _getCurrentPosition_3(_PositionCallback successCallback) native;

  @DomName('Geolocation.watchPosition')
  @DocsEditable()
  int _watchPosition(_PositionCallback successCallback,
      [_PositionErrorCallback errorCallback, Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _watchPosition_1(successCallback, errorCallback, options_1);
    }
    if (errorCallback != null) {
      return _watchPosition_2(successCallback, errorCallback);
    }
    return _watchPosition_3(successCallback);
  }

  @JSName('watchPosition')
  @DomName('Geolocation.watchPosition')
  @DocsEditable()
  int _watchPosition_1(_PositionCallback successCallback,
      _PositionErrorCallback errorCallback, options) native;
  @JSName('watchPosition')
  @DomName('Geolocation.watchPosition')
  @DocsEditable()
  int _watchPosition_2(_PositionCallback successCallback,
      _PositionErrorCallback errorCallback) native;
  @JSName('watchPosition')
  @DomName('Geolocation.watchPosition')
  @DocsEditable()
  int _watchPosition_3(_PositionCallback successCallback) native;
}

/**
 * Wrapper for Firefox- it returns an object which we cannot map correctly.
 * Basically Firefox was returning a [xpconnect wrapped nsIDOMGeoPosition] but
 * which has further oddities.
 */
class _GeopositionWrapper implements Geoposition {
  var _ptr;
  _GeopositionWrapper(this._ptr);

  Coordinates get coords => JS('Coordinates', '#.coords', _ptr);
  int get timestamp => JS('int', '#.timestamp', _ptr);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('Geoposition')
@Unstable()
@Native("Geoposition")
class Geoposition extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Geoposition._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Geoposition.coords')
  @DocsEditable()
  final Coordinates coords;

  @DomName('Geoposition.timestamp')
  @DocsEditable()
  final int timestamp;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// We implement EventTarget and have stubs for its methods because it's tricky to
// convince the scripts to make our instance methods abstract, and the bodies that
// get generated require `this` to be an EventTarget.
@DocsEditable()
@DomName('GlobalEventHandlers')
@Experimental() // untriaged
abstract class GlobalEventHandlers implements EventTarget {
  void addEventListener(String type, dynamic listener(Event event),
      [bool useCapture]);
  bool dispatchEvent(Event event);
  void removeEventListener(String type, dynamic listener(Event event),
      [bool useCapture]);
  Events get on;

  // To suppress missing implicit constructor warnings.
  factory GlobalEventHandlers._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('GlobalEventHandlers.abortEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> abortEvent =
      const EventStreamProvider<Event>('abort');

  @DomName('GlobalEventHandlers.blurEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> blurEvent =
      const EventStreamProvider<Event>('blur');

  @DomName('GlobalEventHandlers.canplayEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> canPlayEvent =
      const EventStreamProvider<Event>('canplay');

  @DomName('GlobalEventHandlers.canplaythroughEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> canPlayThroughEvent =
      const EventStreamProvider<Event>('canplaythrough');

  @DomName('GlobalEventHandlers.changeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  @DomName('GlobalEventHandlers.clickEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> clickEvent =
      const EventStreamProvider<MouseEvent>('click');

  @DomName('GlobalEventHandlers.contextmenuEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> contextMenuEvent =
      const EventStreamProvider<MouseEvent>('contextmenu');

  @DomName('GlobalEventHandlers.dblclickEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> doubleClickEvent =
      const EventStreamProvider<Event>('dblclick');

  @DomName('GlobalEventHandlers.dragEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragEvent =
      const EventStreamProvider<MouseEvent>('drag');

  @DomName('GlobalEventHandlers.dragendEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragEndEvent =
      const EventStreamProvider<MouseEvent>('dragend');

  @DomName('GlobalEventHandlers.dragenterEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragEnterEvent =
      const EventStreamProvider<MouseEvent>('dragenter');

  @DomName('GlobalEventHandlers.dragleaveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragLeaveEvent =
      const EventStreamProvider<MouseEvent>('dragleave');

  @DomName('GlobalEventHandlers.dragoverEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragOverEvent =
      const EventStreamProvider<MouseEvent>('dragover');

  @DomName('GlobalEventHandlers.dragstartEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragStartEvent =
      const EventStreamProvider<MouseEvent>('dragstart');

  @DomName('GlobalEventHandlers.dropEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dropEvent =
      const EventStreamProvider<MouseEvent>('drop');

  @DomName('GlobalEventHandlers.durationchangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> durationChangeEvent =
      const EventStreamProvider<Event>('durationchange');

  @DomName('GlobalEventHandlers.emptiedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> emptiedEvent =
      const EventStreamProvider<Event>('emptied');

  @DomName('GlobalEventHandlers.endedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> endedEvent =
      const EventStreamProvider<Event>('ended');

  @DomName('GlobalEventHandlers.errorEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  @DomName('GlobalEventHandlers.focusEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> focusEvent =
      const EventStreamProvider<Event>('focus');

  @DomName('GlobalEventHandlers.inputEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> inputEvent =
      const EventStreamProvider<Event>('input');

  @DomName('GlobalEventHandlers.invalidEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> invalidEvent =
      const EventStreamProvider<Event>('invalid');

  @DomName('GlobalEventHandlers.keydownEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<KeyboardEvent> keyDownEvent =
      const EventStreamProvider<KeyboardEvent>('keydown');

  @DomName('GlobalEventHandlers.keypressEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<KeyboardEvent> keyPressEvent =
      const EventStreamProvider<KeyboardEvent>('keypress');

  @DomName('GlobalEventHandlers.keyupEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<KeyboardEvent> keyUpEvent =
      const EventStreamProvider<KeyboardEvent>('keyup');

  @DomName('GlobalEventHandlers.loadEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadEvent =
      const EventStreamProvider<Event>('load');

  @DomName('GlobalEventHandlers.loadeddataEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadedDataEvent =
      const EventStreamProvider<Event>('loadeddata');

  @DomName('GlobalEventHandlers.loadedmetadataEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadedMetadataEvent =
      const EventStreamProvider<Event>('loadedmetadata');

  @DomName('GlobalEventHandlers.mousedownEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseDownEvent =
      const EventStreamProvider<MouseEvent>('mousedown');

  @DomName('GlobalEventHandlers.mouseenterEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseEnterEvent =
      const EventStreamProvider<MouseEvent>('mouseenter');

  @DomName('GlobalEventHandlers.mouseleaveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseLeaveEvent =
      const EventStreamProvider<MouseEvent>('mouseleave');

  @DomName('GlobalEventHandlers.mousemoveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseMoveEvent =
      const EventStreamProvider<MouseEvent>('mousemove');

  @DomName('GlobalEventHandlers.mouseoutEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseOutEvent =
      const EventStreamProvider<MouseEvent>('mouseout');

  @DomName('GlobalEventHandlers.mouseoverEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseOverEvent =
      const EventStreamProvider<MouseEvent>('mouseover');

  @DomName('GlobalEventHandlers.mouseupEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseUpEvent =
      const EventStreamProvider<MouseEvent>('mouseup');

  @DomName('GlobalEventHandlers.mousewheelEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<WheelEvent> mouseWheelEvent =
      const EventStreamProvider<WheelEvent>('mousewheel');

  @DomName('GlobalEventHandlers.pauseEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> pauseEvent =
      const EventStreamProvider<Event>('pause');

  @DomName('GlobalEventHandlers.playEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> playEvent =
      const EventStreamProvider<Event>('play');

  @DomName('GlobalEventHandlers.playingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> playingEvent =
      const EventStreamProvider<Event>('playing');

  @DomName('GlobalEventHandlers.ratechangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> rateChangeEvent =
      const EventStreamProvider<Event>('ratechange');

  @DomName('GlobalEventHandlers.resetEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> resetEvent =
      const EventStreamProvider<Event>('reset');

  @DomName('GlobalEventHandlers.resizeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> resizeEvent =
      const EventStreamProvider<Event>('resize');

  @DomName('GlobalEventHandlers.scrollEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> scrollEvent =
      const EventStreamProvider<Event>('scroll');

  @DomName('GlobalEventHandlers.seekedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> seekedEvent =
      const EventStreamProvider<Event>('seeked');

  @DomName('GlobalEventHandlers.seekingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> seekingEvent =
      const EventStreamProvider<Event>('seeking');

  @DomName('GlobalEventHandlers.selectEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> selectEvent =
      const EventStreamProvider<Event>('select');

  @DomName('GlobalEventHandlers.stalledEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> stalledEvent =
      const EventStreamProvider<Event>('stalled');

  @DomName('GlobalEventHandlers.submitEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> submitEvent =
      const EventStreamProvider<Event>('submit');

  @DomName('GlobalEventHandlers.suspendEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> suspendEvent =
      const EventStreamProvider<Event>('suspend');

  @DomName('GlobalEventHandlers.timeupdateEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> timeUpdateEvent =
      const EventStreamProvider<Event>('timeupdate');

  @DomName('GlobalEventHandlers.touchcancelEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<TouchEvent> touchCancelEvent =
      const EventStreamProvider<TouchEvent>('touchcancel');

  @DomName('GlobalEventHandlers.touchendEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<TouchEvent> touchEndEvent =
      const EventStreamProvider<TouchEvent>('touchend');

  @DomName('GlobalEventHandlers.touchmoveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<TouchEvent> touchMoveEvent =
      const EventStreamProvider<TouchEvent>('touchmove');

  @DomName('GlobalEventHandlers.touchstartEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<TouchEvent> touchStartEvent =
      const EventStreamProvider<TouchEvent>('touchstart');

  @DomName('GlobalEventHandlers.volumechangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> volumeChangeEvent =
      const EventStreamProvider<Event>('volumechange');

  @DomName('GlobalEventHandlers.waitingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> waitingEvent =
      const EventStreamProvider<Event>('waiting');

  @DomName('GlobalEventHandlers.onabort')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onAbort => abortEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onblur')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onBlur => blurEvent.forTarget(this);

  @DomName('GlobalEventHandlers.oncanplay')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onCanPlay => canPlayEvent.forTarget(this);

  @DomName('GlobalEventHandlers.oncanplaythrough')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onCanPlayThrough => canPlayThroughEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onChange => changeEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onclick')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onClick => clickEvent.forTarget(this);

  @DomName('GlobalEventHandlers.oncontextmenu')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onContextMenu => contextMenuEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondblclick')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onDoubleClick => doubleClickEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondrag')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDrag => dragEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondragend')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDragEnd => dragEndEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondragenter')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDragEnter => dragEnterEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondragleave')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDragLeave => dragLeaveEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondragover')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDragOver => dragOverEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondragstart')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDragStart => dragStartEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondrop')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDrop => dropEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondurationchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onDurationChange => durationChangeEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onemptied')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onEmptied => emptiedEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onended')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onEnded => endedEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onerror')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onError => errorEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onfocus')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onFocus => focusEvent.forTarget(this);

  @DomName('GlobalEventHandlers.oninput')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onInput => inputEvent.forTarget(this);

  @DomName('GlobalEventHandlers.oninvalid')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onInvalid => invalidEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onkeydown')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<KeyboardEvent> get onKeyDown => keyDownEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onkeypress')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<KeyboardEvent> get onKeyPress => keyPressEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onkeyup')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<KeyboardEvent> get onKeyUp => keyUpEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onload')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onLoad => loadEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onloadeddata')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onLoadedData => loadedDataEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onloadedmetadata')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onLoadedMetadata => loadedMetadataEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmousedown')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseDown => mouseDownEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseEnter => mouseEnterEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseLeave => mouseLeaveEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmousemove')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseMove => mouseMoveEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmouseout')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseOut => mouseOutEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmouseover')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseOver => mouseOverEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmouseup')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseUp => mouseUpEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmousewheel')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<WheelEvent> get onMouseWheel => mouseWheelEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onpause')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onPause => pauseEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onplay')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onPlay => playEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onplaying')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onPlaying => playingEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onratechange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onRateChange => rateChangeEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onreset')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onReset => resetEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onResize => resizeEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onscroll')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onScroll => scrollEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onseeked')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSeeked => seekedEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onseeking')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSeeking => seekingEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onselect')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSelect => selectEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onstalled')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onStalled => stalledEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onsubmit')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSubmit => submitEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onsuspend')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSuspend => suspendEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ontimeupdate')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onTimeUpdate => timeUpdateEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ontouchcancel')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<TouchEvent> get onTouchCancel => touchCancelEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ontouchend')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<TouchEvent> get onTouchEnd => touchEndEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ontouchmove')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<TouchEvent> get onTouchMove => touchMoveEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ontouchstart')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<TouchEvent> get onTouchStart => touchStartEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onvolumechange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onVolumeChange => volumeChangeEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onwaiting')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onWaiting => waitingEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
/**
 * An `<hr>` tag.
 */
@DomName('HTMLHRElement')
@Native("HTMLHRElement")
class HRElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory HRElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLHRElement.HTMLHRElement')
  @DocsEditable()
  factory HRElement() => JS('returns:HRElement;creates:HRElement;new:true',
      '#.createElement(#)', document, "hr");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  HRElement.created() : super.created();

  @DomName('HTMLHRElement.color')
  @DocsEditable()
  @Experimental() // untriaged
  String color;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('HashChangeEvent')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
@Native("HashChangeEvent")
class HashChangeEvent extends Event {
  factory HashChangeEvent(String type,
      {bool canBubble: true,
      bool cancelable: true,
      String oldUrl,
      String newUrl}) {
    var options = {
      'canBubble': canBubble,
      'cancelable': cancelable,
      'oldURL': oldUrl,
      'newURL': newUrl,
    };
    return JS('HashChangeEvent', 'new HashChangeEvent(#, #)', type,
        convertDartToNative_Dictionary(options));
  }

  @DomName('HashChangeEvent.HashChangeEvent')
  @DocsEditable()
  factory HashChangeEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return HashChangeEvent._create_1(type, eventInitDict_1);
    }
    return HashChangeEvent._create_2(type);
  }
  static HashChangeEvent _create_1(type, eventInitDict) =>
      JS('HashChangeEvent', 'new HashChangeEvent(#,#)', type, eventInitDict);
  static HashChangeEvent _create_2(type) =>
      JS('HashChangeEvent', 'new HashChangeEvent(#)', type);

  /// 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;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLHeadElement')
@Native("HTMLHeadElement")
class HeadElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory HeadElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLHeadElement.HTMLHeadElement')
  @DocsEditable()
  factory HeadElement() => JS(
      'returns:HeadElement;creates:HeadElement;new:true',
      '#.createElement(#)',
      document,
      "head");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  HeadElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('Headers')
@Experimental() // untriaged
@Native("Headers")
class Headers extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Headers._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Headers.Headers')
  @DocsEditable()
  factory Headers([input]) {
    if (input == null) {
      return Headers._create_1();
    }
    if ((input is Headers)) {
      return Headers._create_2(input);
    }
    if ((input is Map)) {
      var input_1 = convertDartToNative_Dictionary(input);
      return Headers._create_3(input_1);
    }
    if ((input is List<Object>)) {
      return Headers._create_4(input);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static Headers _create_1() => JS('Headers', 'new Headers()');
  static Headers _create_2(input) => JS('Headers', 'new Headers(#)', input);
  static Headers _create_3(input) => JS('Headers', 'new Headers(#)', input);
  static Headers _create_4(input) => JS('Headers', 'new Headers(#)', input);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLHeadingElement')
@Native("HTMLHeadingElement")
class HeadingElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory HeadingElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h1() => JS(
      'returns:HeadingElement;creates:HeadingElement;new:true',
      '#.createElement(#)',
      document,
      "h1");

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h2() => JS(
      'returns:HeadingElement;creates:HeadingElement;new:true',
      '#.createElement(#)',
      document,
      "h2");

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h3() => JS(
      'returns:HeadingElement;creates:HeadingElement;new:true',
      '#.createElement(#)',
      document,
      "h3");

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h4() => JS(
      'returns:HeadingElement;creates:HeadingElement;new:true',
      '#.createElement(#)',
      document,
      "h4");

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h5() => JS(
      'returns:HeadingElement;creates:HeadingElement;new:true',
      '#.createElement(#)',
      document,
      "h5");

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h6() => JS(
      'returns:HeadingElement;creates:HeadingElement;new:true',
      '#.createElement(#)',
      document,
      "h6");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  HeadingElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DomName('History')
@Native("History")
class History extends Interceptor implements HistoryBase {
  /**
   * Checks if the State APIs are supported on the current platform.
   *
   * See also:
   *
   * * [pushState]
   * * [replaceState]
   * * [state]
   */
  static bool get supportsState => JS('bool', '!!window.history.pushState');
  // To suppress missing implicit constructor warnings.
  factory History._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('History.length')
  @DocsEditable()
  final int length;

  @DomName('History.scrollRestoration')
  @DocsEditable()
  @Experimental() // untriaged
  String scrollRestoration;

  @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 delta]) native;

  @DomName('History.pushState')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void pushState(/*SerializedScriptValue*/ data, String title, String url) {
    var data_1 = convertDartToNative_SerializedScriptValue(data);
    _pushState_1(data_1, title, url);
    return;
  }

  @JSName('pushState')
  @DomName('History.pushState')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void _pushState_1(data, title, url) native;

  @DomName('History.replaceState')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void replaceState(/*SerializedScriptValue*/ data, String title, String url) {
    var data_1 = convertDartToNative_SerializedScriptValue(data);
    _replaceState_1(data_1, title, url);
    return;
  }

  @JSName('replaceState')
  @DomName('History.replaceState')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void _replaceState_1(data, title, 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('HMDVRDevice')
@Experimental() // untriaged
@Native("HMDVRDevice")
class HmdvrDevice extends VRDevice {
  // To suppress missing implicit constructor warnings.
  factory HmdvrDevice._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HMDVRDevice.getEyeParameters')
  @DocsEditable()
  @Experimental() // untriaged
  VREyeParameters getEyeParameters(String whichEye) native;

  @DomName('HMDVRDevice.setFieldOfView')
  @DocsEditable()
  @Experimental() // untriaged
  void setFieldOfView([VRFieldOfView leftFov, VRFieldOfView rightFov]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLCollection')
@Native("HTMLCollection")
class HtmlCollection extends Interceptor
    with ListMixin<Node>, ImmutableListMixin<Node>
    implements JavaScriptIndexingBehavior<Node>, List<Node> {
  // To suppress missing implicit constructor warnings.
  factory HtmlCollection._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLCollection.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  Node operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("Node", "#[#]", this, index);
  }

  void operator []=(int index, Node value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Node> mixins.
  // Node is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Node get first {
    if (this.length > 0) {
      return JS('Node', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Node get last {
    int len = this.length;
    if (len > 0) {
      return JS('Node', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Node get single {
    int len = this.length;
    if (len == 1) {
      return JS('Node', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Node elementAt(int index) => this[index];
  // -- end List<Node> mixins.

  @DomName('HTMLCollection.item')
  @DocsEditable()
  Node item(int index) native;

  @DomName('HTMLCollection.namedItem')
  @DocsEditable()
  Object namedItem(String name) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('HTMLDocument')
@Native("HTMLDocument")
class HtmlDocument extends Document {
  // To suppress missing implicit constructor warnings.
  factory HtmlDocument._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Document.body')
  BodyElement body;

  /// UNSTABLE: Chrome-only - create a Range from the given point.
  @DomName('Document.caretRangeFromPoint')
  @Unstable()
  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) {
    if (HtmlDocument.supportsCssCanvasContext)
      return JS('CanvasRenderingContext', '#.getCSSCanvasContext(#, #, #, #)',
          this, contextId, name, width, height);
    throw new UnsupportedError("Not supported");
  }

  @DomName('Document.head')
  HeadElement get head => _head;

  @DomName('Document.lastModified')
  String get lastModified => _lastModified;

  @DomName('Document.preferredStylesheetSet')
  String get preferredStylesheetSet => _preferredStylesheetSet;

  @DomName('Document.referrer')
  String get referrer => _referrer;

  @DomName('Document.selectedStylesheetSet')
  String get selectedStylesheetSet => _selectedStylesheetSet;
  set selectedStylesheetSet(String value) {
    _selectedStylesheetSet = value;
  }

  @DomName('Document.styleSheets')
  List<StyleSheet> get styleSheets => _styleSheets;

  @DomName('Document.title')
  String get title => _title;

  @DomName('Document.title')
  set title(String value) {
    _title = value;
  }

  /**
   * Returns page to standard layout.
   *
   * Has no effect if the page is not in fullscreen mode.
   *
   * ## Other resources
   *
   * * [Using the fullscreen
   *   API](http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)
   *   from WebPlatform.org.
   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
   */
  @DomName('Document.webkitExitFullscreen')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  void exitFullscreen() {
    _webkitExitFullscreen();
  }

  @Experimental()
  /**
   * Register a custom subclass of Element to be instantiatable by the DOM.
   *
   * This is necessary to allow the construction of any custom elements.
   *
   * The class being registered must either subclass HtmlElement or SvgElement.
   * If they subclass these directly then they can be used as:
   *
   *     class FooElement extends HtmlElement{
   *        void created() {
   *          print('FooElement created!');
   *        }
   *     }
   *
   *     main() {
   *       document.registerElement('x-foo', FooElement);
   *       var myFoo = new Element.tag('x-foo');
   *       // prints 'FooElement created!' to the console.
   *     }
   *
   * The custom element can also be instantiated via HTML using the syntax
   * `<x-foo></x-foo>`
   *
   * Other elements can be subclassed as well:
   *
   *     class BarElement extends InputElement{
   *        void created() {
   *          print('BarElement created!');
   *        }
   *     }
   *
   *     main() {
   *       document.registerElement('x-bar', BarElement);
   *       var myBar = new Element.tag('input', 'x-bar');
   *       // prints 'BarElement created!' to the console.
   *     }
   *
   * This custom element can also be instantiated via HTML using the syntax
   * `<input is="x-bar"></input>`
   *
   */
  void registerElement(String tag, Type customElementClass,
      {String extendsTag}) {
    _registerCustomElement(
        JS('', 'window'), this, tag, customElementClass, extendsTag);
  }

  /** *Deprecated*: use [registerElement] instead. */
  @deprecated
  @Experimental()
  void register(String tag, Type customElementClass, {String extendsTag}) {
    return registerElement(tag, customElementClass, extendsTag: extendsTag);
  }

  /**
   * Static factory designed to expose `visibilitychange` events to event
   * handlers that are not necessarily instances of [Document].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Document.visibilityChange')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @Experimental()
  static const EventStreamProvider<Event> visibilityChangeEvent =
      const _CustomEventStreamProvider<Event>(
          _determineVisibilityChangeEventType);

  static String _determineVisibilityChangeEventType(EventTarget e) {
    if (JS('bool', '(typeof #.hidden !== "undefined")', e)) {
      // Opera 12.10 and Firefox 18 and later support
      return 'visibilitychange';
    } else if (JS('bool', '(typeof #.mozHidden !== "undefined")', e)) {
      return 'mozvisibilitychange';
    } else if (JS('bool', '(typeof #.msHidden !== "undefined")', e)) {
      return 'msvisibilitychange';
    } else if (JS('bool', '(typeof #.webkitHidden !== "undefined")', e)) {
      return 'webkitvisibilitychange';
    }
    return 'visibilitychange';
  }

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @Experimental()
  Stream<Event> get onVisibilityChange => visibilityChangeEvent.forTarget(this);

  /// Creates an element upgrader which can be used to change the Dart wrapper
  /// type for elements.
  ///
  /// The type specified must be a subclass of HtmlElement, when an element is
  /// upgraded then the created constructor will be invoked on that element.
  ///
  /// If the type is not a direct subclass of HtmlElement then the extendsTag
  /// parameter must be provided.
  @Experimental()
  ElementUpgrader createElementUpgrader(Type type, {String extendsTag}) {
    return new _JSElementUpgrader(this, type, extendsTag);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLFormControlsCollection')
@Native("HTMLFormControlsCollection")
class HtmlFormControlsCollection extends HtmlCollection {
  // To suppress missing implicit constructor warnings.
  factory HtmlFormControlsCollection._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLFormControlsCollection.item')
  @DocsEditable()
  @Experimental() // untriaged
  Node item(int index) native;

  @DomName('HTMLFormControlsCollection.namedItem')
  @DocsEditable()
  Object namedItem(String name) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLHtmlElement')
@Native("HTMLHtmlElement")
class HtmlHtmlElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory HtmlHtmlElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLHtmlElement.HTMLHtmlElement')
  @DocsEditable()
  factory HtmlHtmlElement() => JS(
      'returns:HtmlHtmlElement;creates:HtmlHtmlElement;new:true',
      '#.createElement(#)',
      document,
      "html");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  HtmlHtmlElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLOptionsCollection')
@Native("HTMLOptionsCollection")
class HtmlOptionsCollection extends HtmlCollection {
  // To suppress missing implicit constructor warnings.
  factory HtmlOptionsCollection._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('item')
  @DomName('HTMLOptionsCollection.item')
  @DocsEditable()
  @Experimental() // untriaged
  Node _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.

/**
  * A client-side XHR request for getting data from a URL,
  * formally known as XMLHttpRequest.
  *
  * HttpRequest can be used to obtain data from HTTP and FTP protocols,
  * and is useful for AJAX-style page updates.
  *
  * The simplest way to get the contents of a text file, such as a
  * JSON-formatted file, is with [getString].
  * For example, the following code gets the contents of a JSON file
  * and prints its length:
  *
  *     var path = 'myData.json';
  *     HttpRequest.getString(path)
  *         .then((String fileContents) {
  *           print(fileContents.length);
  *         })
  *         .catchError((Error error) {
  *           print(error.toString());
  *         });
  *
  * ## Fetching data from other servers
  *
  * For security reasons, browsers impose restrictions on requests
  * made by embedded apps.
  * With the default behavior of this class,
  * the code making the request must be served from the same origin
  * (domain name, port, and application layer protocol)
  * as the requested resource.
  * In the example above, the myData.json file must be co-located with the
  * app that uses it.
  * You might be able to
  * [get around this restriction](http://www.dartlang.org/articles/json-web-service/#a-note-on-cors-and-httprequest)
  * by using CORS headers or JSONP.
  *
  * ## Other resources
  *
  * * [Fetch Data Dynamically](https://www.dartlang.org/docs/tutorials/fetchdata/),
  * a tutorial from _A Game of Darts_,
  * shows two different ways to use HttpRequest to get a JSON file.
  * * [Get Input from a Form](https://www.dartlang.org/docs/tutorials/forms/),
  * another tutorial from _A Game of Darts_,
  * shows using HttpRequest with a custom server.
  * * [Dart article on using HttpRequests](http://www.dartlang.org/articles/json-web-service/#getting-data)
  * * [JS XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest)
  * * [Using XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest)
 */
@DomName('XMLHttpRequest')
@Native("XMLHttpRequest")
class HttpRequest extends HttpRequestEventTarget {
  /**
   * Creates a GET request for the specified [url].
   *
   * The server response must be a `text/` mime type for this request to
   * succeed.
   *
   * This is similar to [request] but specialized for HTTP GET requests which
   * return text content.
   *
   * To add query parameters, append them to the [url] following a `?`,
   * joining each key to its value with `=` and separating key-value pairs with
   * `&`.
   *
   *     var name = Uri.encodeQueryComponent('John');
   *     var id = Uri.encodeQueryComponent('42');
   *     HttpRequest.getString('users.json?name=$name&id=$id')
   *       .then((HttpRequest resp) {
   *         // Do something with the response.
   *     });
   *
   * See also:
   *
   * * [request]
   */
  static Future<String> getString(String url,
      {bool withCredentials, void onProgress(ProgressEvent e)}) {
    return request(url,
            withCredentials: withCredentials, onProgress: onProgress)
        .then((HttpRequest xhr) => xhr.responseText);
  }

  /**
   * Makes a server POST request with the specified data encoded as form data.
   *
   * This is roughly the POST equivalent of getString. This method is similar
   * to sending a FormData object with broader browser support but limited to
   * String values.
   *
   * If [data] is supplied, the key/value pairs are URI encoded with
   * [Uri.encodeQueryComponent] and converted into an HTTP query string.
   *
   * Unless otherwise specified, this method appends the following header:
   *
   *     Content-Type: application/x-www-form-urlencoded; charset=UTF-8
   *
   * Here's an example of using this method:
   *
   *     var data = { 'firstName' : 'John', 'lastName' : 'Doe' };
   *     HttpRequest.postFormData('/send', data).then((HttpRequest resp) {
   *       // Do something with the response.
   *     });
   *
   * See also:
   *
   * * [request]
   */
  static Future<HttpRequest> postFormData(String url, Map<String, String> data,
      {bool withCredentials,
      String responseType,
      Map<String, String> requestHeaders,
      void onProgress(ProgressEvent e)}) {
    var parts = [];
    data.forEach((key, value) {
      parts.add('${Uri.encodeQueryComponent(key)}='
          '${Uri.encodeQueryComponent(value)}');
    });
    var formData = parts.join('&');

    if (requestHeaders == null) {
      requestHeaders = <String, String>{};
    }
    requestHeaders.putIfAbsent('Content-Type',
        () => 'application/x-www-form-urlencoded; charset=UTF-8');

    return request(url,
        method: 'POST',
        withCredentials: withCredentials,
        responseType: responseType,
        requestHeaders: requestHeaders,
        sendData: formData,
        onProgress: onProgress);
  }

  /**
   * Creates and sends a URL request for the specified [url].
   *
   * By default `request` will perform an HTTP GET request, but a different
   * method (`POST`, `PUT`, `DELETE`, etc) can be used by specifying the
   * [method] parameter. (See also [HttpRequest.postFormData] for `POST` 
   * requests only.
   *
   * The Future is completed when the response is available.
   *
   * If specified, `sendData` will send data in the form of a [ByteBuffer],
   * [Blob], [Document], [String], or [FormData] along with the HttpRequest.
   *
   * If specified, [responseType] sets the desired response format for the
   * request. By default it is [String], but can also be 'arraybuffer', 'blob', 
   * 'document', 'json', or 'text'. See also [HttpRequest.responseType] 
   * for more information.
   *
   * The [withCredentials] parameter specified that credentials such as a cookie
   * (already) set in the header or
   * [authorization headers](http://tools.ietf.org/html/rfc1945#section-10.2)
   * should be specified for the request. Details to keep in mind when using
   * credentials:
   *
   * * Using credentials is only useful for cross-origin requests.
   * * The `Access-Control-Allow-Origin` header of `url` cannot contain a wildcard (*).
   * * The `Access-Control-Allow-Credentials` header of `url` must be set to true.
   * * If `Access-Control-Expose-Headers` has not been set to true, only a subset of all the response headers will be returned when calling [getAllRequestHeaders].
   *
   * The following is equivalent to the [getString] sample above:
   *
   *     var name = Uri.encodeQueryComponent('John');
   *     var id = Uri.encodeQueryComponent('42');
   *     HttpRequest.request('users.json?name=$name&id=$id')
   *       .then((HttpRequest resp) {
   *         // Do something with the response.
   *     });
   *
   * Here's an example of submitting an entire form with [FormData].
   *
   *     var myForm = querySelector('form#myForm');
   *     var data = new FormData(myForm);
   *     HttpRequest.request('/submit', method: 'POST', sendData: data)
   *       .then((HttpRequest resp) {
   *         // Do something with the response.
   *     });
   *
   * Note that requests for file:// URIs are only supported by Chrome extensions
   * with appropriate permissions in their manifest. Requests to file:// URIs
   * will also never fail- the Future will always complete successfully, even
   * when the file cannot be found.
   *
   * See also: [authorization headers](http://en.wikipedia.org/wiki/Basic_access_authentication).
   */
  static Future<HttpRequest> request(String url,
      {String method,
      bool withCredentials,
      String responseType,
      String mimeType,
      Map<String, String> requestHeaders,
      sendData,
      void onProgress(ProgressEvent e)}) {
    var completer = new Completer<HttpRequest>();

    var xhr = new HttpRequest();
    if (method == null) {
      method = 'GET';
    }
    xhr.open(method, url, async: true);

    if (withCredentials != null) {
      xhr.withCredentials = withCredentials;
    }

    if (responseType != null) {
      xhr.responseType = responseType;
    }

    if (mimeType != null) {
      xhr.overrideMimeType(mimeType);
    }

    if (requestHeaders != null) {
      requestHeaders.forEach((header, value) {
        xhr.setRequestHeader(header, value);
      });
    }

    if (onProgress != null) {
      xhr.onProgress.listen(onProgress);
    }

    xhr.onLoad.listen((e) {
      var accepted = xhr.status >= 200 && xhr.status < 300;
      var fileUri = xhr.status == 0; // file:// URIs have status of 0.
      var notModified = xhr.status == 304;
      // Redirect status is specified up to 307, but others have been used in
      // practice. Notably Google Drive uses 308 Resume Incomplete for
      // resumable uploads, and it's also been used as a redirect. The
      // redirect case will be handled by the browser before it gets to us,
      // so if we see it we should pass it through to the user.
      var unknownRedirect = xhr.status > 307 && xhr.status < 400;

      if (accepted || fileUri || notModified || unknownRedirect) {
        completer.complete(xhr);
      } else {
        completer.completeError(e);
      }
    });

    xhr.onError.listen(completer.completeError);

    if (sendData != null) {
      xhr.send(sendData);
    } else {
      xhr.send();
    }

    return completer.future;
  }

  /**
   * Checks to see if the Progress event is supported on the current platform.
   */
  static bool get supportsProgressEvent {
    var xhr = new HttpRequest();
    return JS('bool', '("onprogress" in #)', xhr);
  }

  /**
   * Checks to see if the current platform supports making cross origin
   * requests.
   *
   * Note that even if cross origin requests are supported, they still may fail
   * if the destination server does not support CORS requests.
   */
  static bool get supportsCrossOrigin {
    var xhr = new HttpRequest();
    return JS('bool', '("withCredentials" in #)', xhr);
  }

  /**
   * Checks to see if the LoadEnd event is supported on the current platform.
   */
  static bool get supportsLoadEndEvent {
    var xhr = new HttpRequest();
    return JS('bool', '("onloadend" in #)', xhr);
  }

  /**
   * Checks to see if the overrideMimeType method is supported on the current
   * platform.
   */
  static bool get supportsOverrideMimeType {
    var xhr = new HttpRequest();
    return JS('bool', '("overrideMimeType" in #)', xhr);
  }

  /**
   * Makes a cross-origin request to the specified URL.
   *
   * This API provides a subset of [request] which works on IE9. If IE9
   * cross-origin support is not required then [request] should be used instead.
   */
  @Experimental()
  static Future<String> requestCrossOrigin(String url,
      {String method, String sendData}) {
    if (supportsCrossOrigin) {
      return request(url, method: method, sendData: sendData).then((xhr) {
        return xhr.responseText;
      });
    }
    var completer = new Completer<String>();
    if (method == null) {
      method = 'GET';
    }
    var xhr = JS('var', 'new XDomainRequest()');
    JS('', '#.open(#, #)', xhr, method, url);
    JS(
        '',
        '#.onload = #',
        xhr,
        convertDartClosureToJS((e) {
          var response = JS('String', '#.responseText', xhr);
          completer.complete(response);
        }, 1));
    JS(
        '',
        '#.onerror = #',
        xhr,
        convertDartClosureToJS((e) {
          completer.completeError(e);
        }, 1));

    // IE9 RTM - XDomainRequest issued requests may abort if all event handlers
    // not specified
    // http://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified
    JS('', '#.onprogress = {}', xhr);
    JS('', '#.ontimeout = {}', xhr);
    JS('', '#.timeout = Number.MAX_VALUE', xhr);

    if (sendData != null) {
      JS('', '#.send(#)', xhr, sendData);
    } else {
      JS('', '#.send()', xhr);
    }

    return completer.future;
  }

  /**
   * Returns all response headers as a key-value map.
   *
   * Multiple values for the same header key can be combined into one,
   * separated by a comma and a space.
   *
   * See: http://www.w3.org/TR/XMLHttpRequest/#the-getresponseheader()-method
   */
  Map<String, String> get responseHeaders {
    // from Closure's goog.net.Xhrio.getResponseHeaders.
    var headers = <String, String>{};
    var headersString = this.getAllResponseHeaders();
    if (headersString == null) {
      return headers;
    }
    var headersList = headersString.split('\r\n');
    for (var header in headersList) {
      if (header.isEmpty) {
        continue;
      }

      var splitIdx = header.indexOf(': ');
      if (splitIdx == -1) {
        continue;
      }
      var key = header.substring(0, splitIdx).toLowerCase();
      var value = header.substring(splitIdx + 2);
      if (headers.containsKey(key)) {
        headers[key] = '${headers[key]}, $value';
      } else {
        headers[key] = value;
      }
    }
    return headers;
  }

  /**
   * Specify the desired `url`, and `method` to use in making the request.
   *
   * By default the request is done asyncronously, with no user or password
   * authentication information. If `async` is false, the request will be send
   * synchronously.
   *
   * Calling `open` again on a currently active request is equivalent to
   * calling `abort`.
   *
   * Note: Most simple HTTP requests can be accomplished using the [getString],
   * [request], [requestCrossOrigin], or [postFormData] methods. Use of this
   * `open` method is intended only for more complex HTTP requests where
   * finer-grained control is needed.
   */
  @DomName('XMLHttpRequest.open')
  @DocsEditable()
  void open(String method, String url,
      {bool async, String user, String password}) native;

  // To suppress missing implicit constructor warnings.
  factory HttpRequest._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `readystatechange` events to event
   * handlers that are not necessarily instances of [HttpRequest].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequest.readystatechangeEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> readyStateChangeEvent =
      const EventStreamProvider<ProgressEvent>('readystatechange');

  /**
   * General constructor for any type of request (GET, POST, etc).
   *
   * This call is used in conjunction with [open]:
   *
   *     var request = new HttpRequest();
   *     request.open('GET', 'http://dartlang.org');
   *     request.onLoad.listen((event) => print(
   *         'Request complete ${event.target.reponseText}'));
   *     request.send();
   *
   * is the (more verbose) equivalent of
   *
   *     HttpRequest.getString('http://dartlang.org').then(
   *         (result) => print('Request complete: $result'));
   */
  @DomName('XMLHttpRequest.XMLHttpRequest')
  @DocsEditable()
  factory HttpRequest() {
    return HttpRequest._create_1();
  }
  static HttpRequest _create_1() => JS('HttpRequest', 'new XMLHttpRequest()');

  @DomName('XMLHttpRequest.DONE')
  @DocsEditable()
  static const int DONE = 4;

  @DomName('XMLHttpRequest.HEADERS_RECEIVED')
  @DocsEditable()
  static const int HEADERS_RECEIVED = 2;

  @DomName('XMLHttpRequest.LOADING')
  @DocsEditable()
  static const int LOADING = 3;

  @DomName('XMLHttpRequest.OPENED')
  @DocsEditable()
  static const int OPENED = 1;

  @DomName('XMLHttpRequest.UNSENT')
  @DocsEditable()
  static const int UNSENT = 0;

  /**
   * Indicator of the current state of the request:
   *
   * <table>
   *   <tr>
   *     <td>Value</td>
   *     <td>State</td>
   *     <td>Meaning</td>
   *   </tr>
   *   <tr>
   *     <td>0</td>
   *     <td>unsent</td>
   *     <td><code>open()</code> has not yet been called</td>
   *   </tr>
   *   <tr>
   *     <td>1</td>
   *     <td>opened</td>
   *     <td><code>send()</code> has not yet been called</td>
   *   </tr>
   *   <tr>
   *     <td>2</td>
   *     <td>headers received</td>
   *     <td><code>sent()</code> has been called; response headers and <code>status</code> are available</td>
   *   </tr>
   *   <tr>
   *     <td>3</td> <td>loading</td> <td><code>responseText</code> holds some data</td>
   *   </tr>
   *   <tr>
   *     <td>4</td> <td>done</td> <td>request is complete</td>
   *   </tr>
   * </table>
   */
  @DomName('XMLHttpRequest.readyState')
  @DocsEditable()
  final int readyState;

  /**
   * The data received as a reponse from the request.
   *
   * The data could be in the
   * form of a [String], [ByteBuffer], [Document], [Blob], or json (also a
   * [String]). `null` indicates request failure.
   */
  @DomName('XMLHttpRequest.response')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  dynamic get response => _convertNativeToDart_XHR_Response(this._get_response);
  @JSName('response')
  /**
   * The data received as a reponse from the request.
   *
   * The data could be in the
   * form of a [String], [ByteBuffer], [Document], [Blob], or json (also a
   * [String]). `null` indicates request failure.
   */
  @DomName('XMLHttpRequest.response')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Creates(
      'NativeByteBuffer|Blob|Document|=Object|JSExtendableArray|String|num')
  final dynamic _get_response;

  /**
   * The response in String form or empty String on failure.
   */
  @DomName('XMLHttpRequest.responseText')
  @DocsEditable()
  final String responseText;

  /**
   * [String] telling the server the desired response format.
   *
   * Default is `String`.
   * Other options are one of 'arraybuffer', 'blob', 'document', 'json',
   * 'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if
   * `responseType` is set while performing a synchronous request.
   *
   * See also: [MDN
   * responseType](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-responsetype)
   */
  @DomName('XMLHttpRequest.responseType')
  @DocsEditable()
  String responseType;

  @JSName('responseURL')
  @DomName('XMLHttpRequest.responseURL')
  @DocsEditable()
  @Experimental() // untriaged
  final String responseUrl;

  @JSName('responseXML')
  /**
   * The request response, or null on failure.
   *
   * The response is processed as
   * `text/xml` stream, unless responseType = 'document' and the request is
   * synchronous.
   */
  @DomName('XMLHttpRequest.responseXML')
  @DocsEditable()
  final Document responseXml;

  /**
   * The HTTP result code from the request (200, 404, etc).
   * See also: [HTTP Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
   */
  @DomName('XMLHttpRequest.status')
  @DocsEditable()
  final int status;

  /**
   * The request response string (such as \"200 OK\").
   * See also: [HTTP Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
   */
  @DomName('XMLHttpRequest.statusText')
  @DocsEditable()
  final String statusText;

  /**
   * Length of time in milliseconds 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#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_RECEIVED` 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](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields)
   * 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](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields)
   * for a list of common response headers.
   */
  @DomName('XMLHttpRequest.getResponseHeader')
  @DocsEditable()
  @Unstable()
  String getResponseHeader(String name) 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 [IANA Official MIME types](https://www.iana.org/assignments/media-types/media-types.xhtml)
   */
  @DomName('XMLHttpRequest.overrideMimeType')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void overrideMimeType(String mime) 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 complex 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([body_OR_data]) native;

  /**
   * Sets the value of an HTTP request 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/Web/API/XMLHttpRequest#setRequestHeader())
   *   from MDN.
   * * [The setRequestHeader()
   *   method](http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method)
   *   from W3C.
   */
  @DomName('XMLHttpRequest.setRequestHeader')
  @DocsEditable()
  void setRequestHeader(String name, String value) native;

  /// Stream of `readystatechange` events handled by this [HttpRequest].
/**
   * Event listeners to be notified every time the [HttpRequest]
   * object's `readyState` changes values.
   */
  @DomName('XMLHttpRequest.onreadystatechange')
  @DocsEditable()
  Stream<ProgressEvent> get onReadyStateChange =>
      readyStateChangeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('XMLHttpRequestEventTarget')
@Experimental() // untriaged
@Native("XMLHttpRequestEventTarget")
class HttpRequestEventTarget extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory HttpRequestEventTarget._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `abort` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequestEventTarget.abortEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<ProgressEvent> abortEvent =
      const EventStreamProvider<ProgressEvent>('abort');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequestEventTarget.errorEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<ProgressEvent> errorEvent =
      const EventStreamProvider<ProgressEvent>('error');

  /**
   * Static factory designed to expose `load` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequestEventTarget.loadEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<ProgressEvent> loadEvent =
      const EventStreamProvider<ProgressEvent>('load');

  /**
   * Static factory designed to expose `loadend` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequestEventTarget.loadendEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<ProgressEvent> loadEndEvent =
      const EventStreamProvider<ProgressEvent>('loadend');

  /**
   * Static factory designed to expose `loadstart` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequestEventTarget.loadstartEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<ProgressEvent> loadStartEvent =
      const EventStreamProvider<ProgressEvent>('loadstart');

  /**
   * Static factory designed to expose `progress` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequestEventTarget.progressEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<ProgressEvent> progressEvent =
      const EventStreamProvider<ProgressEvent>('progress');

  /**
   * Static factory designed to expose `timeout` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequestEventTarget.timeoutEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<ProgressEvent> timeoutEvent =
      const EventStreamProvider<ProgressEvent>('timeout');

  /// Stream of `abort` events handled by this [HttpRequestEventTarget].
  @DomName('XMLHttpRequestEventTarget.onabort')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);

  /// Stream of `error` events handled by this [HttpRequestEventTarget].
  @DomName('XMLHttpRequestEventTarget.onerror')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<ProgressEvent> get onError => errorEvent.forTarget(this);

  /// Stream of `load` events handled by this [HttpRequestEventTarget].
  @DomName('XMLHttpRequestEventTarget.onload')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<ProgressEvent> get onLoad => loadEvent.forTarget(this);

  /// Stream of `loadend` events handled by this [HttpRequestEventTarget].
  @DomName('XMLHttpRequestEventTarget.onloadend')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental() // untriaged
  Stream<ProgressEvent> get onLoadEnd => loadEndEvent.forTarget(this);

  /// Stream of `loadstart` events handled by this [HttpRequestEventTarget].
  @DomName('XMLHttpRequestEventTarget.onloadstart')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<ProgressEvent> get onLoadStart => loadStartEvent.forTarget(this);

  /// Stream of `progress` events handled by this [HttpRequestEventTarget].
  @DomName('XMLHttpRequestEventTarget.onprogress')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental() // untriaged
  Stream<ProgressEvent> get onProgress => progressEvent.forTarget(this);

  /// Stream of `timeout` events handled by this [HttpRequestEventTarget].
  @DomName('XMLHttpRequestEventTarget.ontimeout')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<ProgressEvent> get onTimeout => timeoutEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('XMLHttpRequestUpload')
// http://xhr.spec.whatwg.org/#xmlhttprequestupload
@Experimental()
@Native("XMLHttpRequestUpload")
class HttpRequestUpload extends HttpRequestEventTarget {
  // To suppress missing implicit constructor warnings.
  factory HttpRequestUpload._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLIFrameElement')
@Native("HTMLIFrameElement")
class IFrameElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory IFrameElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLIFrameElement.HTMLIFrameElement')
  @DocsEditable()
  factory IFrameElement() => JS(
      'returns:IFrameElement;creates:IFrameElement;new:true',
      '#.createElement(#)',
      document,
      "iframe");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  IFrameElement.created() : super.created();

  @DomName('HTMLIFrameElement.allowFullscreen')
  @DocsEditable()
  @Experimental() // untriaged
  bool allowFullscreen;

  @DomName('HTMLIFrameElement.contentWindow')
  @DocsEditable()
  WindowBase get contentWindow =>
      _convertNativeToDart_Window(this._get_contentWindow);
  @JSName('contentWindow')
  @DomName('HTMLIFrameElement.contentWindow')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_contentWindow;

  @DomName('HTMLIFrameElement.height')
  @DocsEditable()
  String height;

  @DomName('HTMLIFrameElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLIFrameElement.referrerpolicy')
  @DocsEditable()
  @Experimental() // untriaged
  String referrerpolicy;

  @DomName('HTMLIFrameElement.sandbox')
  @DocsEditable()
  final DomTokenList 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('IdleDeadline')
@Experimental() // untriaged
@Native("IdleDeadline")
class IdleDeadline extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory IdleDeadline._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('IdleDeadline.didTimeout')
  @DocsEditable()
  @Experimental() // untriaged
  final bool didTimeout;

  @DomName('IdleDeadline.timeRemaining')
  @DocsEditable()
  @Experimental() // untriaged
  double timeRemaining() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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('IdleRequestCallback')
@Experimental() // untriaged
typedef void IdleRequestCallback(IdleDeadline deadline);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('ImageBitmap')
@Experimental() // untriaged
@Native("ImageBitmap")
class ImageBitmap extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ImageBitmap._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('ImageBitmap.height')
  @DocsEditable()
  @Experimental() // untriaged
  final int height;

  @DomName('ImageBitmap.width')
  @DocsEditable()
  @Experimental() // untriaged
  final int width;

  @DomName('ImageBitmap.close')
  @DocsEditable()
  @Experimental() // untriaged
  void close() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('ImageBitmapRenderingContext')
@Experimental() // untriaged
@Native("ImageBitmapRenderingContext")
class ImageBitmapRenderingContext extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ImageBitmapRenderingContext._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('ImageBitmapRenderingContext.canvas')
  @DocsEditable()
  @Experimental() // untriaged
  final CanvasElement canvas;

  @DomName('ImageBitmapRenderingContext.transferImageBitmap')
  @DocsEditable()
  @Experimental() // untriaged
  void transferImageBitmap(ImageBitmap bitmap) 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('ImageData')
@Native("ImageData")
class ImageData extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ImageData._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('ImageData.ImageData')
  @DocsEditable()
  factory ImageData(data_OR_sw, int sh_OR_sw, [int sh]) {
    if ((sh_OR_sw is int) && (data_OR_sw is int) && sh == null) {
      return ImageData._create_1(data_OR_sw, sh_OR_sw);
    }
    if ((sh_OR_sw is int) && (data_OR_sw is Uint8ClampedList) && sh == null) {
      return ImageData._create_2(data_OR_sw, sh_OR_sw);
    }
    if ((sh is int) && (sh_OR_sw is int) && (data_OR_sw is Uint8ClampedList)) {
      return ImageData._create_3(data_OR_sw, sh_OR_sw, sh);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static ImageData _create_1(data_OR_sw, sh_OR_sw) =>
      JS('ImageData', 'new ImageData(#,#)', data_OR_sw, sh_OR_sw);
  static ImageData _create_2(data_OR_sw, sh_OR_sw) =>
      JS('ImageData', 'new ImageData(#,#)', data_OR_sw, sh_OR_sw);
  static ImageData _create_3(data_OR_sw, sh_OR_sw, sh) =>
      JS('ImageData', 'new ImageData(#,#,#)', data_OR_sw, sh_OR_sw, sh);

  @DomName('ImageData.data')
  @DocsEditable()
  @Creates('NativeUint8ClampedList')
  @Returns('NativeUint8ClampedList')
  final Uint8ClampedList data;

  @DomName('ImageData.height')
  @DocsEditable()
  final int height;

  @DomName('ImageData.width')
  @DocsEditable()
  final int width;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DomName('HTMLImageElement')
@Native("HTMLImageElement")
class ImageElement extends HtmlElement implements CanvasImageSource {
  // To suppress missing implicit constructor warnings.
  factory ImageElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLImageElement.HTMLImageElement')
  @DocsEditable()
  factory ImageElement({String src, int width, int height}) {
    ImageElement e = JS('returns:ImageElement;creates:ImageElement;new:true',
        '#.createElement(#)', document, "img");
    if (src != null) e.src = src;
    if (width != null) e.width = width;
    if (height != null) e.height = height;
    return e;
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ImageElement.created() : super.created();

  @DomName('HTMLImageElement.alt')
  @DocsEditable()
  String alt;

  @DomName('HTMLImageElement.complete')
  @DocsEditable()
  final bool complete;

  @DomName('HTMLImageElement.crossOrigin')
  @DocsEditable()
  String crossOrigin;

  @DomName('HTMLImageElement.currentSrc')
  @DocsEditable()
  @Experimental() // untriaged
  final String currentSrc;

  @DomName('HTMLImageElement.height')
  @DocsEditable()
  int height;

  @DomName('HTMLImageElement.isMap')
  @DocsEditable()
  bool isMap;

  @DomName('HTMLImageElement.naturalHeight')
  @DocsEditable()
  final int naturalHeight;

  @DomName('HTMLImageElement.naturalWidth')
  @DocsEditable()
  final int naturalWidth;

  @DomName('HTMLImageElement.referrerpolicy')
  @DocsEditable()
  @Experimental() // untriaged
  String referrerpolicy;

  @DomName('HTMLImageElement.sizes')
  @DocsEditable()
  @Experimental() // untriaged
  String sizes;

  @DomName('HTMLImageElement.src')
  @DocsEditable()
  String src;

  @DomName('HTMLImageElement.srcset')
  @DocsEditable()
  @Experimental() // untriaged
  String srcset;

  @DomName('HTMLImageElement.useMap')
  @DocsEditable()
  String useMap;

  @DomName('HTMLImageElement.width')
  @DocsEditable()
  int width;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('InjectedScriptHost')
@Experimental() // untriaged
@Native("InjectedScriptHost")
class InjectedScriptHost extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory InjectedScriptHost._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('InjectedScriptHost.inspect')
  @DocsEditable()
  @Experimental() // untriaged
  void inspect(Object objectId, Object hints) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('InputDeviceCapabilities')
@Experimental() // untriaged
@Native("InputDeviceCapabilities")
class InputDeviceCapabilities extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory InputDeviceCapabilities._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('InputDeviceCapabilities.InputDeviceCapabilities')
  @DocsEditable()
  factory InputDeviceCapabilities([Map deviceInitDict]) {
    if (deviceInitDict != null) {
      var deviceInitDict_1 = convertDartToNative_Dictionary(deviceInitDict);
      return InputDeviceCapabilities._create_1(deviceInitDict_1);
    }
    return InputDeviceCapabilities._create_2();
  }
  static InputDeviceCapabilities _create_1(deviceInitDict) => JS(
      'InputDeviceCapabilities',
      'new InputDeviceCapabilities(#)',
      deviceInitDict);
  static InputDeviceCapabilities _create_2() =>
      JS('InputDeviceCapabilities', 'new InputDeviceCapabilities()');

  @DomName('InputDeviceCapabilities.firesTouchEvents')
  @DocsEditable()
  @Experimental() // untriaged
  final bool firesTouchEvents;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DomName('HTMLInputElement')
@Native("HTMLInputElement")
class InputElement extends HtmlElement
    implements
        HiddenInputElement,
        SearchInputElement,
        TextInputElement,
        UrlInputElement,
        TelephoneInputElement,
        EmailInputElement,
        PasswordInputElement,
        DateInputElement,
        MonthInputElement,
        WeekInputElement,
        TimeInputElement,
        LocalDateTimeInputElement,
        NumberInputElement,
        RangeInputElement,
        CheckboxInputElement,
        RadioButtonInputElement,
        FileUploadInputElement,
        SubmitButtonInputElement,
        ImageButtonInputElement,
        ResetButtonInputElement,
        ButtonInputElement {
  factory InputElement({String type}) {
    InputElement e = document.createElement("input");
    if (type != null) {
      try {
        // IE throws an exception for unknown types.
        e.type = type;
      } catch (_) {}
    }
    return e;
  }

  // To suppress missing implicit constructor warnings.
  factory InputElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  InputElement.created() : super.created();

  @DomName('HTMLInputElement.accept')
  @DocsEditable()
  String accept;

  @DomName('HTMLInputElement.alt')
  @DocsEditable()
  String alt;

  @DomName('HTMLInputElement.autocapitalize')
  @DocsEditable()
  @Experimental() // untriaged
  String autocapitalize;

  @DomName('HTMLInputElement.autocomplete')
  @DocsEditable()
  String autocomplete;

  @DomName('HTMLInputElement.autofocus')
  @DocsEditable()
  bool autofocus;

  @DomName('HTMLInputElement.capture')
  @DocsEditable()
  @Experimental() // untriaged
  bool capture;

  @DomName('HTMLInputElement.checked')
  @DocsEditable()
  bool checked;

  @DomName('HTMLInputElement.defaultChecked')
  @DocsEditable()
  bool defaultChecked;

  @DomName('HTMLInputElement.defaultValue')
  @DocsEditable()
  String defaultValue;

  @DomName('HTMLInputElement.dirName')
  @DocsEditable()
  String dirName;

  @DomName('HTMLInputElement.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('HTMLInputElement.files')
  @DocsEditable()
  @Returns('FileList|Null')
  @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|Null')
  @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.minLength')
  @DocsEditable()
  @Experimental() // untriaged
  int minLength;

  @DomName('HTMLInputElement.multiple')
  @DocsEditable()
  bool multiple;

  @DomName('HTMLInputElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLInputElement.pattern')
  @DocsEditable()
  String pattern;

  @DomName('HTMLInputElement.placeholder')
  @DocsEditable()
  String placeholder;

  @DomName('HTMLInputElement.readOnly')
  @DocsEditable()
  bool readOnly;

  @DomName('HTMLInputElement.required')
  @DocsEditable()
  bool required;

  @DomName('HTMLInputElement.selectionDirection')
  @DocsEditable()
  String selectionDirection;

  @DomName('HTMLInputElement.selectionEnd')
  @DocsEditable()
  int selectionEnd;

  @DomName('HTMLInputElement.selectionStart')
  @DocsEditable()
  int selectionStart;

  @DomName('HTMLInputElement.size')
  @DocsEditable()
  int size;

  @DomName('HTMLInputElement.src')
  @DocsEditable()
  String src;

  @DomName('HTMLInputElement.step')
  @DocsEditable()
  String step;

  @DomName('HTMLInputElement.type')
  @DocsEditable()
  String type;

  @DomName('HTMLInputElement.validationMessage')
  @DocsEditable()
  final String validationMessage;

  @DomName('HTMLInputElement.validity')
  @DocsEditable()
  final ValidityState validity;

  @DomName('HTMLInputElement.value')
  @DocsEditable()
  String value;

  @DomName('HTMLInputElement.valueAsDate')
  @DocsEditable()
  DateTime get valueAsDate =>
      convertNativeToDart_DateTime(this._get_valueAsDate);
  @JSName('valueAsDate')
  @DomName('HTMLInputElement.valueAsDate')
  @DocsEditable()
  @Creates('Null')
  final dynamic _get_valueAsDate;

  set valueAsDate(DateTime value) {
    this._set_valueAsDate = convertDartToNative_DateTime(value);
  }

  set _set_valueAsDate(/*dynamic*/ value) {
    JS("void", "#.valueAsDate = #", this, value);
  }

  @DomName('HTMLInputElement.valueAsNumber')
  @DocsEditable()
  num valueAsNumber;

  @JSName('webkitEntries')
  @DomName('HTMLInputElement.webkitEntries')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#concept-input-type-file-selected
  final List<Entry> entries;

  @JSName('webkitdirectory')
  @DomName('HTMLInputElement.webkitdirectory')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://plus.sandbox.google.com/+AddyOsmani/posts/Dk5UhZ6zfF3
  bool directory;

  @DomName('HTMLInputElement.width')
  @DocsEditable()
  int width;

  @DomName('HTMLInputElement.willValidate')
  @DocsEditable()
  final bool willValidate;

  @DomName('HTMLInputElement.checkValidity')
  @DocsEditable()
  bool checkValidity() native;

  @DomName('HTMLInputElement.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() native;

  @DomName('HTMLInputElement.select')
  @DocsEditable()
  void select() native;

  @DomName('HTMLInputElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) native;

  @DomName('HTMLInputElement.setRangeText')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#dom-textarea/input-setrangetext
  @Experimental() // experimental
  void setRangeText(String replacement,
      {int start, int end, String selectionMode}) native;

  @DomName('HTMLInputElement.setSelectionRange')
  @DocsEditable()
  void setSelectionRange(int start, int end, [String direction]) native;

  @DomName('HTMLInputElement.stepDown')
  @DocsEditable()
  void stepDown([int n]) native;

  @DomName('HTMLInputElement.stepUp')
  @DocsEditable()
  void stepUp([int n]) native;
}

// Interfaces representing the InputElement APIs which are supported
// for the various types of InputElement. From:
// http://www.w3.org/html/wg/drafts/html/master/forms.html#the-input-element.

/**
 * Exposes the functionality common between all InputElement types.
 */
abstract class InputElementBase implements Element {
  @DomName('HTMLInputElement.autofocus')
  bool autofocus;

  @DomName('HTMLInputElement.disabled')
  bool disabled;

  @DomName('HTMLInputElement.incremental')
  bool incremental;

  @DomName('HTMLInputElement.indeterminate')
  bool indeterminate;

  @DomName('HTMLInputElement.labels')
  List<Node> get labels;

  @DomName('HTMLInputElement.name')
  String name;

  @DomName('HTMLInputElement.validationMessage')
  String get validationMessage;

  @DomName('HTMLInputElement.validity')
  ValidityState get validity;

  @DomName('HTMLInputElement.value')
  String value;

  @DomName('HTMLInputElement.willValidate')
  bool get willValidate;

  @DomName('HTMLInputElement.checkValidity')
  bool checkValidity();

  @DomName('HTMLInputElement.setCustomValidity')
  void setCustomValidity(String error);
}

/**
 * Hidden input which is not intended to be seen or edited by the user.
 */
abstract class HiddenInputElement implements InputElementBase {
  factory HiddenInputElement() => new InputElement(type: 'hidden');
}

/**
 * Base interface for all inputs which involve text editing.
 */
abstract class TextInputElementBase implements InputElementBase {
  @DomName('HTMLInputElement.autocomplete')
  String autocomplete;

  @DomName('HTMLInputElement.maxLength')
  int maxLength;

  @DomName('HTMLInputElement.pattern')
  String pattern;

  @DomName('HTMLInputElement.placeholder')
  String placeholder;

  @DomName('HTMLInputElement.readOnly')
  bool readOnly;

  @DomName('HTMLInputElement.required')
  bool required;

  @DomName('HTMLInputElement.size')
  int size;

  @DomName('HTMLInputElement.select')
  void select();

  @DomName('HTMLInputElement.selectionDirection')
  String selectionDirection;

  @DomName('HTMLInputElement.selectionEnd')
  int selectionEnd;

  @DomName('HTMLInputElement.selectionStart')
  int selectionStart;

  @DomName('HTMLInputElement.setSelectionRange')
  void setSelectionRange(int start, int end, [String direction]);
}

/**
 * Similar to [TextInputElement], but on platforms where search is styled
 * differently this will get the search style.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
abstract class SearchInputElement implements TextInputElementBase {
  factory SearchInputElement() => new InputElement(type: 'search');

  @DomName('HTMLInputElement.dirName')
  String dirName;

  @DomName('HTMLInputElement.list')
  Element get list;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'search')).type == 'search';
  }
}

/**
 * A basic text input editor control.
 */
abstract class TextInputElement implements TextInputElementBase {
  factory TextInputElement() => new InputElement(type: 'text');

  @DomName('HTMLInputElement.dirName')
  String dirName;

  @DomName('HTMLInputElement.list')
  Element get list;
}

/**
 * A control for editing an absolute URL.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
abstract class UrlInputElement implements TextInputElementBase {
  factory UrlInputElement() => new InputElement(type: 'url');

  @DomName('HTMLInputElement.list')
  Element get list;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'url')).type == 'url';
  }
}

/**
 * Represents a control for editing a telephone number.
 *
 * This provides a single line of text with minimal formatting help since
 * there is a wide variety of telephone numbers.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
abstract class TelephoneInputElement implements TextInputElementBase {
  factory TelephoneInputElement() => new InputElement(type: 'tel');

  @DomName('HTMLInputElement.list')
  Element get list;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'tel')).type == 'tel';
  }
}

/**
 * An e-mail address or list of e-mail addresses.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
abstract class EmailInputElement implements TextInputElementBase {
  factory EmailInputElement() => new InputElement(type: 'email');

  @DomName('HTMLInputElement.autocomplete')
  String autocomplete;

  @DomName('HTMLInputElement.autofocus')
  bool autofocus;

  @DomName('HTMLInputElement.list')
  Element get list;

  @DomName('HTMLInputElement.maxLength')
  int maxLength;

  @DomName('HTMLInputElement.multiple')
  bool multiple;

  @DomName('HTMLInputElement.pattern')
  String pattern;

  @DomName('HTMLInputElement.placeholder')
  String placeholder;

  @DomName('HTMLInputElement.readOnly')
  bool readOnly;

  @DomName('HTMLInputElement.required')
  bool required;

  @DomName('HTMLInputElement.size')
  int size;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'email')).type == 'email';
  }
}

/**
 * Text with no line breaks (sensitive information).
 */
abstract class PasswordInputElement implements TextInputElementBase {
  factory PasswordInputElement() => new InputElement(type: 'password');
}

/**
 * Base interface for all input element types which involve ranges.
 */
abstract class RangeInputElementBase implements InputElementBase {
  @DomName('HTMLInputElement.list')
  Element get list;

  @DomName('HTMLInputElement.max')
  String max;

  @DomName('HTMLInputElement.min')
  String min;

  @DomName('HTMLInputElement.step')
  String step;

  @DomName('HTMLInputElement.valueAsNumber')
  num valueAsNumber;

  @DomName('HTMLInputElement.stepDown')
  void stepDown([int n]);

  @DomName('HTMLInputElement.stepUp')
  void stepUp([int n]);
}

/**
 * A date (year, month, day) with no time zone.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
abstract class DateInputElement implements RangeInputElementBase {
  factory DateInputElement() => new InputElement(type: 'date');

  @DomName('HTMLInputElement.valueAsDate')
  DateTime valueAsDate;

  @DomName('HTMLInputElement.readOnly')
  bool readOnly;

  @DomName('HTMLInputElement.required')
  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'date')).type == 'date';
  }
}

/**
 * A date consisting of a year and a month with no time zone.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
abstract class MonthInputElement implements RangeInputElementBase {
  factory MonthInputElement() => new InputElement(type: 'month');

  @DomName('HTMLInputElement.valueAsDate')
  DateTime valueAsDate;

  @DomName('HTMLInputElement.readOnly')
  bool readOnly;

  @DomName('HTMLInputElement.required')
  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'month')).type == 'month';
  }
}

/**
 * A date consisting of a week-year number and a week number with no time zone.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
abstract class WeekInputElement implements RangeInputElementBase {
  factory WeekInputElement() => new InputElement(type: 'week');

  @DomName('HTMLInputElement.valueAsDate')
  DateTime valueAsDate;

  @DomName('HTMLInputElement.readOnly')
  bool readOnly;

  @DomName('HTMLInputElement.required')
  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'week')).type == 'week';
  }
}

/**
 * A time (hour, minute, seconds, fractional seconds) with no time zone.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
abstract class TimeInputElement implements RangeInputElementBase {
  factory TimeInputElement() => new InputElement(type: 'time');

  @DomName('HTMLInputElement.valueAsDate')
  DateTime valueAsDate;

  @DomName('HTMLInputElement.readOnly')
  bool readOnly;

  @DomName('HTMLInputElement.required')
  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'time')).type == 'time';
  }
}

/**
 * A date and time (year, month, day, hour, minute, second, fraction of a
 * second) with no time zone.
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
abstract class LocalDateTimeInputElement implements RangeInputElementBase {
  factory LocalDateTimeInputElement() =>
      new InputElement(type: 'datetime-local');

  @DomName('HTMLInputElement.readOnly')
  bool readOnly;

  @DomName('HTMLInputElement.required')
  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'datetime-local')).type == 'datetime-local';
  }
}

/**
 * A numeric editor control.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
abstract class NumberInputElement implements RangeInputElementBase {
  factory NumberInputElement() => new InputElement(type: 'number');

  @DomName('HTMLInputElement.placeholder')
  String placeholder;

  @DomName('HTMLInputElement.readOnly')
  bool readOnly;

  @DomName('HTMLInputElement.required')
  bool required;

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'number')).type == 'number';
  }
}

/**
 * Similar to [NumberInputElement] but the browser may provide more optimal
 * styling (such as a slider control).
 *
 * Use [supported] to check if this is supported on the current platform.
 */
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE, '10')
@Experimental()
abstract class RangeInputElement implements RangeInputElementBase {
  factory RangeInputElement() => new InputElement(type: 'range');

  /// Returns true if this input type is supported on the current platform.
  static bool get supported {
    return (new InputElement(type: 'range')).type == 'range';
  }
}

/**
 * A boolean editor control.
 *
 * Note that if [indeterminate] is set then this control is in a third
 * indeterminate state.
 */
abstract class CheckboxInputElement implements InputElementBase {
  factory CheckboxInputElement() => new InputElement(type: 'checkbox');

  @DomName('HTMLInputElement.checked')
  bool checked;

  @DomName('HTMLInputElement.required')
  bool required;
}

/**
 * A control that when used with other [ReadioButtonInputElement] controls
 * forms a radio button group in which only one control can be checked at a
 * time.
 *
 * Radio buttons are considered to be in the same radio button group if:
 *
 * * They are all of type 'radio'.
 * * They all have either the same [FormElement] owner, or no owner.
 * * Their name attributes contain the same name.
 */
abstract class RadioButtonInputElement implements InputElementBase {
  factory RadioButtonInputElement() => new InputElement(type: 'radio');

  @DomName('HTMLInputElement.checked')
  bool checked;

  @DomName('HTMLInputElement.required')
  bool required;
}

/**
 * A control for picking files from the user's computer.
 */
abstract class FileUploadInputElement implements InputElementBase {
  factory FileUploadInputElement() => new InputElement(type: 'file');

  @DomName('HTMLInputElement.accept')
  String accept;

  @DomName('HTMLInputElement.multiple')
  bool multiple;

  @DomName('HTMLInputElement.required')
  bool required;

  @DomName('HTMLInputElement.files')
  List<File> files;
}

/**
 * A button, which when clicked, submits the form.
 */
abstract class SubmitButtonInputElement implements InputElementBase {
  factory SubmitButtonInputElement() => new InputElement(type: 'submit');

  @DomName('HTMLInputElement.formAction')
  String formAction;

  @DomName('HTMLInputElement.formEnctype')
  String formEnctype;

  @DomName('HTMLInputElement.formMethod')
  String formMethod;

  @DomName('HTMLInputElement.formNoValidate')
  bool formNoValidate;

  @DomName('HTMLInputElement.formTarget')
  String formTarget;
}

/**
 * Either an image which the user can select a coordinate to or a form
 * submit button.
 */
abstract class ImageButtonInputElement implements InputElementBase {
  factory ImageButtonInputElement() => new InputElement(type: 'image');

  @DomName('HTMLInputElement.alt')
  String alt;

  @DomName('HTMLInputElement.formAction')
  String formAction;

  @DomName('HTMLInputElement.formEnctype')
  String formEnctype;

  @DomName('HTMLInputElement.formMethod')
  String formMethod;

  @DomName('HTMLInputElement.formNoValidate')
  bool formNoValidate;

  @DomName('HTMLInputElement.formTarget')
  String formTarget;

  @DomName('HTMLInputElement.height')
  int height;

  @DomName('HTMLInputElement.src')
  String src;

  @DomName('HTMLInputElement.width')
  int width;
}

/**
 * A button, which when clicked, resets the form.
 */
abstract class ResetButtonInputElement implements InputElementBase {
  factory ResetButtonInputElement() => new InputElement(type: 'reset');
}

/**
 * A button, with no default behavior.
 */
abstract class ButtonInputElement implements InputElementBase {
  factory ButtonInputElement() => new InputElement(type: 'button');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('InstallEvent')
@Experimental() // untriaged
@Native("InstallEvent")
class InstallEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory InstallEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('InstallEvent.InstallEvent')
  @DocsEditable()
  factory InstallEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return InstallEvent._create_1(type, eventInitDict_1);
    }
    return InstallEvent._create_2(type);
  }
  static InstallEvent _create_1(type, eventInitDict) =>
      JS('InstallEvent', 'new InstallEvent(#,#)', type, eventInitDict);
  static InstallEvent _create_2(type) =>
      JS('InstallEvent', 'new InstallEvent(#)', type);

  @DomName('InstallEvent.registerForeignFetchScopes')
  @DocsEditable()
  @Experimental() // untriaged
  void registerForeignFetchScopes(List<String> subScopes, Object origins) {
    List subScopes_1 = convertDartToNative_StringArray(subScopes);
    _registerForeignFetchScopes_1(subScopes_1, origins);
    return;
  }

  @JSName('registerForeignFetchScopes')
  @DomName('InstallEvent.registerForeignFetchScopes')
  @DocsEditable()
  @Experimental() // untriaged
  void _registerForeignFetchScopes_1(List subScopes, origins) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('IntersectionObserver')
@Experimental() // untriaged
@Native("IntersectionObserver")
class IntersectionObserver extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory IntersectionObserver._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('IntersectionObserver.root')
  @DocsEditable()
  @Experimental() // untriaged
  final Element root;

  @DomName('IntersectionObserver.rootMargin')
  @DocsEditable()
  @Experimental() // untriaged
  final String rootMargin;

  @DomName('IntersectionObserver.thresholds')
  @DocsEditable()
  @Experimental() // untriaged
  final List<num> thresholds;

  @DomName('IntersectionObserver.disconnect')
  @DocsEditable()
  @Experimental() // untriaged
  void disconnect() native;

  @DomName('IntersectionObserver.observe')
  @DocsEditable()
  @Experimental() // untriaged
  void observe(Element target) native;

  @DomName('IntersectionObserver.takeRecords')
  @DocsEditable()
  @Experimental() // untriaged
  List<IntersectionObserverEntry> takeRecords() native;

  @DomName('IntersectionObserver.unobserve')
  @DocsEditable()
  @Experimental() // untriaged
  void unobserve(Element target) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('IntersectionObserverEntry')
@Experimental() // untriaged
@Native("IntersectionObserverEntry")
class IntersectionObserverEntry extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory IntersectionObserverEntry._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('IntersectionObserverEntry.boundingClientRect')
  @DocsEditable()
  @Experimental() // untriaged
  final Rectangle boundingClientRect;

  @DomName('IntersectionObserverEntry.intersectionRect')
  @DocsEditable()
  @Experimental() // untriaged
  final Rectangle intersectionRect;

  @DomName('IntersectionObserverEntry.rootBounds')
  @DocsEditable()
  @Experimental() // untriaged
  final Rectangle rootBounds;

  @DomName('IntersectionObserverEntry.target')
  @DocsEditable()
  @Experimental() // untriaged
  final Element target;

  @DomName('IntersectionObserverEntry.time')
  @DocsEditable()
  @Experimental() // untriaged
  final double time;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * An event that describes user interaction with the keyboard.
 *
 * The [type] of the event identifies what kind of interaction occurred.
 *
 * See also:
 *
 * * [KeyboardEvent](https://developer.mozilla.org/en/DOM/KeyboardEvent) at MDN.
 */
@DomName('KeyboardEvent')
@Native("KeyboardEvent")
class KeyboardEvent extends UIEvent {
  /**
   * Programmatically create a KeyboardEvent.
   *
   * Due to browser differences, keyCode, charCode, or keyIdentifier values
   * cannot be specified in this base level constructor. This constructor
   * enables the user to programmatically create and dispatch a [KeyboardEvent],
   * but it will not contain any particular key content. For programmatically
   * creating keyboard events with specific key value contents, see the custom
   * Event [KeyEvent].
   */
  factory KeyboardEvent(String type,
      {Window view,
      bool canBubble: true,
      bool cancelable: true,
      int location,
      int keyLocation, // Legacy alias for location
      bool ctrlKey: false,
      bool altKey: false,
      bool shiftKey: false,
      bool metaKey: false}) {
    if (view == null) {
      view = window;
    }
    location ??= keyLocation ?? 1;
    KeyboardEvent e = document._createEvent("KeyboardEvent");
    e._initKeyboardEvent(type, canBubble, cancelable, view, "", location,
        ctrlKey, altKey, shiftKey, metaKey);
    return e;
  }

  @DomName('KeyboardEvent.initKeyboardEvent')
  void _initKeyboardEvent(
      String type,
      bool canBubble,
      bool cancelable,
      Window view,
      String keyIdentifier,
      int location,
      bool ctrlKey,
      bool altKey,
      bool shiftKey,
      bool metaKey) {
    if (JS('bool', 'typeof(#.initKeyEvent) == "function"', this)) {
      // initKeyEvent is only in Firefox (instead of initKeyboardEvent). It has
      // a slightly different signature, and allows you to specify keyCode and
      // charCode as the last two arguments, but we just set them as the default
      // since they can't be specified in other browsers.
      JS('void', '#.initKeyEvent(#, #, #, #, #, #, #, #, 0, 0)', this, type,
          canBubble, cancelable, view, ctrlKey, altKey, shiftKey, metaKey);
    } else {
      // initKeyboardEvent is for all other browsers.
      JS(
          'void',
          '#.initKeyboardEvent(#, #, #, #, #, #, #, #, #, #)',
          this,
          type,
          canBubble,
          cancelable,
          view,
          keyIdentifier,
          location,
          ctrlKey,
          altKey,
          shiftKey,
          metaKey);
    }
  }

  @DomName('KeyboardEvent.keyCode')
  final int keyCode;

  @DomName('KeyboardEvent.charCode')
  final int charCode;

  @DomName('KeyboardEvent.which')
  int get which => _which;

  @DomName('KeyboardEvent.KeyboardEvent')
  @DocsEditable()
  factory KeyboardEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return KeyboardEvent._create_1(type, eventInitDict_1);
    }
    return KeyboardEvent._create_2(type);
  }
  static KeyboardEvent _create_1(type, eventInitDict) =>
      JS('KeyboardEvent', 'new KeyboardEvent(#,#)', type, eventInitDict);
  static KeyboardEvent _create_2(type) =>
      JS('KeyboardEvent', 'new KeyboardEvent(#)', type);

  @DomName('KeyboardEvent.DOM_KEY_LOCATION_LEFT')
  @DocsEditable()
  @Experimental() // untriaged
  static const int DOM_KEY_LOCATION_LEFT = 0x01;

  @DomName('KeyboardEvent.DOM_KEY_LOCATION_NUMPAD')
  @DocsEditable()
  @Experimental() // untriaged
  static const int DOM_KEY_LOCATION_NUMPAD = 0x03;

  @DomName('KeyboardEvent.DOM_KEY_LOCATION_RIGHT')
  @DocsEditable()
  @Experimental() // untriaged
  static const int DOM_KEY_LOCATION_RIGHT = 0x02;

  @DomName('KeyboardEvent.DOM_KEY_LOCATION_STANDARD')
  @DocsEditable()
  @Experimental() // untriaged
  static const int DOM_KEY_LOCATION_STANDARD = 0x00;

  @DomName('KeyboardEvent.altKey')
  @DocsEditable()
  final bool altKey;

  @JSName('charCode')
  @DomName('KeyboardEvent.charCode')
  @DocsEditable()
  @Experimental() // untriaged
  final int _charCode;

  @DomName('KeyboardEvent.code')
  @DocsEditable()
  @Experimental() // untriaged
  final String code;

  @DomName('KeyboardEvent.ctrlKey')
  @DocsEditable()
  final bool ctrlKey;

  @DomName('KeyboardEvent.key')
  @DocsEditable()
  @Experimental() // untriaged
  final String key;

  @JSName('keyCode')
  @DomName('KeyboardEvent.keyCode')
  @DocsEditable()
  @Experimental() // untriaged
  final int _keyCode;

  @JSName('keyIdentifier')
  @DomName('KeyboardEvent.keyIdentifier')
  @DocsEditable()
  @Experimental() // nonstandard
  final String _keyIdentifier;

  @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;

  // Use implementation from UIEvent.
  // final int _which;

  @DomName('KeyboardEvent.getModifierState')
  @DocsEditable()
  @Experimental() // untriaged
  bool getModifierState(String keyArg) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('KeyframeEffect')
@Experimental() // untriaged
@Native("KeyframeEffect")
class KeyframeEffect extends AnimationEffectReadOnly {
  // To suppress missing implicit constructor warnings.
  factory KeyframeEffect._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('KeyframeEffect.KeyframeEffect')
  @DocsEditable()
  factory KeyframeEffect(Element target, Object effect, [timing]) {
    if (effect != null &&
        (target is Element || target == null) &&
        timing == null) {
      return KeyframeEffect._create_1(target, effect);
    }
    if ((timing is num) &&
        effect != null &&
        (target is Element || target == null)) {
      return KeyframeEffect._create_2(target, effect, timing);
    }
    if ((timing is Map) &&
        effect != null &&
        (target is Element || target == null)) {
      var timing_1 = convertDartToNative_Dictionary(timing);
      return KeyframeEffect._create_3(target, effect, timing_1);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static KeyframeEffect _create_1(target, effect) =>
      JS('KeyframeEffect', 'new KeyframeEffect(#,#)', target, effect);
  static KeyframeEffect _create_2(target, effect, timing) =>
      JS('KeyframeEffect', 'new KeyframeEffect(#,#,#)', target, effect, timing);
  static KeyframeEffect _create_3(target, effect, timing) =>
      JS('KeyframeEffect', 'new KeyframeEffect(#,#,#)', target, effect, timing);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLKeygenElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#the-keygen-element
@Native("HTMLKeygenElement")
class KeygenElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory KeygenElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLKeygenElement.HTMLKeygenElement')
  @DocsEditable()
  factory KeygenElement() => document.createElement("keygen");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  KeygenElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported =>
      Element.isTagSupported('keygen') &&
      (new Element.tag('keygen') is KeygenElement);

  @DomName('HTMLKeygenElement.autofocus')
  @DocsEditable()
  bool autofocus;

  @DomName('HTMLKeygenElement.challenge')
  @DocsEditable()
  String challenge;

  @DomName('HTMLKeygenElement.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('HTMLKeygenElement.form')
  @DocsEditable()
  final FormElement form;

  @DomName('HTMLKeygenElement.keytype')
  @DocsEditable()
  String keytype;

  @DomName('HTMLKeygenElement.labels')
  @DocsEditable()
  @Unstable()
  @Returns('NodeList|Null')
  @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.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() 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('KeywordValue')
@Experimental() // untriaged
@Native("KeywordValue")
class KeywordValue extends StyleValue {
  // To suppress missing implicit constructor warnings.
  factory KeywordValue._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('KeywordValue.KeywordValue')
  @DocsEditable()
  factory KeywordValue(String keyword) {
    return KeywordValue._create_1(keyword);
  }
  static KeywordValue _create_1(keyword) =>
      JS('KeywordValue', 'new KeywordValue(#)', keyword);

  @DomName('KeywordValue.keywordValue')
  @DocsEditable()
  @Experimental() // untriaged
  final String keywordValue;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLLIElement')
@Native("HTMLLIElement")
class LIElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory LIElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLLIElement.HTMLLIElement')
  @DocsEditable()
  factory LIElement() => JS('returns:LIElement;creates:LIElement;new:true',
      '#.createElement(#)', document, "li");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  LIElement.created() : super.created();

  @DomName('HTMLLIElement.value')
  @DocsEditable()
  int value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLLabelElement')
@Native("HTMLLabelElement")
class LabelElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory LabelElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLLabelElement.HTMLLabelElement')
  @DocsEditable()
  factory LabelElement() => JS(
      'returns:LabelElement;creates:LabelElement;new:true',
      '#.createElement(#)',
      document,
      "label");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  LabelElement.created() : super.created();

  @DomName('HTMLLabelElement.control')
  @DocsEditable()
  final HtmlElement control;

  @DomName('HTMLLabelElement.form')
  @DocsEditable()
  final FormElement form;

  @DomName('HTMLLabelElement.htmlFor')
  @DocsEditable()
  String htmlFor;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLLegendElement')
@Native("HTMLLegendElement")
class LegendElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory LegendElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLLegendElement.HTMLLegendElement')
  @DocsEditable()
  factory LegendElement() => JS(
      'returns:LegendElement;creates:LegendElement;new:true',
      '#.createElement(#)',
      document,
      "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) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('LengthValue')
@Experimental() // untriaged
@Native("LengthValue")
class LengthValue extends StyleValue {
  // To suppress missing implicit constructor warnings.
  factory LengthValue._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('LengthValue.add')
  @DocsEditable()
  @Experimental() // untriaged
  LengthValue add(LengthValue other) native;

  @DomName('LengthValue.divide')
  @DocsEditable()
  @Experimental() // untriaged
  LengthValue divide(num value) native;

  @DomName('LengthValue.fromDictionary')
  @DocsEditable()
  @Experimental() // untriaged
  static LengthValue fromDictionary(Map dictionary) {
    var dictionary_1 = convertDartToNative_Dictionary(dictionary);
    return _fromDictionary_1(dictionary_1);
  }

  @JSName('fromDictionary')
  @DomName('LengthValue.fromDictionary')
  @DocsEditable()
  @Experimental() // untriaged
  static LengthValue _fromDictionary_1(dictionary) native;

  @DomName('LengthValue.fromValue')
  @DocsEditable()
  @Experimental() // untriaged
  static LengthValue fromValue(num value, String type) native;

  @DomName('LengthValue.multiply')
  @DocsEditable()
  @Experimental() // untriaged
  LengthValue multiply(num value) native;

  @DomName('LengthValue.parse')
  @DocsEditable()
  @Experimental() // untriaged
  static LengthValue parse(String cssString) native;

  @DomName('LengthValue.subtract')
  @DocsEditable()
  @Experimental() // untriaged
  LengthValue subtract(LengthValue other) 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('HTMLLinkElement')
@Native("HTMLLinkElement")
class LinkElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory LinkElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLLinkElement.HTMLLinkElement')
  @DocsEditable()
  factory LinkElement() => JS(
      'returns:LinkElement;creates:LinkElement;new:true',
      '#.createElement(#)',
      document,
      "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.as')
  @DocsEditable()
  @Experimental() // untriaged
  String as;

  @DomName('HTMLLinkElement.crossOrigin')
  @DocsEditable()
  @Experimental() // untriaged
  String crossOrigin;

  @DomName('HTMLLinkElement.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('HTMLLinkElement.href')
  @DocsEditable()
  String href;

  @DomName('HTMLLinkElement.hreflang')
  @DocsEditable()
  String hreflang;

  @DomName('HTMLLinkElement.import')
  @DocsEditable()
  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/imports/index.html#interface-import
  @Experimental()
  final Document import;

  @DomName('HTMLLinkElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String integrity;

  @DomName('HTMLLinkElement.media')
  @DocsEditable()
  String media;

  @DomName('HTMLLinkElement.rel')
  @DocsEditable()
  String rel;

  @DomName('HTMLLinkElement.relList')
  @DocsEditable()
  @Experimental() // untriaged
  final DomTokenList relList;

  @DomName('HTMLLinkElement.sheet')
  @DocsEditable()
  final StyleSheet sheet;

  @DomName('HTMLLinkElement.sizes')
  @DocsEditable()
  final DomTokenList 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')
@Native("Location")
class Location extends Interceptor implements LocationBase {
  // To suppress missing implicit constructor warnings.
  factory Location._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Location.ancestorOrigins')
  @DocsEditable()
  @Experimental() // nonstandard
  @Returns('DomStringList|Null')
  @Creates('DomStringList')
  final List<String> ancestorOrigins;

  @DomName('Location.hash')
  @DocsEditable()
  String hash;

  @DomName('Location.host')
  @DocsEditable()
  String host;

  @DomName('Location.hostname')
  @DocsEditable()
  String hostname;

  @DomName('Location.href')
  @DocsEditable()
  String href;

  @DomName('Location.pathname')
  @DocsEditable()
  String pathname;

  @DomName('Location.port')
  @DocsEditable()
  String port;

  @DomName('Location.protocol')
  @DocsEditable()
  String protocol;

  @DomName('Location.search')
  @DocsEditable()
  String search;

  @DomName('Location.assign')
  @DocsEditable()
  void assign([String url]) native;

  @DomName('Location.reload')
  @DocsEditable()
  void reload() native;

  @DomName('Location.replace')
  @DocsEditable()
  void replace(String url) native;

  @DomName('Location.origin')
  String get origin {
    if (JS('bool', '("origin" in #)', this)) {
      return JS('String', '#.origin', this);
    }
    return '${this.protocol}//${this.host}';
  }

  @DomName('Location.toString')
  @DocsEditable()
  String toString() => JS('String', 'String(#)', this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLMapElement')
@Native("HTMLMapElement")
class MapElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory MapElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLMapElement.HTMLMapElement')
  @DocsEditable()
  factory MapElement() => JS('returns:MapElement;creates:MapElement;new:true',
      '#.createElement(#)', document, "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|Null')
  @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('Matrix')
@Experimental() // untriaged
@Native("Matrix")
class Matrix extends TransformComponent {
  // To suppress missing implicit constructor warnings.
  factory Matrix._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Matrix.Matrix')
  @DocsEditable()
  factory Matrix(num a_OR_m11, num b_OR_m12, num c_OR_m13, num d_OR_m14,
      num e_OR_m21, num f_OR_m22,
      [num m23,
      num m24,
      num m31,
      num m32,
      num m33,
      num m34,
      num m41,
      num m42,
      num m43,
      num m44]) {
    if ((f_OR_m22 is num) &&
        (e_OR_m21 is num) &&
        (d_OR_m14 is num) &&
        (c_OR_m13 is num) &&
        (b_OR_m12 is num) &&
        (a_OR_m11 is num) &&
        m23 == null &&
        m24 == null &&
        m31 == null &&
        m32 == null &&
        m33 == null &&
        m34 == null &&
        m41 == null &&
        m42 == null &&
        m43 == null &&
        m44 == null) {
      return Matrix._create_1(
          a_OR_m11, b_OR_m12, c_OR_m13, d_OR_m14, e_OR_m21, f_OR_m22);
    }
    if ((m44 is num) &&
        (m43 is num) &&
        (m42 is num) &&
        (m41 is num) &&
        (m34 is num) &&
        (m33 is num) &&
        (m32 is num) &&
        (m31 is num) &&
        (m24 is num) &&
        (m23 is num) &&
        (f_OR_m22 is num) &&
        (e_OR_m21 is num) &&
        (d_OR_m14 is num) &&
        (c_OR_m13 is num) &&
        (b_OR_m12 is num) &&
        (a_OR_m11 is num)) {
      return Matrix._create_2(a_OR_m11, b_OR_m12, c_OR_m13, d_OR_m14, e_OR_m21,
          f_OR_m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static Matrix _create_1(
          a_OR_m11, b_OR_m12, c_OR_m13, d_OR_m14, e_OR_m21, f_OR_m22) =>
      JS('Matrix', 'new Matrix(#,#,#,#,#,#)', a_OR_m11, b_OR_m12, c_OR_m13,
          d_OR_m14, e_OR_m21, f_OR_m22);
  static Matrix _create_2(a_OR_m11, b_OR_m12, c_OR_m13, d_OR_m14, e_OR_m21,
          f_OR_m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44) =>
      JS(
          'Matrix',
          'new Matrix(#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#)',
          a_OR_m11,
          b_OR_m12,
          c_OR_m13,
          d_OR_m14,
          e_OR_m21,
          f_OR_m22,
          m23,
          m24,
          m31,
          m32,
          m33,
          m34,
          m41,
          m42,
          m43,
          m44);

  @DomName('Matrix.a')
  @DocsEditable()
  @Experimental() // untriaged
  final double a;

  @DomName('Matrix.b')
  @DocsEditable()
  @Experimental() // untriaged
  final double b;

  @DomName('Matrix.c')
  @DocsEditable()
  @Experimental() // untriaged
  final double c;

  @DomName('Matrix.d')
  @DocsEditable()
  @Experimental() // untriaged
  final double d;

  @DomName('Matrix.e')
  @DocsEditable()
  @Experimental() // untriaged
  final double e;

  @DomName('Matrix.f')
  @DocsEditable()
  @Experimental() // untriaged
  final double f;

  @DomName('Matrix.m11')
  @DocsEditable()
  @Experimental() // untriaged
  final double m11;

  @DomName('Matrix.m12')
  @DocsEditable()
  @Experimental() // untriaged
  final double m12;

  @DomName('Matrix.m13')
  @DocsEditable()
  @Experimental() // untriaged
  final double m13;

  @DomName('Matrix.m14')
  @DocsEditable()
  @Experimental() // untriaged
  final double m14;

  @DomName('Matrix.m21')
  @DocsEditable()
  @Experimental() // untriaged
  final double m21;

  @DomName('Matrix.m22')
  @DocsEditable()
  @Experimental() // untriaged
  final double m22;

  @DomName('Matrix.m23')
  @DocsEditable()
  @Experimental() // untriaged
  final double m23;

  @DomName('Matrix.m24')
  @DocsEditable()
  @Experimental() // untriaged
  final double m24;

  @DomName('Matrix.m31')
  @DocsEditable()
  @Experimental() // untriaged
  final double m31;

  @DomName('Matrix.m32')
  @DocsEditable()
  @Experimental() // untriaged
  final double m32;

  @DomName('Matrix.m33')
  @DocsEditable()
  @Experimental() // untriaged
  final double m33;

  @DomName('Matrix.m34')
  @DocsEditable()
  @Experimental() // untriaged
  final double m34;

  @DomName('Matrix.m41')
  @DocsEditable()
  @Experimental() // untriaged
  final double m41;

  @DomName('Matrix.m42')
  @DocsEditable()
  @Experimental() // untriaged
  final double m42;

  @DomName('Matrix.m43')
  @DocsEditable()
  @Experimental() // untriaged
  final double m43;

  @DomName('Matrix.m44')
  @DocsEditable()
  @Experimental() // untriaged
  final double m44;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MediaDeviceInfo')
@Experimental() // untriaged
@Native("MediaDeviceInfo")
class MediaDeviceInfo extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaDeviceInfo._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MediaDeviceInfo.deviceId')
  @DocsEditable()
  @Experimental() // untriaged
  final String deviceId;

  @DomName('MediaDeviceInfo.groupId')
  @DocsEditable()
  @Experimental() // untriaged
  final String groupId;

  @DomName('MediaDeviceInfo.kind')
  @DocsEditable()
  @Experimental() // untriaged
  final String kind;

  @DomName('MediaDeviceInfo.label')
  @DocsEditable()
  @Experimental() // untriaged
  final String label;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MediaDevices')
@Experimental() // untriaged
@Native("MediaDevices")
class MediaDevices extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaDevices._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MediaDevices.enumerateDevices')
  @DocsEditable()
  @Experimental() // untriaged
  Future enumerateDevices() native;

  @DomName('MediaDevices.getUserMedia')
  @DocsEditable()
  @Experimental() // untriaged
  Future getUserMedia(Map options) {
    var options_1 = convertDartToNative_Dictionary(options);
    return _getUserMedia_1(options_1);
  }

  @JSName('getUserMedia')
  @DomName('MediaDevices.getUserMedia')
  @DocsEditable()
  @Experimental() // untriaged
  Future _getUserMedia_1(options) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLMediaElement')
@Unstable()
@Native("HTMLMediaElement")
class MediaElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory MediaElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  MediaElement.created() : super.created();

  @DomName('HTMLMediaElement.HAVE_CURRENT_DATA')
  @DocsEditable()
  static const int HAVE_CURRENT_DATA = 2;

  @DomName('HTMLMediaElement.HAVE_ENOUGH_DATA')
  @DocsEditable()
  static const int HAVE_ENOUGH_DATA = 4;

  @DomName('HTMLMediaElement.HAVE_FUTURE_DATA')
  @DocsEditable()
  static const int HAVE_FUTURE_DATA = 3;

  @DomName('HTMLMediaElement.HAVE_METADATA')
  @DocsEditable()
  static const int HAVE_METADATA = 1;

  @DomName('HTMLMediaElement.HAVE_NOTHING')
  @DocsEditable()
  static const int HAVE_NOTHING = 0;

  @DomName('HTMLMediaElement.NETWORK_EMPTY')
  @DocsEditable()
  static const int NETWORK_EMPTY = 0;

  @DomName('HTMLMediaElement.NETWORK_IDLE')
  @DocsEditable()
  static const int NETWORK_IDLE = 1;

  @DomName('HTMLMediaElement.NETWORK_LOADING')
  @DocsEditable()
  static const int NETWORK_LOADING = 2;

  @DomName('HTMLMediaElement.NETWORK_NO_SOURCE')
  @DocsEditable()
  static const int NETWORK_NO_SOURCE = 3;

  @DomName('HTMLMediaElement.audioTracks')
  @DocsEditable()
  @Experimental() // untriaged
  @Returns('AudioTrackList|Null')
  @Creates('AudioTrackList')
  final List<AudioTrack> audioTracks;

  @DomName('HTMLMediaElement.autoplay')
  @DocsEditable()
  bool autoplay;

  @DomName('HTMLMediaElement.buffered')
  @DocsEditable()
  final TimeRanges buffered;

  @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.disableRemotePlayback')
  @DocsEditable()
  @Experimental() // untriaged
  bool disableRemotePlayback;

  @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.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.session')
  @DocsEditable()
  @Experimental() // untriaged
  MediaSession session;

  @DomName('HTMLMediaElement.sinkId')
  @DocsEditable()
  @Experimental() // untriaged
  final String sinkId;

  @DomName('HTMLMediaElement.src')
  @DocsEditable()
  String src;

  @DomName('HTMLMediaElement.textTracks')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-media-texttracks
  @Experimental()
  final TextTrackList textTracks;

  @DomName('HTMLMediaElement.videoTracks')
  @DocsEditable()
  @Experimental() // untriaged
  final VideoTrackList videoTracks;

  @DomName('HTMLMediaElement.volume')
  @DocsEditable()
  num volume;

  @JSName('webkitAudioDecodedByteCount')
  @DomName('HTMLMediaElement.webkitAudioDecodedByteCount')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // nonstandard
  final int audioDecodedByteCount;

  @JSName('webkitVideoDecodedByteCount')
  @DomName('HTMLMediaElement.webkitVideoDecodedByteCount')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // nonstandard
  final int videoDecodedByteCount;

  @DomName('HTMLMediaElement.addTextTrack')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-media-addtexttrack
  @Experimental()
  TextTrack addTextTrack(String kind, [String label, String language]) native;

  @DomName('HTMLMediaElement.canPlayType')
  @DocsEditable()
  @Unstable()
  String canPlayType(String type, [String keySystem]) native;

  @DomName('HTMLMediaElement.captureStream')
  @DocsEditable()
  @Experimental() // untriaged
  MediaStream captureStream() native;

  @DomName('HTMLMediaElement.load')
  @DocsEditable()
  void load() native;

  @DomName('HTMLMediaElement.pause')
  @DocsEditable()
  void pause() native;

  @DomName('HTMLMediaElement.play')
  @DocsEditable()
  Future play() native;

  @DomName('HTMLMediaElement.setMediaKeys')
  @DocsEditable()
  @Experimental() // untriaged
  Future setMediaKeys(MediaKeys mediaKeys) native;

  @DomName('HTMLMediaElement.setSinkId')
  @DocsEditable()
  @Experimental() // untriaged
  Future setSinkId(String sinkId) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MediaEncryptedEvent')
@Experimental() // untriaged
@Native("MediaEncryptedEvent")
class MediaEncryptedEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MediaEncryptedEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MediaEncryptedEvent.MediaEncryptedEvent')
  @DocsEditable()
  factory MediaEncryptedEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return MediaEncryptedEvent._create_1(type, eventInitDict_1);
    }
    return MediaEncryptedEvent._create_2(type);
  }
  static MediaEncryptedEvent _create_1(type, eventInitDict) => JS(
      'MediaEncryptedEvent',
      'new MediaEncryptedEvent(#,#)',
      type,
      eventInitDict);
  static MediaEncryptedEvent _create_2(type) =>
      JS('MediaEncryptedEvent', 'new MediaEncryptedEvent(#)', type);

  @DomName('MediaEncryptedEvent.initData')
  @DocsEditable()
  @Experimental() // untriaged
  final ByteBuffer initData;

  @DomName('MediaEncryptedEvent.initDataType')
  @DocsEditable()
  @Experimental() // untriaged
  final String initDataType;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MediaError')
@Unstable()
@Native("MediaError")
class MediaError extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaError._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MediaError.MEDIA_ERR_ABORTED')
  @DocsEditable()
  static const int MEDIA_ERR_ABORTED = 1;

  @DomName('MediaError.MEDIA_ERR_DECODE')
  @DocsEditable()
  static const int MEDIA_ERR_DECODE = 3;

  @DomName('MediaError.MEDIA_ERR_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('MediaKeyMessageEvent')
// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-mediakeymessageevent
@Experimental()
@Native("MediaKeyMessageEvent")
class MediaKeyMessageEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MediaKeyMessageEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MediaKeyMessageEvent.MediaKeyMessageEvent')
  @DocsEditable()
  factory MediaKeyMessageEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return MediaKeyMessageEvent._create_1(type, eventInitDict_1);
    }
    return MediaKeyMessageEvent._create_2(type);
  }
  static MediaKeyMessageEvent _create_1(type, eventInitDict) => JS(
      'MediaKeyMessageEvent',
      'new MediaKeyMessageEvent(#,#)',
      type,
      eventInitDict);
  static MediaKeyMessageEvent _create_2(type) =>
      JS('MediaKeyMessageEvent', 'new MediaKeyMessageEvent(#)', type);

  @DomName('MediaKeyMessageEvent.message')
  @DocsEditable()
  final ByteBuffer message;

  @DomName('MediaKeyMessageEvent.messageType')
  @DocsEditable()
  @Experimental() // untriaged
  final String messageType;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MediaKeySession')
// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-mediakeysession
@Experimental()
@Native("MediaKeySession")
class MediaKeySession extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaKeySession._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MediaKeySession.closed')
  @DocsEditable()
  @Experimental() // untriaged
  final Future closed;

  @DomName('MediaKeySession.expiration')
  @DocsEditable()
  @Experimental() // untriaged
  final double expiration;

  @DomName('MediaKeySession.keyStatuses')
  @DocsEditable()
  @Experimental() // untriaged
  final MediaKeyStatusMap keyStatuses;

  @DomName('MediaKeySession.sessionId')
  @DocsEditable()
  final String sessionId;

  @DomName('MediaKeySession.close')
  @DocsEditable()
  Future close() native;

  @DomName('MediaKeySession.generateRequest')
  @DocsEditable()
  @Experimental() // untriaged
  Future generateRequest(String initDataType, /*BufferSource*/ initData) native;

  @DomName('MediaKeySession.load')
  @DocsEditable()
  @Experimental() // untriaged
  Future load(String sessionId) native;

  @DomName('MediaKeySession.remove')
  @DocsEditable()
  @Experimental() // untriaged
  Future remove() native;

  @JSName('update')
  @DomName('MediaKeySession.update')
  @DocsEditable()
  Future _update(/*BufferSource*/ 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('MediaKeyStatusMap')
@Experimental() // untriaged
@Native("MediaKeyStatusMap")
class MediaKeyStatusMap extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaKeyStatusMap._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MediaKeyStatusMap.size')
  @DocsEditable()
  @Experimental() // untriaged
  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.

@DocsEditable()
@DomName('MediaKeySystemAccess')
@Experimental() // untriaged
@Native("MediaKeySystemAccess")
class MediaKeySystemAccess extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaKeySystemAccess._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MediaKeySystemAccess.keySystem')
  @DocsEditable()
  @Experimental() // untriaged
  final String keySystem;

  @DomName('MediaKeySystemAccess.createMediaKeys')
  @DocsEditable()
  @Experimental() // untriaged
  Future createMediaKeys() native;

  @DomName('MediaKeySystemAccess.getConfiguration')
  @DocsEditable()
  @Experimental() // untriaged
  Map getConfiguration() {
    return convertNativeToDart_Dictionary(_getConfiguration_1());
  }

  @JSName('getConfiguration')
  @DomName('MediaKeySystemAccess.getConfiguration')
  @DocsEditable()
  @Experimental() // untriaged
  _getConfiguration_1() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MediaKeys')
// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html
@Experimental()
@Native("MediaKeys")
class MediaKeys extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaKeys._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('createSession')
  @DomName('MediaKeys.createSession')
  @DocsEditable()
  MediaKeySession _createSession([String sessionType]) native;

  @DomName('MediaKeys.setServerCertificate')
  @DocsEditable()
  @Experimental() // untriaged
  Future setServerCertificate(/*BufferSource*/ serverCertificate) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MediaList')
@Unstable()
@Native("MediaList")
class MediaList extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaList._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MediaList.length')
  @DocsEditable()
  final int length;

  @DomName('MediaList.mediaText')
  @DocsEditable()
  String mediaText;

  @DomName('MediaList.appendMedium')
  @DocsEditable()
  void appendMedium(String medium) native;

  @DomName('MediaList.deleteMedium')
  @DocsEditable()
  void deleteMedium(String medium) 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('MediaMetadata')
@Experimental() // untriaged
@Native("MediaMetadata")
class MediaMetadata extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaMetadata._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MediaMetadata.MediaMetadata')
  @DocsEditable()
  factory MediaMetadata(Map metadata) {
    var metadata_1 = convertDartToNative_Dictionary(metadata);
    return MediaMetadata._create_1(metadata_1);
  }
  static MediaMetadata _create_1(metadata) =>
      JS('MediaMetadata', 'new MediaMetadata(#)', metadata);

  @DomName('MediaMetadata.album')
  @DocsEditable()
  @Experimental() // untriaged
  final String album;

  @DomName('MediaMetadata.artist')
  @DocsEditable()
  @Experimental() // untriaged
  final String artist;

  @DomName('MediaMetadata.title')
  @DocsEditable()
  @Experimental() // untriaged
  final String title;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MediaQueryList')
@Unstable()
@Native("MediaQueryList")
class MediaQueryList extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaQueryList._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MediaQueryList.changeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  @DomName('MediaQueryList.matches')
  @DocsEditable()
  final bool matches;

  @DomName('MediaQueryList.media')
  @DocsEditable()
  final String media;

  @DomName('MediaQueryList.addListener')
  @DocsEditable()
  void addListener(EventListener listener) native;

  @DomName('MediaQueryList.removeListener')
  @DocsEditable()
  void removeListener(EventListener listener) native;

  @DomName('MediaQueryList.onchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onChange => changeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MediaQueryListEvent')
@Experimental() // untriaged
@Native("MediaQueryListEvent")
class MediaQueryListEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MediaQueryListEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MediaQueryListEvent.MediaQueryListEvent')
  @DocsEditable()
  factory MediaQueryListEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return MediaQueryListEvent._create_1(type, eventInitDict_1);
    }
    return MediaQueryListEvent._create_2(type);
  }
  static MediaQueryListEvent _create_1(type, eventInitDict) => JS(
      'MediaQueryListEvent',
      'new MediaQueryListEvent(#,#)',
      type,
      eventInitDict);
  static MediaQueryListEvent _create_2(type) =>
      JS('MediaQueryListEvent', 'new MediaQueryListEvent(#)', type);

  @DomName('MediaQueryListEvent.matches')
  @DocsEditable()
  @Experimental() // untriaged
  final bool matches;

  @DomName('MediaQueryListEvent.media')
  @DocsEditable()
  @Experimental() // untriaged
  final String media;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MediaRecorder')
@Experimental() // untriaged
@Native("MediaRecorder")
class MediaRecorder extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaRecorder._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MediaRecorder.errorEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  @DomName('MediaRecorder.pauseEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> pauseEvent =
      const EventStreamProvider<Event>('pause');

  @DomName('MediaRecorder.MediaRecorder')
  @DocsEditable()
  factory MediaRecorder(MediaStream stream, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return MediaRecorder._create_1(stream, options_1);
    }
    return MediaRecorder._create_2(stream);
  }
  static MediaRecorder _create_1(stream, options) =>
      JS('MediaRecorder', 'new MediaRecorder(#,#)', stream, options);
  static MediaRecorder _create_2(stream) =>
      JS('MediaRecorder', 'new MediaRecorder(#)', stream);

  @DomName('MediaRecorder.audioBitsPerSecond')
  @DocsEditable()
  @Experimental() // untriaged
  final int audioBitsPerSecond;

  @DomName('MediaRecorder.ignoreMutedMedia')
  @DocsEditable()
  @Experimental() // untriaged
  bool ignoreMutedMedia;

  @DomName('MediaRecorder.mimeType')
  @DocsEditable()
  @Experimental() // untriaged
  final String mimeType;

  @DomName('MediaRecorder.state')
  @DocsEditable()
  @Experimental() // untriaged
  final String state;

  @DomName('MediaRecorder.stream')
  @DocsEditable()
  @Experimental() // untriaged
  final MediaStream stream;

  @DomName('MediaRecorder.videoBitsPerSecond')
  @DocsEditable()
  @Experimental() // untriaged
  final int videoBitsPerSecond;

  @DomName('MediaRecorder.isTypeSupported')
  @DocsEditable()
  @Experimental() // untriaged
  static bool isTypeSupported(String type) native;

  @DomName('MediaRecorder.pause')
  @DocsEditable()
  @Experimental() // untriaged
  void pause() native;

  @DomName('MediaRecorder.requestData')
  @DocsEditable()
  @Experimental() // untriaged
  void requestData() native;

  @DomName('MediaRecorder.resume')
  @DocsEditable()
  @Experimental() // untriaged
  void resume() native;

  @DomName('MediaRecorder.start')
  @DocsEditable()
  @Experimental() // untriaged
  void start([int timeslice]) native;

  @DomName('MediaRecorder.stop')
  @DocsEditable()
  @Experimental() // untriaged
  void stop() native;

  @DomName('MediaRecorder.onerror')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onError => errorEvent.forTarget(this);

  @DomName('MediaRecorder.onpause')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onPause => pauseEvent.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('MediaSession')
@Experimental() // untriaged
@Native("MediaSession")
class MediaSession extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MediaSession._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MediaSession.MediaSession')
  @DocsEditable()
  factory MediaSession() {
    return MediaSession._create_1();
  }
  static MediaSession _create_1() => JS('MediaSession', 'new MediaSession()');

  @DomName('MediaSession.metadata')
  @DocsEditable()
  @Experimental() // untriaged
  MediaMetadata metadata;

  @DomName('MediaSession.activate')
  @DocsEditable()
  @Experimental() // untriaged
  Future activate() native;

  @DomName('MediaSession.deactivate')
  @DocsEditable()
  @Experimental() // untriaged
  Future deactivate() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MediaSource')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE, '11')
// https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#mediasource
@Experimental()
@Native("MediaSource")
class MediaSource extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaSource._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MediaSource.MediaSource')
  @DocsEditable()
  factory MediaSource() {
    return MediaSource._create_1();
  }
  static MediaSource _create_1() => JS('MediaSource', 'new MediaSource()');

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.MediaSource)');

  @DomName('MediaSource.activeSourceBuffers')
  @DocsEditable()
  final SourceBufferList activeSourceBuffers;

  @DomName('MediaSource.duration')
  @DocsEditable()
  num duration;

  @DomName('MediaSource.readyState')
  @DocsEditable()
  final String readyState;

  @DomName('MediaSource.sourceBuffers')
  @DocsEditable()
  final SourceBufferList sourceBuffers;

  @DomName('MediaSource.addSourceBuffer')
  @DocsEditable()
  SourceBuffer addSourceBuffer(String type) native;

  @DomName('MediaSource.endOfStream')
  @DocsEditable()
  void endOfStream([String error]) native;

  @DomName('MediaSource.isTypeSupported')
  @DocsEditable()
  static bool isTypeSupported(String type) native;

  @DomName('MediaSource.removeSourceBuffer')
  @DocsEditable()
  void removeSourceBuffer(SourceBuffer buffer) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DomName('MediaStream')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html#mediastream
@Native("MediaStream")
class MediaStream extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaStream._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `addtrack` events to event
   * handlers that are not necessarily instances of [MediaStream].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MediaStream.addtrackEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> addTrackEvent =
      const EventStreamProvider<Event>('addtrack');

  /**
   * Static factory designed to expose `ended` events to event
   * handlers that are not necessarily instances of [MediaStream].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MediaStream.endedEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> endedEvent =
      const EventStreamProvider<Event>('ended');

  /**
   * Static factory designed to expose `removetrack` events to event
   * handlers that are not necessarily instances of [MediaStream].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MediaStream.removetrackEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> removeTrackEvent =
      const EventStreamProvider<Event>('removetrack');

  @DomName('MediaStream.MediaStream')
  @DocsEditable()
  factory MediaStream([stream_OR_tracks]) {
    if (stream_OR_tracks == null) {
      return MediaStream._create_1();
    }
    if ((stream_OR_tracks is MediaStream)) {
      return MediaStream._create_2(stream_OR_tracks);
    }
    if ((stream_OR_tracks is List<MediaStreamTrack>)) {
      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.active')
  @DocsEditable()
  @Experimental() // untriaged
  final bool active;

  @DomName('MediaStream.id')
  @DocsEditable()
  final String id;

  @DomName('MediaStream.addTrack')
  @DocsEditable()
  void addTrack(MediaStreamTrack track) native;

  @DomName('MediaStream.clone')
  @DocsEditable()
  @Experimental() // untriaged
  MediaStream clone() native;

  @DomName('MediaStream.getAudioTracks')
  @DocsEditable()
  @Creates('JSExtendableArray|MediaStreamTrack')
  @Returns('JSExtendableArray')
  List<MediaStreamTrack> getAudioTracks() native;

  @DomName('MediaStream.getTrackById')
  @DocsEditable()
  MediaStreamTrack getTrackById(String trackId) native;

  @DomName('MediaStream.getTracks')
  @DocsEditable()
  @Experimental() // untriaged
  List<MediaStreamTrack> getTracks() native;

  @DomName('MediaStream.getVideoTracks')
  @DocsEditable()
  @Creates('JSExtendableArray|MediaStreamTrack')
  @Returns('JSExtendableArray')
  List<MediaStreamTrack> getVideoTracks() native;

  @DomName('MediaStream.removeTrack')
  @DocsEditable()
  void removeTrack(MediaStreamTrack track) native;

  /// Stream of `addtrack` events handled by this [MediaStream].
  @DomName('MediaStream.onaddtrack')
  @DocsEditable()
  Stream<Event> get onAddTrack => addTrackEvent.forTarget(this);

  /// Stream of `ended` events handled by this [MediaStream].
  @DomName('MediaStream.onended')
  @DocsEditable()
  Stream<Event> get onEnded => endedEvent.forTarget(this);

  /// Stream of `removetrack` events handled by this [MediaStream].
  @DomName('MediaStream.onremovetrack')
  @DocsEditable()
  Stream<Event> get onRemoveTrack => removeTrackEvent.forTarget(this);

  /**
   * Checks if the MediaStream APIs are supported on the current platform.
   *
   * See also:
   *
   * * [Navigator.getUserMedia]
   */
  static bool get supported => JS(
      'bool',
      '''!!(#.getUserMedia || #.webkitGetUserMedia ||
        #.mozGetUserMedia || #.msGetUserMedia)''',
      window.navigator,
      window.navigator,
      window.navigator,
      window.navigator);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MediaStreamEvent')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html
@Native("MediaStreamEvent")
class MediaStreamEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MediaStreamEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MediaStreamEvent.MediaStreamEvent')
  @DocsEditable()
  factory MediaStreamEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return MediaStreamEvent._create_1(type, eventInitDict_1);
    }
    return MediaStreamEvent._create_2(type);
  }
  static MediaStreamEvent _create_1(type, eventInitDict) =>
      JS('MediaStreamEvent', 'new MediaStreamEvent(#,#)', type, eventInitDict);
  static MediaStreamEvent _create_2(type) =>
      JS('MediaStreamEvent', 'new MediaStreamEvent(#)', type);

  /// Checks if this type is supported on the current platform.
  static bool get supported => Device.isEventTypeSupported('MediaStreamEvent');

  @DomName('MediaStreamEvent.stream')
  @DocsEditable()
  final MediaStream stream;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MediaStreamTrack')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html#mediastreamtrack
@Native("MediaStreamTrack")
class MediaStreamTrack extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaStreamTrack._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `ended` events to event
   * handlers that are not necessarily instances of [MediaStreamTrack].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MediaStreamTrack.endedEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> endedEvent =
      const EventStreamProvider<Event>('ended');

  /**
   * Static factory designed to expose `mute` events to event
   * handlers that are not necessarily instances of [MediaStreamTrack].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MediaStreamTrack.muteEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> muteEvent =
      const EventStreamProvider<Event>('mute');

  /**
   * Static factory designed to expose `unmute` events to event
   * handlers that are not necessarily instances of [MediaStreamTrack].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MediaStreamTrack.unmuteEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> unmuteEvent =
      const EventStreamProvider<Event>('unmute');

  @DomName('MediaStreamTrack.enabled')
  @DocsEditable()
  bool enabled;

  @DomName('MediaStreamTrack.id')
  @DocsEditable()
  final String id;

  @DomName('MediaStreamTrack.kind')
  @DocsEditable()
  final String kind;

  @DomName('MediaStreamTrack.label')
  @DocsEditable()
  final String label;

  @DomName('MediaStreamTrack.muted')
  @DocsEditable()
  @Experimental() // untriaged
  final bool muted;

  @DomName('MediaStreamTrack.readyState')
  @DocsEditable()
  final String readyState;

  @DomName('MediaStreamTrack.remote')
  @DocsEditable()
  @Experimental() // untriaged
  final bool remote;

  @DomName('MediaStreamTrack.clone')
  @DocsEditable()
  @Experimental() // untriaged
  MediaStreamTrack clone() native;

  @JSName('getSources')
  @DomName('MediaStreamTrack.getSources')
  @DocsEditable()
  @Experimental() // untriaged
  static void _getSources(MediaStreamTrackSourcesCallback callback) native;

  @JSName('getSources')
  @DomName('MediaStreamTrack.getSources')
  @DocsEditable()
  @Experimental() // untriaged
  static Future<List<SourceInfo>> getSources() {
    var completer = new Completer<List<SourceInfo>>();
    _getSources((value) {
      completer.complete(value);
    });
    return completer.future;
  }

  @DomName('MediaStreamTrack.stop')
  @DocsEditable()
  @Experimental() // untriaged
  void stop() native;

  /// Stream of `ended` events handled by this [MediaStreamTrack].
  @DomName('MediaStreamTrack.onended')
  @DocsEditable()
  Stream<Event> get onEnded => endedEvent.forTarget(this);

  /// Stream of `mute` events handled by this [MediaStreamTrack].
  @DomName('MediaStreamTrack.onmute')
  @DocsEditable()
  Stream<Event> get onMute => muteEvent.forTarget(this);

  /// Stream of `unmute` events handled by this [MediaStreamTrack].
  @DomName('MediaStreamTrack.onunmute')
  @DocsEditable()
  Stream<Event> get onUnmute => unmuteEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MediaStreamTrackEvent')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html
@Native("MediaStreamTrackEvent")
class MediaStreamTrackEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MediaStreamTrackEvent._() {
    throw new UnsupportedError("Not supported");
  }

  /// Checks if this type is supported on the current platform.
  static bool get supported =>
      Device.isEventTypeSupported('MediaStreamTrackEvent');

  @DomName('MediaStreamTrackEvent.track')
  @DocsEditable()
  final MediaStreamTrack track;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('MediaStreamTrackSourcesCallback')
@Experimental() // untriaged
typedef void MediaStreamTrackSourcesCallback(List<SourceInfo> sources);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MemoryInfo')
@Experimental() // nonstandard
@Native("MemoryInfo")
class MemoryInfo extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MemoryInfo._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MemoryInfo.jsHeapSizeLimit')
  @DocsEditable()
  final int jsHeapSizeLimit;

  @DomName('MemoryInfo.totalJSHeapSize')
  @DocsEditable()
  final int totalJSHeapSize;

  @DomName('MemoryInfo.usedJSHeapSize')
  @DocsEditable()
  final int usedJSHeapSize;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
/**
 * An HTML <menu> element.
 *
 * A <menu> element represents an unordered list of menu commands.
 *
 * See also:
 *
 *  * [Menu Element](https://developer.mozilla.org/en-US/docs/HTML/Element/menu) from MDN.
 *  * [Menu Element](http://www.w3.org/TR/html5/the-menu-element.html#the-menu-element) from the W3C.
 */
@DomName('HTMLMenuElement')
@Native("HTMLMenuElement")
class MenuElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory MenuElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLMenuElement.HTMLMenuElement')
  @DocsEditable()
  factory MenuElement() => JS(
      'returns:MenuElement;creates:MenuElement;new:true',
      '#.createElement(#)',
      document,
      "menu");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  MenuElement.created() : super.created();

  @DomName('HTMLMenuElement.label')
  @DocsEditable()
  @Experimental() // untriaged
  String label;

  @DomName('HTMLMenuElement.type')
  @DocsEditable()
  @Experimental() // untriaged
  String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLMenuItemElement')
@Experimental() // untriaged
@Native("HTMLMenuItemElement")
class MenuItemElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory MenuItemElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  MenuItemElement.created() : super.created();

  @DomName('HTMLMenuItemElement.checked')
  @DocsEditable()
  @Experimental() // untriaged
  bool checked;

  @JSName('default')
  @DomName('HTMLMenuItemElement.default')
  @DocsEditable()
  @Experimental() // untriaged
  bool defaultValue;

  @DomName('HTMLMenuItemElement.disabled')
  @DocsEditable()
  @Experimental() // untriaged
  bool disabled;

  @DomName('HTMLMenuItemElement.icon')
  @DocsEditable()
  @Experimental() // untriaged
  String icon;

  @DomName('HTMLMenuItemElement.label')
  @DocsEditable()
  @Experimental() // untriaged
  String label;

  @DomName('HTMLMenuItemElement.radiogroup')
  @DocsEditable()
  @Experimental() // untriaged
  String radiogroup;

  @DomName('HTMLMenuItemElement.type')
  @DocsEditable()
  @Experimental() // untriaged
  String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MessageChannel')
@Unstable()
@Native("MessageChannel")
class MessageChannel extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MessageChannel._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MessageChannel.port1')
  @DocsEditable()
  final MessagePort port1;

  @DomName('MessageChannel.port2')
  @DocsEditable()
  final MessagePort port2;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('MessageEvent')
@Native("MessageEvent")
class MessageEvent extends Event {
  factory MessageEvent(String type,
      {bool canBubble: false,
      bool cancelable: false,
      Object data,
      String origin,
      String lastEventId,
      Window source,
      List<MessagePort> messagePorts}) {
    if (source == null) {
      source = window;
    }
    if (!Device.isIE) {
      // TODO: This if check should be removed once IE
      // implements the constructor.
      return JS(
          'MessageEvent',
          'new MessageEvent(#, {bubbles: #, cancelable: #, data: #, origin: #, lastEventId: #, source: #, ports: #})',
          type,
          canBubble,
          cancelable,
          data,
          origin,
          lastEventId,
          source,
          messagePorts);
    }
    MessageEvent event = document._createEvent("MessageEvent");
    event._initMessageEvent(type, canBubble, cancelable, data, origin,
        lastEventId, source, messagePorts);
    return event;
  }

  // TODO(alanknight): This really should be generated by the
  // _OutputConversion in the systemnative.py script, but that doesn't
  // use those conversions right now, so do this as a one-off.
  @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.MessageEvent')
  @DocsEditable()
  factory MessageEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return MessageEvent._create_1(type, eventInitDict_1);
    }
    return MessageEvent._create_2(type);
  }
  static MessageEvent _create_1(type, eventInitDict) =>
      JS('MessageEvent', 'new MessageEvent(#,#)', type, eventInitDict);
  static MessageEvent _create_2(type) =>
      JS('MessageEvent', 'new MessageEvent(#)', type);

  @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;

  @DomName('MessageEvent.suborigin')
  @DocsEditable()
  @Experimental() // untriaged
  final String suborigin;

  @JSName('initMessageEvent')
  @DomName('MessageEvent.initMessageEvent')
  @DocsEditable()
  void _initMessageEvent(
      String typeArg,
      bool canBubbleArg,
      bool cancelableArg,
      Object dataArg,
      String originArg,
      String lastEventIdArg,
      Window sourceArg,
      List<MessagePort> portsArg) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MessagePort')
@Unstable()
@Native("MessagePort")
class MessagePort extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MessagePort._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [MessagePort].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MessagePort.messageEvent')
  @DocsEditable()
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  @DomName('MessagePort.close')
  @DocsEditable()
  void close() native;

  @DomName('MessagePort.postMessage')
  @DocsEditable()
  void postMessage(/*any*/ message, [List<MessagePort> transfer]) {
    if (transfer != null) {
      var message_1 = convertDartToNative_SerializedScriptValue(message);
      _postMessage_1(message_1, transfer);
      return;
    }
    var message_1 = convertDartToNative_SerializedScriptValue(message);
    _postMessage_2(message_1);
    return;
  }

  @JSName('postMessage')
  @DomName('MessagePort.postMessage')
  @DocsEditable()
  void _postMessage_1(message, List<MessagePort> transfer) native;
  @JSName('postMessage')
  @DomName('MessagePort.postMessage')
  @DocsEditable()
  void _postMessage_2(message) native;

  @DomName('MessagePort.start')
  @DocsEditable()
  void start() native;

  /// Stream of `message` events handled by this [MessagePort].
  @DomName('MessagePort.onmessage')
  @DocsEditable()
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLMetaElement')
@Native("HTMLMetaElement")
class MetaElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory MetaElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLMetaElement.HTMLMetaElement')
  @DocsEditable()
  factory MetaElement() => JS(
      'returns:MetaElement;creates:MetaElement;new:true',
      '#.createElement(#)',
      document,
      "meta");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  MetaElement.created() : super.created();

  @DomName('HTMLMetaElement.content')
  @DocsEditable()
  String content;

  @DomName('HTMLMetaElement.httpEquiv')
  @DocsEditable()
  String httpEquiv;

  @DomName('HTMLMetaElement.name')
  @DocsEditable()
  String name;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('Metadata')
// http://www.w3.org/TR/file-system-api/#the-metadata-interface
@Experimental()
@Native("Metadata")
class Metadata extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Metadata._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Metadata.modificationTime')
  @DocsEditable()
  DateTime get modificationTime =>
      convertNativeToDart_DateTime(this._get_modificationTime);
  @JSName('modificationTime')
  @DomName('Metadata.modificationTime')
  @DocsEditable()
  @Creates('Null')
  final dynamic _get_modificationTime;

  @DomName('Metadata.size')
  @DocsEditable()
  final int size;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('MetadataCallback')
// http://www.w3.org/TR/file-system-api/#idl-def-MetadataCallback
@Experimental()
typedef void MetadataCallback(Metadata metadata);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLMeterElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
@Native("HTMLMeterElement")
class MeterElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory MeterElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLMeterElement.HTMLMeterElement')
  @DocsEditable()
  factory MeterElement() => document.createElement("meter");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  MeterElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('meter');

  @DomName('HTMLMeterElement.high')
  @DocsEditable()
  num high;

  @DomName('HTMLMeterElement.labels')
  @DocsEditable()
  @Unstable()
  @Returns('NodeList|Null')
  @Creates('NodeList')
  final List<Node> labels;

  @DomName('HTMLMeterElement.low')
  @DocsEditable()
  num low;

  @DomName('HTMLMeterElement.max')
  @DocsEditable()
  num max;

  @DomName('HTMLMeterElement.min')
  @DocsEditable()
  num min;

  @DomName('HTMLMeterElement.optimum')
  @DocsEditable()
  num optimum;

  @DomName('HTMLMeterElement.value')
  @DocsEditable()
  num value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MIDIAccess')
// http://webaudio.github.io/web-midi-api/#midiaccess-interface
@Experimental()
@Native("MIDIAccess")
class MidiAccess extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MidiAccess._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MIDIAccess.inputs')
  @DocsEditable()
  final MidiInputMap inputs;

  @DomName('MIDIAccess.outputs')
  @DocsEditable()
  final MidiOutputMap outputs;

  @DomName('MIDIAccess.sysexEnabled')
  @DocsEditable()
  @Experimental() // untriaged
  final bool sysexEnabled;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MIDIConnectionEvent')
// http://webaudio.github.io/web-midi-api/#midiconnectionevent-interface
@Experimental()
@Native("MIDIConnectionEvent")
class MidiConnectionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MidiConnectionEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MIDIConnectionEvent.MIDIConnectionEvent')
  @DocsEditable()
  factory MidiConnectionEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return MidiConnectionEvent._create_1(type, eventInitDict_1);
    }
    return MidiConnectionEvent._create_2(type);
  }
  static MidiConnectionEvent _create_1(type, eventInitDict) => JS(
      'MidiConnectionEvent',
      'new MIDIConnectionEvent(#,#)',
      type,
      eventInitDict);
  static MidiConnectionEvent _create_2(type) =>
      JS('MidiConnectionEvent', 'new MIDIConnectionEvent(#)', type);

  @DomName('MIDIConnectionEvent.port')
  @DocsEditable()
  final MidiPort port;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MIDIInput')
// http://webaudio.github.io/web-midi-api/#idl-def-MIDIInput
@Experimental()
@Native("MIDIInput")
class MidiInput extends MidiPort {
  // To suppress missing implicit constructor warnings.
  factory MidiInput._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `midimessage` events to event
   * handlers that are not necessarily instances of [MidiInput].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('MIDIInput.midimessageEvent')
  @DocsEditable()
  static const EventStreamProvider<MidiMessageEvent> midiMessageEvent =
      const EventStreamProvider<MidiMessageEvent>('midimessage');

  /// Stream of `midimessage` events handled by this [MidiInput].
  @DomName('MIDIInput.onmidimessage')
  @DocsEditable()
  Stream<MidiMessageEvent> get onMidiMessage =>
      midiMessageEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MIDIInputMap')
@Experimental() // untriaged
@Native("MIDIInputMap")
class MidiInputMap extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MidiInputMap._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MIDIInputMap.size')
  @DocsEditable()
  @Experimental() // untriaged
  final int size;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MIDIMessageEvent')
// http://webaudio.github.io/web-midi-api/#midimessageevent-interface
@Experimental()
@Native("MIDIMessageEvent")
class MidiMessageEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MidiMessageEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MIDIMessageEvent.MIDIMessageEvent')
  @DocsEditable()
  factory MidiMessageEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return MidiMessageEvent._create_1(type, eventInitDict_1);
    }
    return MidiMessageEvent._create_2(type);
  }
  static MidiMessageEvent _create_1(type, eventInitDict) =>
      JS('MidiMessageEvent', 'new MIDIMessageEvent(#,#)', type, eventInitDict);
  static MidiMessageEvent _create_2(type) =>
      JS('MidiMessageEvent', 'new MIDIMessageEvent(#)', type);

  @DomName('MIDIMessageEvent.data')
  @DocsEditable()
  final Uint8List data;

  @DomName('MIDIMessageEvent.receivedTime')
  @DocsEditable()
  final double receivedTime;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MIDIOutput')
// http://webaudio.github.io/web-midi-api/#midioutput-interface
@Experimental()
@Native("MIDIOutput")
class MidiOutput extends MidiPort {
  // To suppress missing implicit constructor warnings.
  factory MidiOutput._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MIDIOutput.send')
  @DocsEditable()
  void send(Uint8List data, [num timestamp]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MIDIOutputMap')
@Experimental() // untriaged
@Native("MIDIOutputMap")
class MidiOutputMap extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MidiOutputMap._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MIDIOutputMap.size')
  @DocsEditable()
  @Experimental() // untriaged
  final int size;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MIDIPort')
// http://webaudio.github.io/web-midi-api/#idl-def-MIDIPort
@Experimental()
@Native("MIDIPort")
class MidiPort extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MidiPort._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MIDIPort.connection')
  @DocsEditable()
  @Experimental() // untriaged
  final String connection;

  @DomName('MIDIPort.id')
  @DocsEditable()
  final String id;

  @DomName('MIDIPort.manufacturer')
  @DocsEditable()
  final String manufacturer;

  @DomName('MIDIPort.name')
  @DocsEditable()
  final String name;

  @DomName('MIDIPort.state')
  @DocsEditable()
  @Experimental() // untriaged
  final String state;

  @DomName('MIDIPort.type')
  @DocsEditable()
  final String type;

  @DomName('MIDIPort.version')
  @DocsEditable()
  final String version;

  @DomName('MIDIPort.close')
  @DocsEditable()
  @Experimental() // untriaged
  Future close() native;

  @DomName('MIDIPort.open')
  @DocsEditable()
  @Experimental() // untriaged
  Future open() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MimeType')
@Experimental() // non-standard
@Native("MimeType")
class MimeType extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MimeType._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MimeType.description')
  @DocsEditable()
  final String description;

  @DomName('MimeType.enabledPlugin')
  @DocsEditable()
  final Plugin enabledPlugin;

  @DomName('MimeType.suffixes')
  @DocsEditable()
  final String suffixes;

  @DomName('MimeType.type')
  @DocsEditable()
  final String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MimeTypeArray')
@Experimental() // non-standard
@Native("MimeTypeArray")
class MimeTypeArray extends Interceptor
    with ListMixin<MimeType>, ImmutableListMixin<MimeType>
    implements List<MimeType>, JavaScriptIndexingBehavior<MimeType> {
  // To suppress missing implicit constructor warnings.
  factory MimeTypeArray._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MimeTypeArray.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  MimeType operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("MimeType", "#[#]", this, index);
  }

  void operator []=(int index, MimeType value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<MimeType> mixins.
  // MimeType is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  MimeType get first {
    if (this.length > 0) {
      return JS('MimeType', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  MimeType get last {
    int len = this.length;
    if (len > 0) {
      return JS('MimeType', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  MimeType get single {
    int len = this.length;
    if (len == 1) {
      return JS('MimeType', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  MimeType elementAt(int index) => this[index];
  // -- end List<MimeType> mixins.

  @DomName('MimeTypeArray.item')
  @DocsEditable()
  MimeType item(int index) native;

  @DomName('MimeTypeArray.namedItem')
  @DocsEditable()
  MimeType namedItem(String name) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLModElement')
@Unstable()
@Native("HTMLModElement")
class ModElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ModElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ModElement.created() : super.created();

  @DomName('HTMLModElement.cite')
  @DocsEditable()
  String cite;

  @DomName('HTMLModElement.dateTime')
  @DocsEditable()
  String dateTime;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DomName('MouseEvent')
@Native("MouseEvent,DragEvent")
class MouseEvent extends UIEvent {
  factory MouseEvent(String type,
      {Window view,
      int detail: 0,
      int screenX: 0,
      int screenY: 0,
      int clientX: 0,
      int clientY: 0,
      int button: 0,
      bool canBubble: true,
      bool cancelable: true,
      bool ctrlKey: false,
      bool altKey: false,
      bool shiftKey: false,
      bool metaKey: false,
      EventTarget relatedTarget}) {
    if (view == null) {
      view = window;
    }
    MouseEvent event = document._createEvent('MouseEvent');
    event._initMouseEvent(
        type,
        canBubble,
        cancelable,
        view,
        detail,
        screenX,
        screenY,
        clientX,
        clientY,
        ctrlKey,
        altKey,
        shiftKey,
        metaKey,
        button,
        relatedTarget);
    return event;
  }

  @DomName('MouseEvent.MouseEvent')
  @DocsEditable()
  factory MouseEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return MouseEvent._create_1(type, eventInitDict_1);
    }
    return MouseEvent._create_2(type);
  }
  static MouseEvent _create_1(type, eventInitDict) =>
      JS('MouseEvent', 'new MouseEvent(#,#)', type, eventInitDict);
  static MouseEvent _create_2(type) =>
      JS('MouseEvent', 'new MouseEvent(#)', type);

  @DomName('MouseEvent.altKey')
  @DocsEditable()
  final bool altKey;

  @DomName('MouseEvent.button')
  @DocsEditable()
  final int button;

  @DomName('MouseEvent.buttons')
  @DocsEditable()
  @Experimental() // untriaged
  final int buttons;

  @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;

  /**
   * The nonstandard way to access the element that the mouse comes
   * from in the case of a `mouseover` event.
   *
   * This member is deprecated and not cross-browser compatible; use
   * relatedTarget to get the same information in the standard way.
   */
  @DomName('MouseEvent.fromElement')
  @DocsEditable()
  @deprecated
  final Node fromElement;

  @JSName('layerX')
  @DomName('MouseEvent.layerX')
  @DocsEditable()
  @Experimental() // untriaged
  final int _layerX;

  @JSName('layerY')
  @DomName('MouseEvent.layerY')
  @DocsEditable()
  @Experimental() // untriaged
  final int _layerY;

  @DomName('MouseEvent.metaKey')
  @DocsEditable()
  final bool metaKey;

  @JSName('movementX')
  @DomName('MouseEvent.movementX')
  @DocsEditable()
  @Experimental() // untriaged
  final int _movementX;

  @JSName('movementY')
  @DomName('MouseEvent.movementY')
  @DocsEditable()
  @Experimental() // untriaged
  final int _movementY;

  @JSName('pageX')
  @DomName('MouseEvent.pageX')
  @DocsEditable()
  @Experimental() // untriaged
  final int _pageX;

  @JSName('pageY')
  @DomName('MouseEvent.pageY')
  @DocsEditable()
  @Experimental() // untriaged
  final int _pageY;

  @DomName('MouseEvent.region')
  @DocsEditable()
  @Experimental() // untriaged
  final String region;

  @DomName('MouseEvent.relatedTarget')
  @DocsEditable()
  EventTarget get relatedTarget =>
      _convertNativeToDart_EventTarget(this._get_relatedTarget);
  @JSName('relatedTarget')
  @DomName('MouseEvent.relatedTarget')
  @DocsEditable()
  @Creates('Node')
  @Returns('EventTarget|=Object')
  final dynamic _get_relatedTarget;

  @JSName('screenX')
  @DomName('MouseEvent.screenX')
  @DocsEditable()
  final int _screenX;

  @JSName('screenY')
  @DomName('MouseEvent.screenY')
  @DocsEditable()
  final int _screenY;

  @DomName('MouseEvent.shiftKey')
  @DocsEditable()
  final bool shiftKey;

  /**
   * The nonstandard way to access the element that the mouse goes
   * to in the case of a `mouseout` event.
   *
   * This member is deprecated and not cross-browser compatible; use
   * relatedTarget to get the same information in the standard way.
   */
  @DomName('MouseEvent.toElement')
  @DocsEditable()
  @deprecated
  final Node toElement;

  // Use implementation from UIEvent.
  // final int _which;

  @DomName('MouseEvent.getModifierState')
  @DocsEditable()
  @Experimental() // untriaged
  bool getModifierState(String keyArg) native;

  @DomName('MouseEvent.initMouseEvent')
  @DocsEditable()
  void _initMouseEvent(
      String type,
      bool bubbles,
      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,
        bubbles,
        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,
      bubbles,
      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/*<num>*/(_clientX, _clientY);

  @DomName('MouseEvent.movementX')
  @DomName('MouseEvent.movementY')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @Experimental()
  Point get movement => new Point/*<num>*/(_movementX, _movementY);

  /**
   * 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/*<num>*/(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/*<num>*/(point.x.toInt(), point.y.toInt());
    }
  }

  @DomName('MouseEvent.screenX')
  @DomName('MouseEvent.screenY')
  Point get screen => new Point/*<num>*/(_screenX, _screenY);

  @DomName('MouseEvent.layerX')
  @DomName('MouseEvent.layerY')
  Point get layer => new Point/*<num>*/(_layerX, _layerY);

  @DomName('MouseEvent.pageX')
  @DomName('MouseEvent.pageY')
  Point get page => new Point/*<num>*/(_pageX, _pageY);

  @DomName('MouseEvent.dataTransfer')
  DataTransfer get dataTransfer =>
      JS('DataTransfer', "#['dataTransfer']", 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('MutationCallback')
typedef void MutationCallback(
    List<MutationRecord> mutations, MutationObserver observer);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DomName('MutationObserver')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
@Native("MutationObserver,WebKitMutationObserver")
class MutationObserver extends Interceptor {
  @DomName('MutationObserver.disconnect')
  @DocsEditable()
  void disconnect() native;

  @DomName('MutationObserver.observe')
  @DocsEditable()
  void _observe(Node target, Map options) {
    var options_1 = convertDartToNative_Dictionary(options);
    _observe_1(target, options_1);
    return;
  }

  @JSName('observe')
  @DomName('MutationObserver.observe')
  @DocsEditable()
  void _observe_1(Node target, options) native;

  @DomName('MutationObserver.takeRecords')
  @DocsEditable()
  List<MutationRecord> takeRecords() native;

  /**
   * Checks to see if the mutation observer API is supported on the current
   * platform.
   */
  static bool get supported {
    return JS(
        'bool', '!!(window.MutationObserver || window.WebKitMutationObserver)');
  }

  /**
   * Observes the target for the specified changes.
   *
   * Some requirements for the optional parameters:
   *
   * * Either childList, attributes or characterData must be true.
   * * If attributeOldValue is true then attributes must also be true.
   * * If attributeFilter is specified then attributes must be true.
   * * If characterDataOldValue is true then characterData must be true.
   */
  void observe(Node target,
      {bool childList,
      bool attributes,
      bool characterData,
      bool subtree,
      bool attributeOldValue,
      bool characterDataOldValue,
      List<String> attributeFilter}) {
    // Parse options into map of known type.
    var parsedOptions = _createDict();

    // Override options passed in the map with named optional arguments.
    override(key, value) {
      if (value != null) _add(parsedOptions, key, value);
    }

    override('childList', childList);
    override('attributes', attributes);
    override('characterData', characterData);
    override('subtree', subtree);
    override('attributeOldValue', attributeOldValue);
    override('characterDataOldValue', characterDataOldValue);
    if (attributeFilter != null) {
      override('attributeFilter', _fixupList(attributeFilter));
    }

    _call(target, parsedOptions);
  }

  // TODO: Change to a set when const Sets are available.
  static final _boolKeys = const {
    'childList': true,
    'attributes': true,
    'characterData': true,
    'subtree': true,
    'attributeOldValue': true,
    'characterDataOldValue': true
  };

  static _createDict() => JS('var', '{}');
  static _add(m, String key, value) {
    JS('void', '#[#] = #', m, key, value);
  }

  static _fixupList(list) => list; // TODO: Ensure is a JavaScript Array.

  // Call native function with no conversions.
  @JSName('observe')
  void _call(target, options) native;

  factory MutationObserver(MutationCallback callback) {
    // Dummy statement to mark types as instantiated.
    JS('MutationObserver|MutationRecord', '0');

    return JS(
        'MutationObserver',
        'new(window.MutationObserver||window.WebKitMutationObserver||'
        'window.MozMutationObserver)(#)',
        convertDartClosureToJS(_wrapBinaryZone(callback), 2));
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('MutationRecord')
@Native("MutationRecord")
class MutationRecord extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory MutationRecord._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('MutationRecord.addedNodes')
  @DocsEditable()
  @Returns('NodeList|Null')
  @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|Null')
  @Creates('NodeList')
  final List<Node> removedNodes;

  @DomName('MutationRecord.target')
  @DocsEditable()
  final Node target;

  @DomName('MutationRecord.type')
  @DocsEditable()
  final String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DomName('Navigator')
@Native("Navigator")
class Navigator extends Interceptor
    implements
        NavigatorStorageUtils,
        NavigatorCpu,
        NavigatorLanguage,
        NavigatorOnLine,
        NavigatorID {
  @DomName('Navigator.language')
  String get language =>
      JS('String', '#.language || #.userLanguage', this, this);

  /**
   * Gets a stream (video and or audio) from the local computer.
   *
   * Use [MediaStream.supported] to check if this is supported by the current
   * platform. The arguments `audio` and `video` default to `false` (stream does
   * not use audio or video, respectively).
   *
   * Simple example usage:
   *
   *     window.navigator.getUserMedia(audio: true, video: true).then((stream) {
   *       var video = new VideoElement()
   *         ..autoplay = true
   *         ..src = Url.createObjectUrlFromStream(stream);
   *       document.body.append(video);
   *     });
   *
   * The user can also pass in Maps to the audio or video parameters to specify
   * mandatory and optional constraints for the media stream. Not passing in a
   * map, but passing in `true` will provide a MediaStream with audio or
   * video capabilities, but without any additional constraints. The particular
   * constraint names for audio and video are still in flux, but as of this
   * writing, here is an example providing more constraints.
   *
   *     window.navigator.getUserMedia(
   *         audio: true,
   *         video: {'mandatory':
   *                    { 'minAspectRatio': 1.333, 'maxAspectRatio': 1.334 },
   *                 'optional':
   *                    [{ 'minFrameRate': 60 },
   *                     { 'maxWidth': 640 }]
   *     });
   *
   * See also:
   * * [MediaStream.supported]
   */
  @DomName('Navigator.webkitGetUserMedia')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @Experimental()
  Future<MediaStream> getUserMedia({audio: false, video: false}) {
    var completer = new Completer<MediaStream>();
    var options = {'audio': audio, 'video': video};
    _ensureGetUserMedia();
    this._getUserMedia(convertDartToNative_SerializedScriptValue(options),
        (stream) {
      completer.complete(stream);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  _ensureGetUserMedia() {
    if (JS('bool', '!(#.getUserMedia)', this)) {
      JS(
          'void',
          '#.getUserMedia = '
          '(#.getUserMedia || #.webkitGetUserMedia || #.mozGetUserMedia ||'
          '#.msGetUserMedia)',
          this,
          this,
          this,
          this,
          this);
    }
  }

  @JSName('getUserMedia')
  void _getUserMedia(options, _NavigatorUserMediaSuccessCallback success,
      _NavigatorUserMediaErrorCallback error) native;

  // To suppress missing implicit constructor warnings.
  factory Navigator._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Navigator.connection')
  @DocsEditable()
  @Experimental() // untriaged
  final NetworkInformation connection;

  @DomName('Navigator.credentials')
  @DocsEditable()
  @Experimental() // untriaged
  final CredentialsContainer credentials;

  @DomName('Navigator.doNotTrack')
  @DocsEditable()
  // http://www.w3.org/2011/tracking-protection/drafts/tracking-dnt.html#js-dom
  @Experimental() // experimental
  final String doNotTrack;

  @DomName('Navigator.geolocation')
  @DocsEditable()
  @Unstable()
  final Geolocation geolocation;

  @DomName('Navigator.maxTouchPoints')
  @DocsEditable()
  @Experimental() // untriaged
  final int maxTouchPoints;

  @DomName('Navigator.mediaDevices')
  @DocsEditable()
  @Experimental() // untriaged
  final MediaDevices mediaDevices;

  @DomName('Navigator.mimeTypes')
  @DocsEditable()
  @Experimental() // nonstandard
  final MimeTypeArray mimeTypes;

  @DomName('Navigator.nfc')
  @DocsEditable()
  @Experimental() // untriaged
  final _NFC nfc;

  @DomName('Navigator.permissions')
  @DocsEditable()
  @Experimental() // untriaged
  final Permissions permissions;

  @DomName('Navigator.presentation')
  @DocsEditable()
  @Experimental() // untriaged
  final Presentation presentation;

  @DomName('Navigator.productSub')
  @DocsEditable()
  @Unstable()
  final String productSub;

  @DomName('Navigator.serviceWorker')
  @DocsEditable()
  @Experimental() // untriaged
  final ServiceWorkerContainer serviceWorker;

  @DomName('Navigator.services')
  @DocsEditable()
  @Experimental() // untriaged
  final ServicePortCollection services;

  @DomName('Navigator.storage')
  @DocsEditable()
  @Experimental() // untriaged
  final StorageManager storage;

  @DomName('Navigator.storageQuota')
  @DocsEditable()
  @Experimental() // untriaged
  final StorageQuota storageQuota;

  @DomName('Navigator.vendor')
  @DocsEditable()
  @Unstable()
  final String vendor;

  @DomName('Navigator.vendorSub')
  @DocsEditable()
  @Unstable()
  final String vendorSub;

  @JSName('webkitPersistentStorage')
  @DomName('Navigator.webkitPersistentStorage')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.w3.org/TR/quota-api/#accessing-storagequota
  final DeprecatedStorageQuota persistentStorage;

  @JSName('webkitTemporaryStorage')
  @DomName('Navigator.webkitTemporaryStorage')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.w3.org/TR/quota-api/#accessing-storagequota
  final DeprecatedStorageQuota temporaryStorage;

  @DomName('Navigator.getBattery')
  @DocsEditable()
  @Experimental() // untriaged
  Future getBattery() native;

  @DomName('Navigator.getGamepads')
  @DocsEditable()
  @Experimental() // untriaged
  @Returns('_GamepadList|Null')
  @Creates('_GamepadList')
  List<Gamepad> getGamepads() native;

  @DomName('Navigator.getVRDevices')
  @DocsEditable()
  @Experimental() // untriaged
  Future getVRDevices() native;

  @DomName('Navigator.registerProtocolHandler')
  @DocsEditable()
  @Unstable()
  void registerProtocolHandler(String scheme, String url, String title) native;

  @DomName('Navigator.requestMIDIAccess')
  @DocsEditable()
  @Experimental() // untriaged
  Future 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
  Future _requestMidiAccess_1(options) native;
  @JSName('requestMIDIAccess')
  @DomName('Navigator.requestMIDIAccess')
  @DocsEditable()
  @Experimental() // untriaged
  Future _requestMidiAccess_2() native;

  @DomName('Navigator.requestMediaKeySystemAccess')
  @DocsEditable()
  @Experimental() // untriaged
  Future requestMediaKeySystemAccess(
      String keySystem, List<Map> supportedConfigurations) native;

  @DomName('Navigator.sendBeacon')
  @DocsEditable()
  @Experimental() // untriaged
  bool sendBeacon(String url, Object data) native;

  // From NavigatorCPU

  @DomName('Navigator.hardwareConcurrency')
  @DocsEditable()
  @Experimental() // untriaged
  final int hardwareConcurrency;

  // From NavigatorID

  @DomName('Navigator.appCodeName')
  @DocsEditable()
  @Experimental() // non-standard
  final String appCodeName;

  @DomName('Navigator.appName')
  @DocsEditable()
  final String appName;

  @DomName('Navigator.appVersion')
  @DocsEditable()
  final String appVersion;

  @DomName('Navigator.dartEnabled')
  @DocsEditable()
  @Experimental() // untriaged
  final bool dartEnabled;

  @DomName('Navigator.platform')
  @DocsEditable()
  final String platform;

  @DomName('Navigator.product')
  @DocsEditable()
  @Unstable()
  final String product;

  @DomName('Navigator.userAgent')
  @DocsEditable()
  final String userAgent;

  // From NavigatorLanguage

  @DomName('Navigator.languages')
  @DocsEditable()
  @Experimental() // untriaged
  final List<String> languages;

  // From NavigatorOnLine

  @DomName('Navigator.onLine')
  @DocsEditable()
  @Unstable()
  final bool onLine;

  // From NavigatorStorageUtils

  @DomName('Navigator.cookieEnabled')
  @DocsEditable()
  @Unstable()
  final bool cookieEnabled;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('NavigatorCPU')
@Experimental() // untriaged
abstract class NavigatorCpu extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigatorCpu._() {
    throw new UnsupportedError("Not supported");
  }

  final int hardwareConcurrency;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('NavigatorID')
@Experimental() // untriaged
abstract class NavigatorID extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigatorID._() {
    throw new UnsupportedError("Not supported");
  }

  final String appCodeName;

  final String appName;

  final String appVersion;

  final bool dartEnabled;

  final String platform;

  final String product;

  final String userAgent;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('NavigatorLanguage')
@Experimental() // untriaged
abstract class NavigatorLanguage extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigatorLanguage._() {
    throw new UnsupportedError("Not supported");
  }

  final String language;

  final List<String> languages;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('NavigatorOnLine')
@Experimental() // untriaged
abstract class NavigatorOnLine extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigatorOnLine._() {
    throw new UnsupportedError("Not supported");
  }

  final bool onLine;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('NavigatorStorageUtils')
@Experimental() // untriaged
@Native("NavigatorStorageUtils")
class NavigatorStorageUtils extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigatorStorageUtils._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('NavigatorStorageUtils.cookieEnabled')
  @DocsEditable()
  @Experimental() // untriaged
  final bool cookieEnabled;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('NavigatorUserMediaError')
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html#idl-def-NavigatorUserMediaError
@Experimental()
@Native("NavigatorUserMediaError")
class NavigatorUserMediaError extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NavigatorUserMediaError._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('NavigatorUserMediaError.constraintName')
  @DocsEditable()
  final String constraintName;

  @DomName('NavigatorUserMediaError.message')
  @DocsEditable()
  final String message;

  @DomName('NavigatorUserMediaError.name')
  @DocsEditable()
  final String name;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('NavigatorUserMediaErrorCallback')
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html#idl-def-NavigatorUserMediaErrorCallback
@Experimental()
typedef void _NavigatorUserMediaErrorCallback(NavigatorUserMediaError error);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('NavigatorUserMediaSuccessCallback')
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html#idl-def-NavigatorUserMediaSuccessCallback
@Experimental()
typedef void _NavigatorUserMediaSuccessCallback(MediaStream stream);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('NetworkInformation')
@Experimental() // untriaged
@Native("NetworkInformation")
class NetworkInformation extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory NetworkInformation._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('NetworkInformation.changeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  @DomName('NetworkInformation.downlinkMax')
  @DocsEditable()
  @Experimental() // untriaged
  final double downlinkMax;

  @DomName('NetworkInformation.type')
  @DocsEditable()
  @Experimental() // untriaged
  final String type;

  @DomName('NetworkInformation.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.

/**
 * Lazy implementation of the child nodes of an element that does not request
 * the actual child nodes of an element until strictly necessary greatly
 * improving performance for the typical cases where it is not required.
 */
class _ChildNodeListLazy extends ListBase<Node> implements NodeListWrapper {
  final Node _this;

  _ChildNodeListLazy(this._this);

  Node get first {
    Node result = JS('Node|Null', '#.firstChild', _this);
    if (result == null) throw new StateError("No elements");
    return result;
  }

  Node get last {
    Node result = JS('Node|Null', '#.lastChild', _this);
    if (result == null) throw new StateError("No elements");
    return result;
  }

  Node get single {
    int l = this.length;
    if (l == 0) throw new StateError("No elements");
    if (l > 1) throw new StateError("More than one element");
    return JS('Node|Null', '#.firstChild', _this);
  }

  void add(Node value) {
    _this.append(value);
  }

  void addAll(Iterable<Node> iterable) {
    if (iterable is _ChildNodeListLazy) {
      _ChildNodeListLazy otherList = iterable;
      if (!identical(otherList._this, _this)) {
        // Optimized route for copying between nodes.
        for (var i = 0, len = otherList.length; i < len; ++i) {
          _this.append(otherList._this.firstChild);
        }
      }
      return;
    }
    for (Node node in iterable) {
      _this.append(node);
    }
  }

  void insert(int index, Node node) {
    if (index < 0 || index > length) {
      throw new RangeError.range(index, 0, length);
    }
    if (index == length) {
      _this.append(node);
    } else {
      _this.insertBefore(node, this[index]);
    }
  }

  void insertAll(int index, Iterable<Node> iterable) {
    if (index == length) {
      addAll(iterable);
    } else {
      var item = this[index];
      _this.insertAllBefore(iterable, item);
    }
  }

  void setAll(int index, Iterable<Node> iterable) {
    throw new UnsupportedError("Cannot setAll on Node list");
  }

  Node removeLast() {
    final result = last;
    if (result != null) {
      _this._removeChild(result);
    }
    return result;
  }

  Node removeAt(int index) {
    var result = this[index];
    if (result != null) {
      _this._removeChild(result);
    }
    return result;
  }

  bool remove(Object object) {
    if (object is! Node) return false;
    Node node = object;
    if (!identical(_this, node.parentNode)) return false;
    _this._removeChild(node);
    return true;
  }

  void _filter(bool test(Node node), bool removeMatching) {
    // This implementation of removeWhere/retainWhere is more efficient
    // than the default in ListBase. Child nodes can be removed in constant
    // time.
    Node child = _this.firstChild;
    while (child != null) {
      Node nextChild = child.nextNode;
      if (test(child) == removeMatching) {
        _this._removeChild(child);
      }
      child = nextChild;
    }
  }

  void removeWhere(bool test(Node node)) {
    _filter(test, true);
  }

  void retainWhere(bool test(Node node)) {
    _filter(test, false);
  }

  void clear() {
    _this._clearChildren();
  }

  void operator []=(int index, Node value) {
    _this._replaceChild(value, this[index]);
  }

  Iterator<Node> get iterator => _this.childNodes.iterator;

  // From List<Node>:

  // TODO(jacobr): this could be implemented for child node lists.
  // The exception we throw here is misleading.
  void sort([Comparator<Node> compare]) {
    throw new UnsupportedError("Cannot sort Node list");
  }

  void shuffle([Random random]) {
    throw new UnsupportedError("Cannot shuffle Node list");
  }

  // FIXME: implement these.
  void setRange(int start, int end, Iterable<Node> iterable,
      [int skipCount = 0]) {
    throw new UnsupportedError("Cannot setRange on Node list");
  }

  void fillRange(int start, int end, [Node fill]) {
    throw new UnsupportedError("Cannot fillRange on Node list");
  }

  void removeRange(int start, int end) {
    throw new UnsupportedError("Cannot removeRange on Node list");
  }
  // -- end List<Node> mixins.

  // TODO(jacobr): benchmark whether this is more efficient or whether caching
  // a local copy of childNodes is more efficient.
  int get length => _this.childNodes.length;

  set length(int value) {
    throw new UnsupportedError("Cannot set length on immutable List.");
  }

  Node operator [](int index) => _this.childNodes[index];

  List<Node> get rawList => _this.childNodes;
}

@DomName('Node')
@Native("Node")
class Node extends EventTarget {
  // Custom element created callback.
  Node._created() : super._created();

  /**
   * A modifiable list of this node's children.
   */
  List<Node> get nodes {
    return new _ChildNodeListLazy(this);
  }

  set nodes(Iterable<Node> value) {
    // Copy list first since we don't want liveness during iteration.
    // TODO(jacobr): there is a better way to do this.
    var copy = value.toList();
    text = '';
    for (Node node in copy) {
      append(node);
    }
  }

  /**
   * Removes this node from the DOM.
   */
  @DomName('Node.removeChild')
  void remove() {
    // TODO(jacobr): should we throw an exception if parent is already null?
    // TODO(vsm): Use the native remove when available.
    if (this.parentNode != null) {
      final Node parent = this.parentNode;
      parentNode._removeChild(this);
    }
  }

  /**
   * Replaces this node with another node.
   */
  @DomName('Node.replaceChild')
  Node replaceWith(Node otherNode) {
    try {
      final Node parent = this.parentNode;
      parent._replaceChild(otherNode, this);
    } catch (e) {}
    ;
    return this;
  }

  /**
   * Inserts all of the nodes into this node directly before refChild.
   *
   * See also:
   *
   * * [insertBefore]
   */
  Node insertAllBefore(Iterable<Node> newNodes, Node refChild) {
    if (newNodes is _ChildNodeListLazy) {
      _ChildNodeListLazy otherList = newNodes;
      if (identical(otherList._this, this)) {
        throw new ArgumentError(newNodes);
      }

      // Optimized route for copying between nodes.
      for (var i = 0, len = otherList.length; i < len; ++i) {
        this.insertBefore(otherList._this.firstChild, refChild);
      }
    } else {
      for (var node in newNodes) {
        this.insertBefore(node, refChild);
      }
    }
  }

  void _clearChildren() {
    while (firstChild != null) {
      _removeChild(firstChild);
    }
  }

  /**
   * Print out a String representation of this Node.
   */
  String toString() {
    String value = nodeValue; // Fetch DOM Node property once.
    return value == null ? super.toString() : value;
  }

  /**
   * A list of this node's children.
   *
   * ## Other resources
   *
   * * [Node.childNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)
   *   from MDN.
   */
  @DomName('Node.childNodes')
  @DocsEditable()
  @Returns('NodeList')
  @Creates('NodeList')
  final List<Node> childNodes;

  // To suppress missing implicit constructor warnings.
  factory Node._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Node.ATTRIBUTE_NODE')
  @DocsEditable()
  static const int ATTRIBUTE_NODE = 2;

  @DomName('Node.CDATA_SECTION_NODE')
  @DocsEditable()
  static const int CDATA_SECTION_NODE = 4;

  @DomName('Node.COMMENT_NODE')
  @DocsEditable()
  static const int COMMENT_NODE = 8;

  @DomName('Node.DOCUMENT_FRAGMENT_NODE')
  @DocsEditable()
  static const int DOCUMENT_FRAGMENT_NODE = 11;

  @DomName('Node.DOCUMENT_NODE')
  @DocsEditable()
  static const int DOCUMENT_NODE = 9;

  @DomName('Node.DOCUMENT_TYPE_NODE')
  @DocsEditable()
  static const int DOCUMENT_TYPE_NODE = 10;

  @DomName('Node.ELEMENT_NODE')
  @DocsEditable()
  static const int ELEMENT_NODE = 1;

  @DomName('Node.ENTITY_NODE')
  @DocsEditable()
  static const int ENTITY_NODE = 6;

  @DomName('Node.ENTITY_REFERENCE_NODE')
  @DocsEditable()
  static const int ENTITY_REFERENCE_NODE = 5;

  @DomName('Node.NOTATION_NODE')
  @DocsEditable()
  static const int NOTATION_NODE = 12;

  @DomName('Node.PROCESSING_INSTRUCTION_NODE')
  @DocsEditable()
  static const int PROCESSING_INSTRUCTION_NODE = 7;

  @DomName('Node.TEXT_NODE')
  @DocsEditable()
  static const int TEXT_NODE = 3;

  @JSName('baseURI')
  @DomName('Node.baseURI')
  @DocsEditable()
  final String baseUri;

  /**
   * The first child of this node.
   *
   * ## Other resources
   *
   * * [Node.firstChild](https://developer.mozilla.org/en-US/docs/Web/API/Node.firstChild)
   *   from MDN.
   */
  @DomName('Node.firstChild')
  @DocsEditable()
  final Node firstChild;

  /**
   * The last child of this node.
   *
   * ## Other resources
   *
   * * [Node.lastChild](https://developer.mozilla.org/en-US/docs/Web/API/Node.lastChild)
   *   from MDN.
   */
  @DomName('Node.lastChild')
  @DocsEditable()
  final Node lastChild;

  @JSName('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 descendents.
   *
   * ## Other resources
   *
   * * [Node.textContent](https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent)
   *   from MDN.
   */
  @DomName('Node.textContent')
  @DocsEditable()
  String text;

  @DomName('Node.treeRoot')
  @DocsEditable()
  @Experimental() // untriaged
  final Node treeRoot;

  @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 node) native;

  @JSName('cloneNode')
  /**
   * Returns a copy of this node.
   *
   * If [deep] is `true`, then all of this node's children and descendents 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 node, Node child) native;

  @JSName('removeChild')
  @DomName('Node.removeChild')
  @DocsEditable()
  Node _removeChild(Node child) native;

  @JSName('replaceChild')
  @DomName('Node.replaceChild')
  @DocsEditable()
  Node _replaceChild(Node node, Node child) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('NodeFilter')
@Unstable()
@Native("NodeFilter")
class NodeFilter extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NodeFilter._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('NodeFilter.FILTER_ACCEPT')
  @DocsEditable()
  static const int FILTER_ACCEPT = 1;

  @DomName('NodeFilter.FILTER_REJECT')
  @DocsEditable()
  static const int FILTER_REJECT = 2;

  @DomName('NodeFilter.FILTER_SKIP')
  @DocsEditable()
  static const int FILTER_SKIP = 3;

  @DomName('NodeFilter.SHOW_ALL')
  @DocsEditable()
  static const int SHOW_ALL = 0xFFFFFFFF;

  @DomName('NodeFilter.SHOW_COMMENT')
  @DocsEditable()
  static const int SHOW_COMMENT = 0x80;

  @DomName('NodeFilter.SHOW_DOCUMENT')
  @DocsEditable()
  static const int SHOW_DOCUMENT = 0x100;

  @DomName('NodeFilter.SHOW_DOCUMENT_FRAGMENT')
  @DocsEditable()
  static const int SHOW_DOCUMENT_FRAGMENT = 0x400;

  @DomName('NodeFilter.SHOW_DOCUMENT_TYPE')
  @DocsEditable()
  static const int SHOW_DOCUMENT_TYPE = 0x200;

  @DomName('NodeFilter.SHOW_ELEMENT')
  @DocsEditable()
  static const int SHOW_ELEMENT = 0x1;

  @DomName('NodeFilter.SHOW_PROCESSING_INSTRUCTION')
  @DocsEditable()
  static const int SHOW_PROCESSING_INSTRUCTION = 0x40;

  @DomName('NodeFilter.SHOW_TEXT')
  @DocsEditable()
  static const int SHOW_TEXT = 0x4;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DomName('NodeIterator')
@Unstable()
@Native("NodeIterator")
class NodeIterator extends Interceptor {
  factory NodeIterator(Node root, int whatToShow) {
    return document._createNodeIterator(root, whatToShow, null);
  }
  // To suppress missing implicit constructor warnings.
  factory NodeIterator._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('NodeIterator.pointerBeforeReferenceNode')
  @DocsEditable()
  final bool pointerBeforeReferenceNode;

  @DomName('NodeIterator.referenceNode')
  @DocsEditable()
  final Node referenceNode;

  @DomName('NodeIterator.root')
  @DocsEditable()
  final Node root;

  @DomName('NodeIterator.whatToShow')
  @DocsEditable()
  final int whatToShow;

  @DomName('NodeIterator.detach')
  @DocsEditable()
  void detach() native;

  @DomName('NodeIterator.nextNode')
  @DocsEditable()
  Node nextNode() native;

  @DomName('NodeIterator.previousNode')
  @DocsEditable()
  Node previousNode() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('NodeList')
@Native("NodeList,RadioNodeList")
class NodeList extends Interceptor
    with ListMixin<Node>, ImmutableListMixin<Node>
    implements JavaScriptIndexingBehavior<Node>, List<Node> {
  // To suppress missing implicit constructor warnings.
  factory NodeList._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('NodeList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  Node operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("Node", "#[#]", this, index);
  }

  void operator []=(int index, Node value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Node> mixins.
  // Node is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Node get first {
    if (this.length > 0) {
      return JS('Node', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Node get last {
    int len = this.length;
    if (len > 0) {
      return JS('Node', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Node get single {
    int len = this.length;
    if (len == 1) {
      return JS('Node', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Node elementAt(int index) => this[index];
  // -- end List<Node> mixins.

  @JSName('item')
  @DomName('NodeList.item')
  @DocsEditable()
  Node _item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('NonDocumentTypeChildNode')
@Experimental() // untriaged
@Native("NonDocumentTypeChildNode")
class NonDocumentTypeChildNode extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NonDocumentTypeChildNode._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('NonDocumentTypeChildNode.nextElementSibling')
  @DocsEditable()
  @Experimental() // untriaged
  final Element nextElementSibling;

  @DomName('NonDocumentTypeChildNode.previousElementSibling')
  @DocsEditable()
  @Experimental() // untriaged
  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('NonElementParentNode')
@Experimental() // untriaged
@Native("NonElementParentNode")
class NonElementParentNode extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory NonElementParentNode._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('NonElementParentNode.getElementById')
  @DocsEditable()
  @Experimental() // untriaged
  Element getElementById(String elementId) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DomName('Notification')
// http://www.w3.org/TR/notifications/#notification
@Experimental() // experimental
@Native("Notification")
class Notification extends EventTarget {
  factory Notification(String title,
      {String dir: null,
      String body: null,
      String lang: null,
      String tag: null,
      String icon: null}) {
    var parsedOptions = {};
    if (dir != null) parsedOptions['dir'] = dir;
    if (body != null) parsedOptions['body'] = body;
    if (lang != null) parsedOptions['lang'] = lang;
    if (tag != null) parsedOptions['tag'] = tag;
    if (icon != null) parsedOptions['icon'] = icon;
    return Notification._factoryNotification(title, parsedOptions);
  }
  // To suppress missing implicit constructor warnings.
  factory Notification._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `click` events to event
   * handlers that are not necessarily instances of [Notification].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Notification.clickEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> clickEvent =
      const EventStreamProvider<Event>('click');

  /**
   * Static factory designed to expose `close` events to event
   * handlers that are not necessarily instances of [Notification].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Notification.closeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> closeEvent =
      const EventStreamProvider<Event>('close');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [Notification].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Notification.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `show` events to event
   * handlers that are not necessarily instances of [Notification].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Notification.showEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> showEvent =
      const EventStreamProvider<Event>('show');

  @DomName('Notification.Notification')
  @DocsEditable()
  static Notification _factoryNotification(String title, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return Notification._create_1(title, options_1);
    }
    return Notification._create_2(title);
  }

  static Notification _create_1(title, options) =>
      JS('Notification', 'new Notification(#,#)', title, options);
  static Notification _create_2(title) =>
      JS('Notification', 'new Notification(#)', title);

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.Notification)');

  @DomName('Notification.actions')
  @DocsEditable()
  @Experimental() // untriaged
  final List actions;

  @DomName('Notification.body')
  @DocsEditable()
  @Experimental() // untriaged
  final String body;

  @DomName('Notification.data')
  @DocsEditable()
  @Experimental() // untriaged
  @annotation_Creates_SerializedScriptValue
  @annotation_Returns_SerializedScriptValue
  final Object data;

  @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.maxActions')
  @DocsEditable()
  @Experimental() // untriaged
  final int maxActions;

  @DomName('Notification.permission')
  @DocsEditable()
  final String permission;

  @DomName('Notification.renotify')
  @DocsEditable()
  @Experimental() // untriaged
  final bool renotify;

  @DomName('Notification.requireInteraction')
  @DocsEditable()
  @Experimental() // untriaged
  final bool requireInteraction;

  @DomName('Notification.silent')
  @DocsEditable()
  @Experimental() // untriaged
  final bool silent;

  @DomName('Notification.tag')
  @DocsEditable()
  @Experimental() // nonstandard
  final String tag;

  @DomName('Notification.timestamp')
  @DocsEditable()
  @Experimental() // untriaged
  final int timestamp;

  @DomName('Notification.title')
  @DocsEditable()
  @Experimental() // untriaged
  final String title;

  @DomName('Notification.vibrate')
  @DocsEditable()
  @Experimental() // untriaged
  final List<int> vibrate;

  @DomName('Notification.close')
  @DocsEditable()
  void close() native;

  @JSName('requestPermission')
  @DomName('Notification.requestPermission')
  @DocsEditable()
  static Future _requestPermission(
      [_NotificationPermissionCallback deprecatedCallback]) 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.

@DocsEditable()
@DomName('NotificationEvent')
@Experimental() // untriaged
@Native("NotificationEvent")
class NotificationEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory NotificationEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('NotificationEvent.NotificationEvent')
  @DocsEditable()
  factory NotificationEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return NotificationEvent._create_1(type, eventInitDict_1);
  }
  static NotificationEvent _create_1(type, eventInitDict) => JS(
      'NotificationEvent', 'new NotificationEvent(#,#)', type, eventInitDict);

  @DomName('NotificationEvent.action')
  @DocsEditable()
  @Experimental() // untriaged
  final String action;

  @DomName('NotificationEvent.notification')
  @DocsEditable()
  @Experimental() // untriaged
  final Notification notification;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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('NumberValue')
@Experimental() // untriaged
@Native("NumberValue")
class NumberValue extends StyleValue {
  // To suppress missing implicit constructor warnings.
  factory NumberValue._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('NumberValue.NumberValue')
  @DocsEditable()
  factory NumberValue(num value) {
    return NumberValue._create_1(value);
  }
  static NumberValue _create_1(value) =>
      JS('NumberValue', 'new NumberValue(#)', value);

  @DomName('NumberValue.value')
  @DocsEditable()
  @Experimental() // untriaged
  final double value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLOListElement')
@Native("HTMLOListElement")
class OListElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory OListElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLOListElement.HTMLOListElement')
  @DocsEditable()
  factory OListElement() => JS(
      'returns:OListElement;creates:OListElement;new:true',
      '#.createElement(#)',
      document,
      "ol");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  OListElement.created() : super.created();

  @DomName('HTMLOListElement.reversed')
  @DocsEditable()
  bool reversed;

  @DomName('HTMLOListElement.start')
  @DocsEditable()
  int start;

  @DomName('HTMLOListElement.type')
  @DocsEditable()
  String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLObjectElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
@Native("HTMLObjectElement")
class ObjectElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ObjectElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLObjectElement.HTMLObjectElement')
  @DocsEditable()
  factory ObjectElement() => document.createElement("object");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ObjectElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('object');

  @DomName('HTMLObjectElement.data')
  @DocsEditable()
  String data;

  @DomName('HTMLObjectElement.form')
  @DocsEditable()
  final FormElement form;

  @DomName('HTMLObjectElement.height')
  @DocsEditable()
  String height;

  @DomName('HTMLObjectElement.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.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() 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('OffscreenCanvas')
@Experimental() // untriaged
@Native("OffscreenCanvas")
class OffscreenCanvas extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory OffscreenCanvas._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('OffscreenCanvas.OffscreenCanvas')
  @DocsEditable()
  factory OffscreenCanvas(int width, int height) {
    return OffscreenCanvas._create_1(width, height);
  }
  static OffscreenCanvas _create_1(width, height) =>
      JS('OffscreenCanvas', 'new OffscreenCanvas(#,#)', width, height);

  @DomName('OffscreenCanvas.height')
  @DocsEditable()
  @Experimental() // untriaged
  int height;

  @DomName('OffscreenCanvas.width')
  @DocsEditable()
  @Experimental() // untriaged
  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('HTMLOptGroupElement')
@Native("HTMLOptGroupElement")
class OptGroupElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory OptGroupElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLOptGroupElement.HTMLOptGroupElement')
  @DocsEditable()
  factory OptGroupElement() => JS(
      'returns:OptGroupElement;creates:OptGroupElement;new:true',
      '#.createElement(#)',
      document,
      "optgroup");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  OptGroupElement.created() : super.created();

  @DomName('HTMLOptGroupElement.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('HTMLOptGroupElement.label')
  @DocsEditable()
  String label;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DomName('HTMLOptionElement')
@Native("HTMLOptionElement")
class OptionElement extends HtmlElement {
  factory OptionElement(
      {String data: '', String value: '', bool selected: false}) {
    return new OptionElement._(data, value, null, selected);
  }

  @DomName('HTMLOptionElement.HTMLOptionElement')
  @DocsEditable()
  factory OptionElement._(
      [String data, String value, bool defaultSelected, bool selected]) {
    if (selected != null) {
      return OptionElement._create_1(data, value, defaultSelected, selected);
    }
    if (defaultSelected != null) {
      return OptionElement._create_2(data, value, defaultSelected);
    }
    if (value != null) {
      return OptionElement._create_3(data, value);
    }
    if (data != null) {
      return OptionElement._create_4(data);
    }
    return OptionElement._create_5();
  }
  static OptionElement _create_1(data, value, defaultSelected, selected) => JS(
      'OptionElement',
      'new Option(#,#,#,#)',
      data,
      value,
      defaultSelected,
      selected);
  static OptionElement _create_2(data, value, defaultSelected) =>
      JS('OptionElement', 'new Option(#,#,#)', data, value, defaultSelected);
  static OptionElement _create_3(data, value) =>
      JS('OptionElement', 'new Option(#,#)', data, value);
  static OptionElement _create_4(data) =>
      JS('OptionElement', 'new Option(#)', data);
  static OptionElement _create_5() => JS('OptionElement', 'new Option()');
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  OptionElement.created() : super.created();

  @DomName('HTMLOptionElement.defaultSelected')
  @DocsEditable()
  bool defaultSelected;

  @DomName('HTMLOptionElement.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('HTMLOptionElement.form')
  @DocsEditable()
  final FormElement form;

  @DomName('HTMLOptionElement.index')
  @DocsEditable()
  final int index;

  @DomName('HTMLOptionElement.label')
  @DocsEditable()
  String label;

  @DomName('HTMLOptionElement.selected')
  @DocsEditable()
  bool selected;

  @DomName('HTMLOptionElement.value')
  @DocsEditable()
  String value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLOutputElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Native("HTMLOutputElement")
class OutputElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory OutputElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLOutputElement.HTMLOutputElement')
  @DocsEditable()
  factory OutputElement() => document.createElement("output");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  OutputElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('output');

  @DomName('HTMLOutputElement.defaultValue')
  @DocsEditable()
  String defaultValue;

  @DomName('HTMLOutputElement.form')
  @DocsEditable()
  final FormElement form;

  @DomName('HTMLOutputElement.htmlFor')
  @DocsEditable()
  final DomTokenList htmlFor;

  @DomName('HTMLOutputElement.labels')
  @DocsEditable()
  @Unstable()
  @Returns('NodeList|Null')
  @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.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() 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('PageTransitionEvent')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html#pagetransitionevent
@Experimental()
@Native("PageTransitionEvent")
class PageTransitionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory PageTransitionEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PageTransitionEvent.PageTransitionEvent')
  @DocsEditable()
  factory PageTransitionEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return PageTransitionEvent._create_1(type, eventInitDict_1);
    }
    return PageTransitionEvent._create_2(type);
  }
  static PageTransitionEvent _create_1(type, eventInitDict) => JS(
      'PageTransitionEvent',
      'new PageTransitionEvent(#,#)',
      type,
      eventInitDict);
  static PageTransitionEvent _create_2(type) =>
      JS('PageTransitionEvent', 'new PageTransitionEvent(#)', type);

  @DomName('PageTransitionEvent.persisted')
  @DocsEditable()
  final bool persisted;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLParagraphElement')
@Native("HTMLParagraphElement")
class ParagraphElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ParagraphElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLParagraphElement.HTMLParagraphElement')
  @DocsEditable()
  factory ParagraphElement() => JS(
      'returns:ParagraphElement;creates:ParagraphElement;new:true',
      '#.createElement(#)',
      document,
      "p");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ParagraphElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLParamElement')
@Unstable()
@Native("HTMLParamElement")
class ParamElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ParamElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLParamElement.HTMLParamElement')
  @DocsEditable()
  factory ParamElement() => JS(
      'returns:ParamElement;creates:ParamElement;new:true',
      '#.createElement(#)',
      document,
      "param");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ParamElement.created() : super.created();

  @DomName('HTMLParamElement.name')
  @DocsEditable()
  String name;

  @DomName('HTMLParamElement.value')
  @DocsEditable()
  String value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('ParentNode')
@Experimental() // untriaged
abstract class ParentNode extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ParentNode._() {
    throw new UnsupportedError("Not supported");
  }

  final int _childElementCount;

  final List<Node> _children;

  final Element _firstElementChild;

  final Element _lastElementChild;

  Element querySelector(String selectors);

  List<Node> _querySelectorAll(String selectors);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('PasswordCredential')
@Experimental() // untriaged
@Native("PasswordCredential")
class PasswordCredential extends Credential {
  // To suppress missing implicit constructor warnings.
  factory PasswordCredential._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PasswordCredential.PasswordCredential')
  @DocsEditable()
  factory PasswordCredential(Map data) {
    var data_1 = convertDartToNative_Dictionary(data);
    return PasswordCredential._create_1(data_1);
  }
  static PasswordCredential _create_1(data) =>
      JS('PasswordCredential', 'new PasswordCredential(#)', data);

  @DomName('PasswordCredential.additionalData')
  @DocsEditable()
  @Experimental() // untriaged
  Object additionalData;

  @DomName('PasswordCredential.idName')
  @DocsEditable()
  @Experimental() // untriaged
  String idName;

  @DomName('PasswordCredential.passwordName')
  @DocsEditable()
  @Experimental() // untriaged
  String passwordName;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('Path2D')
@Experimental() // untriaged
@Native("Path2D")
class Path2D extends Interceptor implements _CanvasPathMethods {
  // To suppress missing implicit constructor warnings.
  factory Path2D._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Path2D.Path2D')
  @DocsEditable()
  factory Path2D([path_OR_text]) {
    if (path_OR_text == null) {
      return Path2D._create_1();
    }
    if ((path_OR_text is Path2D)) {
      return Path2D._create_2(path_OR_text);
    }
    if ((path_OR_text is String)) {
      return Path2D._create_3(path_OR_text);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static Path2D _create_1() => JS('Path2D', 'new Path2D()');
  static Path2D _create_2(path_OR_text) =>
      JS('Path2D', 'new Path2D(#)', path_OR_text);
  static Path2D _create_3(path_OR_text) =>
      JS('Path2D', 'new Path2D(#)', path_OR_text);

  @DomName('Path2D.addPath')
  @DocsEditable()
  @Experimental() // untriaged
  void addPath(Path2D path, [Matrix transform]) native;

  // From CanvasPathMethods

  @DomName('Path2D.arc')
  @DocsEditable()
  @Experimental() // untriaged
  void arc(num x, num y, num radius, num startAngle, num endAngle,
      bool anticlockwise) native;

  @DomName('Path2D.arcTo')
  @DocsEditable()
  @Experimental() // untriaged
  void arcTo(num x1, num y1, num x2, num y2, num radius) native;

  @DomName('Path2D.bezierCurveTo')
  @DocsEditable()
  @Experimental() // untriaged
  void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y, num x, num y)
      native;

  @DomName('Path2D.closePath')
  @DocsEditable()
  @Experimental() // untriaged
  void closePath() native;

  @DomName('Path2D.ellipse')
  @DocsEditable()
  @Experimental() // untriaged
  void ellipse(num x, num y, num radiusX, num radiusY, num rotation,
      num startAngle, num endAngle, bool anticlockwise) native;

  @DomName('Path2D.lineTo')
  @DocsEditable()
  @Experimental() // untriaged
  void lineTo(num x, num y) native;

  @DomName('Path2D.moveTo')
  @DocsEditable()
  @Experimental() // untriaged
  void moveTo(num x, num y) native;

  @DomName('Path2D.quadraticCurveTo')
  @DocsEditable()
  @Experimental() // untriaged
  void quadraticCurveTo(num cpx, num cpy, num x, num y) native;

  @DomName('Path2D.rect')
  @DocsEditable()
  @Experimental() // untriaged
  void rect(num x, num y, num width, num height) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('Performance')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE)
@Native("Performance")
class Performance extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory Performance._() {
    throw new UnsupportedError("Not supported");
  }

  /// 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.clearFrameTimings')
  @DocsEditable()
  @Experimental() // untriaged
  void clearFrameTimings() native;

  @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.clearResourceTimings')
  @DocsEditable()
  @Experimental() // untriaged
  void clearResourceTimings() 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;

  @DomName('Performance.setFrameTimingBufferSize')
  @DocsEditable()
  @Experimental() // untriaged
  void setFrameTimingBufferSize(int maxSize) native;

  @DomName('Performance.setResourceTimingBufferSize')
  @DocsEditable()
  @Experimental() // untriaged
  void setResourceTimingBufferSize(int maxSize) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('PerformanceCompositeTiming')
@Experimental() // untriaged
@Native("PerformanceCompositeTiming")
class PerformanceCompositeTiming extends PerformanceEntry {
  // To suppress missing implicit constructor warnings.
  factory PerformanceCompositeTiming._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PerformanceCompositeTiming.sourceFrame')
  @DocsEditable()
  @Experimental() // untriaged
  final int sourceFrame;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('PerformanceEntry')
// http://www.w3.org/TR/performance-timeline/#sec-PerformanceEntry-interface
@Experimental()
@Native("PerformanceEntry")
class PerformanceEntry extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PerformanceEntry._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PerformanceEntry.duration')
  @DocsEditable()
  final double duration;

  @DomName('PerformanceEntry.entryType')
  @DocsEditable()
  final String entryType;

  @DomName('PerformanceEntry.name')
  @DocsEditable()
  final String name;

  @DomName('PerformanceEntry.startTime')
  @DocsEditable()
  final double startTime;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('PerformanceMark')
// http://www.w3.org/TR/user-timing/#performancemark
@Experimental()
@Native("PerformanceMark")
class PerformanceMark extends PerformanceEntry {
  // To suppress missing implicit constructor warnings.
  factory PerformanceMark._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('PerformanceMeasure')
// http://www.w3.org/TR/user-timing/#performancemeasure
@Experimental()
@Native("PerformanceMeasure")
class PerformanceMeasure extends PerformanceEntry {
  // To suppress missing implicit constructor warnings.
  factory PerformanceMeasure._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('PerformanceNavigation')
@Unstable()
@Native("PerformanceNavigation")
class PerformanceNavigation extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PerformanceNavigation._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PerformanceNavigation.TYPE_BACK_FORWARD')
  @DocsEditable()
  static const int TYPE_BACK_FORWARD = 2;

  @DomName('PerformanceNavigation.TYPE_NAVIGATE')
  @DocsEditable()
  static const int TYPE_NAVIGATE = 0;

  @DomName('PerformanceNavigation.TYPE_RELOAD')
  @DocsEditable()
  static const int TYPE_RELOAD = 1;

  @DomName('PerformanceNavigation.TYPE_RESERVED')
  @DocsEditable()
  static const int TYPE_RESERVED = 255;

  @DomName('PerformanceNavigation.redirectCount')
  @DocsEditable()
  final int redirectCount;

  @DomName('PerformanceNavigation.type')
  @DocsEditable()
  final int type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('PerformanceObserver')
@Experimental() // untriaged
@Native("PerformanceObserver")
class PerformanceObserver extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PerformanceObserver._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PerformanceObserver.disconnect')
  @DocsEditable()
  @Experimental() // untriaged
  void disconnect() native;

  @DomName('PerformanceObserver.observe')
  @DocsEditable()
  @Experimental() // untriaged
  void observe(Map options) {
    var options_1 = convertDartToNative_Dictionary(options);
    _observe_1(options_1);
    return;
  }

  @JSName('observe')
  @DomName('PerformanceObserver.observe')
  @DocsEditable()
  @Experimental() // untriaged
  void _observe_1(options) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('PerformanceObserverEntryList')
@Experimental() // untriaged
@Native("PerformanceObserverEntryList")
class PerformanceObserverEntryList extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PerformanceObserverEntryList._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PerformanceObserverEntryList.getEntries')
  @DocsEditable()
  @Experimental() // untriaged
  List<PerformanceEntry> getEntries() native;

  @DomName('PerformanceObserverEntryList.getEntriesByName')
  @DocsEditable()
  @Experimental() // untriaged
  List<PerformanceEntry> getEntriesByName(String name, String entryType) native;

  @DomName('PerformanceObserverEntryList.getEntriesByType')
  @DocsEditable()
  @Experimental() // untriaged
  List<PerformanceEntry> getEntriesByType(String entryType) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('PerformanceRenderTiming')
@Experimental() // untriaged
@Native("PerformanceRenderTiming")
class PerformanceRenderTiming extends PerformanceEntry {
  // To suppress missing implicit constructor warnings.
  factory PerformanceRenderTiming._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PerformanceRenderTiming.sourceFrame')
  @DocsEditable()
  @Experimental() // untriaged
  final int sourceFrame;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('PerformanceResourceTiming')
// http://www.w3c-test.org/webperf/specs/ResourceTiming/#performanceresourcetiming
@Experimental()
@Native("PerformanceResourceTiming")
class PerformanceResourceTiming extends PerformanceEntry {
  // To suppress missing implicit constructor warnings.
  factory PerformanceResourceTiming._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PerformanceResourceTiming.connectEnd')
  @DocsEditable()
  final double connectEnd;

  @DomName('PerformanceResourceTiming.connectStart')
  @DocsEditable()
  final double connectStart;

  @DomName('PerformanceResourceTiming.domainLookupEnd')
  @DocsEditable()
  final double domainLookupEnd;

  @DomName('PerformanceResourceTiming.domainLookupStart')
  @DocsEditable()
  final double domainLookupStart;

  @DomName('PerformanceResourceTiming.fetchStart')
  @DocsEditable()
  final double fetchStart;

  @DomName('PerformanceResourceTiming.initiatorType')
  @DocsEditable()
  final String initiatorType;

  @DomName('PerformanceResourceTiming.redirectEnd')
  @DocsEditable()
  final double redirectEnd;

  @DomName('PerformanceResourceTiming.redirectStart')
  @DocsEditable()
  final double redirectStart;

  @DomName('PerformanceResourceTiming.requestStart')
  @DocsEditable()
  @Experimental() // nonstandard
  final double requestStart;

  @DomName('PerformanceResourceTiming.responseEnd')
  @DocsEditable()
  @Experimental() // nonstandard
  final double responseEnd;

  @DomName('PerformanceResourceTiming.responseStart')
  @DocsEditable()
  @Experimental() // nonstandard
  final double responseStart;

  @DomName('PerformanceResourceTiming.secureConnectionStart')
  @DocsEditable()
  final double secureConnectionStart;

  @DomName('PerformanceResourceTiming.workerStart')
  @DocsEditable()
  @Experimental() // untriaged
  final double workerStart;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('PerformanceTiming')
@Unstable()
@Native("PerformanceTiming")
class PerformanceTiming extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PerformanceTiming._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PerformanceTiming.connectEnd')
  @DocsEditable()
  final int connectEnd;

  @DomName('PerformanceTiming.connectStart')
  @DocsEditable()
  final int connectStart;

  @DomName('PerformanceTiming.domComplete')
  @DocsEditable()
  final int domComplete;

  @DomName('PerformanceTiming.domContentLoadedEventEnd')
  @DocsEditable()
  final int domContentLoadedEventEnd;

  @DomName('PerformanceTiming.domContentLoadedEventStart')
  @DocsEditable()
  final int domContentLoadedEventStart;

  @DomName('PerformanceTiming.domInteractive')
  @DocsEditable()
  final int domInteractive;

  @DomName('PerformanceTiming.domLoading')
  @DocsEditable()
  final int domLoading;

  @DomName('PerformanceTiming.domainLookupEnd')
  @DocsEditable()
  final int domainLookupEnd;

  @DomName('PerformanceTiming.domainLookupStart')
  @DocsEditable()
  final int domainLookupStart;

  @DomName('PerformanceTiming.fetchStart')
  @DocsEditable()
  final int fetchStart;

  @DomName('PerformanceTiming.loadEventEnd')
  @DocsEditable()
  final int loadEventEnd;

  @DomName('PerformanceTiming.loadEventStart')
  @DocsEditable()
  final int loadEventStart;

  @DomName('PerformanceTiming.navigationStart')
  @DocsEditable()
  final int navigationStart;

  @DomName('PerformanceTiming.redirectEnd')
  @DocsEditable()
  final int redirectEnd;

  @DomName('PerformanceTiming.redirectStart')
  @DocsEditable()
  final int redirectStart;

  @DomName('PerformanceTiming.requestStart')
  @DocsEditable()
  final int requestStart;

  @DomName('PerformanceTiming.responseEnd')
  @DocsEditable()
  final int responseEnd;

  @DomName('PerformanceTiming.responseStart')
  @DocsEditable()
  final int responseStart;

  @DomName('PerformanceTiming.secureConnectionStart')
  @DocsEditable()
  final int secureConnectionStart;

  @DomName('PerformanceTiming.unloadEventEnd')
  @DocsEditable()
  final int unloadEventEnd;

  @DomName('PerformanceTiming.unloadEventStart')
  @DocsEditable()
  final int unloadEventStart;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('PermissionStatus')
@Experimental() // untriaged
@Native("PermissionStatus")
class PermissionStatus extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory PermissionStatus._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PermissionStatus.changeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  @DomName('PermissionStatus.state')
  @DocsEditable()
  @Experimental() // untriaged
  final String state;

  @DomName('PermissionStatus.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('Permissions')
@Experimental() // untriaged
@Native("Permissions")
class Permissions extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Permissions._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Permissions.query')
  @DocsEditable()
  @Experimental() // untriaged
  Future query(Map permission) {
    var permission_1 = convertDartToNative_Dictionary(permission);
    return _query_1(permission_1);
  }

  @JSName('query')
  @DomName('Permissions.query')
  @DocsEditable()
  @Experimental() // untriaged
  Future _query_1(permission) native;

  @DomName('Permissions.request')
  @DocsEditable()
  @Experimental() // untriaged
  Future request(Map permissions) {
    var permissions_1 = convertDartToNative_Dictionary(permissions);
    return _request_1(permissions_1);
  }

  @JSName('request')
  @DomName('Permissions.request')
  @DocsEditable()
  @Experimental() // untriaged
  Future _request_1(permissions) native;

  @DomName('Permissions.requestAll')
  @DocsEditable()
  @Experimental() // untriaged
  Future requestAll(List<Map> permissions) native;

  @DomName('Permissions.revoke')
  @DocsEditable()
  @Experimental() // untriaged
  Future revoke(Map permission) {
    var permission_1 = convertDartToNative_Dictionary(permission);
    return _revoke_1(permission_1);
  }

  @JSName('revoke')
  @DomName('Permissions.revoke')
  @DocsEditable()
  @Experimental() // untriaged
  Future _revoke_1(permission) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('Perspective')
@Experimental() // untriaged
@Native("Perspective")
class Perspective extends TransformComponent {
  // To suppress missing implicit constructor warnings.
  factory Perspective._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Perspective.Perspective')
  @DocsEditable()
  factory Perspective(LengthValue length) {
    return Perspective._create_1(length);
  }
  static Perspective _create_1(length) =>
      JS('Perspective', 'new Perspective(#)', length);

  @DomName('Perspective.length')
  @DocsEditable()
  @Experimental() // untriaged
  final LengthValue length;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLPictureElement')
@Experimental() // untriaged
@Native("HTMLPictureElement")
class PictureElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory PictureElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  PictureElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('Plugin')
@Experimental() // non-standard
@Native("Plugin")
class Plugin extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Plugin._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Plugin.description')
  @DocsEditable()
  final String description;

  @DomName('Plugin.filename')
  @DocsEditable()
  final String filename;

  @DomName('Plugin.length')
  @DocsEditable()
  final int length;

  @DomName('Plugin.name')
  @DocsEditable()
  final String name;

  @DomName('Plugin.item')
  @DocsEditable()
  MimeType item(int index) native;

  @DomName('Plugin.namedItem')
  @DocsEditable()
  MimeType namedItem(String name) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('PluginArray')
@Experimental() // non-standard
@Native("PluginArray")
class PluginArray extends Interceptor
    with ListMixin<Plugin>, ImmutableListMixin<Plugin>
    implements JavaScriptIndexingBehavior<Plugin>, List<Plugin> {
  // To suppress missing implicit constructor warnings.
  factory PluginArray._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PluginArray.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  Plugin operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("Plugin", "#[#]", this, index);
  }

  void operator []=(int index, Plugin value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Plugin> mixins.
  // Plugin is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Plugin get first {
    if (this.length > 0) {
      return JS('Plugin', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Plugin get last {
    int len = this.length;
    if (len > 0) {
      return JS('Plugin', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Plugin get single {
    int len = this.length;
    if (len == 1) {
      return JS('Plugin', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Plugin elementAt(int index) => this[index];
  // -- end List<Plugin> mixins.

  @DomName('PluginArray.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('PointerEvent')
@Experimental() // untriaged
@Native("PointerEvent")
class PointerEvent extends MouseEvent {
  // To suppress missing implicit constructor warnings.
  factory PointerEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PointerEvent.PointerEvent')
  @DocsEditable()
  factory PointerEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return PointerEvent._create_1(type, eventInitDict_1);
    }
    return PointerEvent._create_2(type);
  }
  static PointerEvent _create_1(type, eventInitDict) =>
      JS('PointerEvent', 'new PointerEvent(#,#)', type, eventInitDict);
  static PointerEvent _create_2(type) =>
      JS('PointerEvent', 'new PointerEvent(#)', type);

  @DomName('PointerEvent.height')
  @DocsEditable()
  @Experimental() // untriaged
  final double height;

  @DomName('PointerEvent.isPrimary')
  @DocsEditable()
  @Experimental() // untriaged
  final bool isPrimary;

  @DomName('PointerEvent.pointerId')
  @DocsEditable()
  @Experimental() // untriaged
  final int pointerId;

  @DomName('PointerEvent.pointerType')
  @DocsEditable()
  @Experimental() // untriaged
  final String pointerType;

  @DomName('PointerEvent.pressure')
  @DocsEditable()
  @Experimental() // untriaged
  final double pressure;

  @DomName('PointerEvent.tiltX')
  @DocsEditable()
  @Experimental() // untriaged
  final int tiltX;

  @DomName('PointerEvent.tiltY')
  @DocsEditable()
  @Experimental() // untriaged
  final int tiltY;

  @DomName('PointerEvent.width')
  @DocsEditable()
  @Experimental() // untriaged
  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('PopStateEvent')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
@Native("PopStateEvent")
class PopStateEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory PopStateEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PopStateEvent.PopStateEvent')
  @DocsEditable()
  factory PopStateEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return PopStateEvent._create_1(type, eventInitDict_1);
    }
    return PopStateEvent._create_2(type);
  }
  static PopStateEvent _create_1(type, eventInitDict) =>
      JS('PopStateEvent', 'new PopStateEvent(#,#)', type, eventInitDict);
  static PopStateEvent _create_2(type) =>
      JS('PopStateEvent', 'new PopStateEvent(#)', type);

  @DomName('PopStateEvent.state')
  @DocsEditable()
  dynamic get state =>
      convertNativeToDart_SerializedScriptValue(this._get_state);
  @JSName('state')
  @DomName('PopStateEvent.state')
  @DocsEditable()
  @annotation_Creates_SerializedScriptValue
  @annotation_Returns_SerializedScriptValue
  final dynamic _get_state;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('PositionCallback')
@Unstable()
typedef void _PositionCallback(Geoposition position);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('PositionError')
@Unstable()
@Native("PositionError")
class PositionError extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PositionError._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PositionError.PERMISSION_DENIED')
  @DocsEditable()
  static const int PERMISSION_DENIED = 1;

  @DomName('PositionError.POSITION_UNAVAILABLE')
  @DocsEditable()
  static const int POSITION_UNAVAILABLE = 2;

  @DomName('PositionError.TIMEOUT')
  @DocsEditable()
  static const int TIMEOUT = 3;

  @DomName('PositionError.code')
  @DocsEditable()
  final int code;

  @DomName('PositionError.message')
  @DocsEditable()
  final String message;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('PositionErrorCallback')
@Unstable()
typedef void _PositionErrorCallback(PositionError error);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('PositionSensorVRDevice')
@Experimental() // untriaged
@Native("PositionSensorVRDevice")
class PositionSensorVRDevice extends VRDevice {
  // To suppress missing implicit constructor warnings.
  factory PositionSensorVRDevice._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PositionSensorVRDevice.getImmediateState')
  @DocsEditable()
  @Experimental() // untriaged
  VRPositionState getImmediateState() native;

  @DomName('PositionSensorVRDevice.getState')
  @DocsEditable()
  @Experimental() // untriaged
  VRPositionState getState() native;

  @DomName('PositionSensorVRDevice.resetSensor')
  @DocsEditable()
  @Experimental() // untriaged
  void resetSensor() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('PositionValue')
@Experimental() // untriaged
@Native("PositionValue")
class PositionValue extends StyleValue {
  // To suppress missing implicit constructor warnings.
  factory PositionValue._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PositionValue.PositionValue')
  @DocsEditable()
  factory PositionValue(LengthValue x, LengthValue y) {
    return PositionValue._create_1(x, y);
  }
  static PositionValue _create_1(x, y) =>
      JS('PositionValue', 'new PositionValue(#,#)', x, y);

  @DomName('PositionValue.x')
  @DocsEditable()
  @Experimental() // untriaged
  final LengthValue x;

  @DomName('PositionValue.y')
  @DocsEditable()
  @Experimental() // untriaged
  final LengthValue 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('HTMLPreElement')
@Native("HTMLPreElement")
class PreElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory PreElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLPreElement.HTMLPreElement')
  @DocsEditable()
  factory PreElement() => JS('returns:PreElement;creates:PreElement;new:true',
      '#.createElement(#)', document, "pre");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  PreElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('Presentation')
@Experimental() // untriaged
@Native("Presentation")
class Presentation extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Presentation._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Presentation.defaultRequest')
  @DocsEditable()
  @Experimental() // untriaged
  PresentationRequest defaultRequest;

  @DomName('Presentation.receiver')
  @DocsEditable()
  @Experimental() // untriaged
  final PresentationReceiver receiver;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('PresentationAvailability')
@Experimental() // untriaged
@Native("PresentationAvailability")
class PresentationAvailability extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory PresentationAvailability._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PresentationAvailability.changeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  @DomName('PresentationAvailability.value')
  @DocsEditable()
  @Experimental() // untriaged
  final bool value;

  @DomName('PresentationAvailability.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('PresentationConnection')
@Experimental() // untriaged
@Native("PresentationConnection")
class PresentationConnection extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory PresentationConnection._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PresentationConnection.messageEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  @DomName('PresentationConnection.binaryType')
  @DocsEditable()
  @Experimental() // untriaged
  String binaryType;

  @DomName('PresentationConnection.id')
  @DocsEditable()
  @Experimental() // untriaged
  final String id;

  @DomName('PresentationConnection.state')
  @DocsEditable()
  @Experimental() // untriaged
  final String state;

  @DomName('PresentationConnection.close')
  @DocsEditable()
  @Experimental() // untriaged
  void close() native;

  @DomName('PresentationConnection.send')
  @DocsEditable()
  @Experimental() // untriaged
  void send(data_OR_message) native;

  @DomName('PresentationConnection.terminate')
  @DocsEditable()
  @Experimental() // untriaged
  void terminate() native;

  @DomName('PresentationConnection.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('PresentationConnectionAvailableEvent')
@Experimental() // untriaged
@Native("PresentationConnectionAvailableEvent")
class PresentationConnectionAvailableEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory PresentationConnectionAvailableEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName(
      'PresentationConnectionAvailableEvent.PresentationConnectionAvailableEvent')
  @DocsEditable()
  factory PresentationConnectionAvailableEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return PresentationConnectionAvailableEvent._create_1(
        type, eventInitDict_1);
  }
  static PresentationConnectionAvailableEvent _create_1(type, eventInitDict) =>
      JS('PresentationConnectionAvailableEvent',
          'new PresentationConnectionAvailableEvent(#,#)', type, eventInitDict);

  @DomName('PresentationConnectionAvailableEvent.connection')
  @DocsEditable()
  @Experimental() // untriaged
  final PresentationConnection connection;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('PresentationConnectionCloseEvent')
@Experimental() // untriaged
@Native("PresentationConnectionCloseEvent")
class PresentationConnectionCloseEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory PresentationConnectionCloseEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PresentationConnectionCloseEvent.PresentationConnectionCloseEvent')
  @DocsEditable()
  factory PresentationConnectionCloseEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return PresentationConnectionCloseEvent._create_1(type, eventInitDict_1);
  }
  static PresentationConnectionCloseEvent _create_1(type, eventInitDict) => JS(
      'PresentationConnectionCloseEvent',
      'new PresentationConnectionCloseEvent(#,#)',
      type,
      eventInitDict);

  @DomName('PresentationConnectionCloseEvent.message')
  @DocsEditable()
  @Experimental() // untriaged
  final String message;

  @DomName('PresentationConnectionCloseEvent.reason')
  @DocsEditable()
  @Experimental() // untriaged
  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('PresentationReceiver')
@Experimental() // untriaged
@Native("PresentationReceiver")
class PresentationReceiver extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory PresentationReceiver._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PresentationReceiver.getConnection')
  @DocsEditable()
  @Experimental() // untriaged
  Future getConnection() native;

  @DomName('PresentationReceiver.getConnections')
  @DocsEditable()
  @Experimental() // untriaged
  Future getConnections() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('PresentationRequest')
@Experimental() // untriaged
@Native("PresentationRequest")
class PresentationRequest extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory PresentationRequest._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PresentationRequest.PresentationRequest')
  @DocsEditable()
  factory PresentationRequest(String url) {
    return PresentationRequest._create_1(url);
  }
  static PresentationRequest _create_1(url) =>
      JS('PresentationRequest', 'new PresentationRequest(#)', url);

  @DomName('PresentationRequest.getAvailability')
  @DocsEditable()
  @Experimental() // untriaged
  Future getAvailability() native;

  @DomName('PresentationRequest.reconnect')
  @DocsEditable()
  @Experimental() // untriaged
  Future reconnect(String id) native;

  @DomName('PresentationRequest.start')
  @DocsEditable()
  @Experimental() // untriaged
  Future start() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('ProcessingInstruction')
@Unstable()
@Native("ProcessingInstruction")
class ProcessingInstruction extends CharacterData {
  // To suppress missing implicit constructor warnings.
  factory ProcessingInstruction._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('ProcessingInstruction.sheet')
  @DocsEditable()
  @Experimental() // non-standard
  final StyleSheet sheet;

  @DomName('ProcessingInstruction.target')
  @DocsEditable()
  final String target;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLProgressElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
@Native("HTMLProgressElement")
class ProgressElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ProgressElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLProgressElement.HTMLProgressElement')
  @DocsEditable()
  factory ProgressElement() => document.createElement("progress");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ProgressElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('progress');

  @DomName('HTMLProgressElement.labels')
  @DocsEditable()
  @Unstable()
  @Returns('NodeList|Null')
  @Creates('NodeList')
  final List<Node> labels;

  @DomName('HTMLProgressElement.max')
  @DocsEditable()
  num max;

  @DomName('HTMLProgressElement.position')
  @DocsEditable()
  final double position;

  @DomName('HTMLProgressElement.value')
  @DocsEditable()
  num value;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('ProgressEvent')
@Native("ProgressEvent")
class ProgressEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory ProgressEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('ProgressEvent.ProgressEvent')
  @DocsEditable()
  factory ProgressEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return ProgressEvent._create_1(type, eventInitDict_1);
    }
    return ProgressEvent._create_2(type);
  }
  static ProgressEvent _create_1(type, eventInitDict) =>
      JS('ProgressEvent', 'new ProgressEvent(#,#)', type, eventInitDict);
  static ProgressEvent _create_2(type) =>
      JS('ProgressEvent', 'new ProgressEvent(#)', type);

  @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('PromiseRejectionEvent')
@Experimental() // untriaged
@Native("PromiseRejectionEvent")
class PromiseRejectionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory PromiseRejectionEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PromiseRejectionEvent.PromiseRejectionEvent')
  @DocsEditable()
  factory PromiseRejectionEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return PromiseRejectionEvent._create_1(type, eventInitDict_1);
  }
  static PromiseRejectionEvent _create_1(type, eventInitDict) => JS(
      'PromiseRejectionEvent',
      'new PromiseRejectionEvent(#,#)',
      type,
      eventInitDict);

  @DomName('PromiseRejectionEvent.promise')
  @DocsEditable()
  @Experimental() // untriaged
  final Future promise;

  @DomName('PromiseRejectionEvent.reason')
  @DocsEditable()
  @Experimental() // untriaged
  final Object 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('PushEvent')
@Experimental() // untriaged
@Native("PushEvent")
class PushEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory PushEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PushEvent.PushEvent')
  @DocsEditable()
  factory PushEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return PushEvent._create_1(type, eventInitDict_1);
    }
    return PushEvent._create_2(type);
  }
  static PushEvent _create_1(type, eventInitDict) =>
      JS('PushEvent', 'new PushEvent(#,#)', type, eventInitDict);
  static PushEvent _create_2(type) => JS('PushEvent', 'new PushEvent(#)', type);

  @DomName('PushEvent.data')
  @DocsEditable()
  @Experimental() // untriaged
  final PushMessageData data;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('PushManager')
@Experimental() // untriaged
@Native("PushManager")
class PushManager extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PushManager._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PushManager.getSubscription')
  @DocsEditable()
  @Experimental() // untriaged
  Future getSubscription() native;

  @DomName('PushManager.permissionState')
  @DocsEditable()
  @Experimental() // untriaged
  Future permissionState([Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _permissionState_1(options_1);
    }
    return _permissionState_2();
  }

  @JSName('permissionState')
  @DomName('PushManager.permissionState')
  @DocsEditable()
  @Experimental() // untriaged
  Future _permissionState_1(options) native;
  @JSName('permissionState')
  @DomName('PushManager.permissionState')
  @DocsEditable()
  @Experimental() // untriaged
  Future _permissionState_2() native;

  @DomName('PushManager.subscribe')
  @DocsEditable()
  @Experimental() // untriaged
  Future subscribe([Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _subscribe_1(options_1);
    }
    return _subscribe_2();
  }

  @JSName('subscribe')
  @DomName('PushManager.subscribe')
  @DocsEditable()
  @Experimental() // untriaged
  Future _subscribe_1(options) native;
  @JSName('subscribe')
  @DomName('PushManager.subscribe')
  @DocsEditable()
  @Experimental() // untriaged
  Future _subscribe_2() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('PushMessageData')
@Experimental() // untriaged
@Native("PushMessageData")
class PushMessageData extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PushMessageData._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PushMessageData.arrayBuffer')
  @DocsEditable()
  @Experimental() // untriaged
  ByteBuffer arrayBuffer() native;

  @DomName('PushMessageData.blob')
  @DocsEditable()
  @Experimental() // untriaged
  Blob blob() native;

  @DomName('PushMessageData.json')
  @DocsEditable()
  @Experimental() // untriaged
  Object json() native;

  @DomName('PushMessageData.text')
  @DocsEditable()
  @Experimental() // untriaged
  String text() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('PushSubscription')
@Experimental() // untriaged
@Native("PushSubscription")
class PushSubscription extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory PushSubscription._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('PushSubscription.endpoint')
  @DocsEditable()
  @Experimental() // untriaged
  final String endpoint;

  @DomName('PushSubscription.getKey')
  @DocsEditable()
  @Experimental() // untriaged
  ByteBuffer getKey(String name) native;

  @DomName('PushSubscription.unsubscribe')
  @DocsEditable()
  @Experimental() // untriaged
  Future unsubscribe() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLQuoteElement')
@Native("HTMLQuoteElement")
class QuoteElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory QuoteElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLQuoteElement.HTMLQuoteElement')
  @DocsEditable()
  factory QuoteElement() => JS(
      'returns:QuoteElement;creates:QuoteElement;new:true',
      '#.createElement(#)',
      document,
      "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('RTCPeerConnectionErrorCallback')
@Experimental() // untriaged
typedef void RtcPeerConnectionErrorCallback(DomException exception);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('RTCSessionDescriptionCallback')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCSessionDescription
@Experimental()
typedef void _RtcSessionDescriptionCallback(RtcSessionDescription sdp);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('RTCStatsCallback')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCStatsCallback
@Experimental()
typedef void RtcStatsCallback(RtcStatsResponse response);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('Range')
@Unstable()
@Native("Range")
class Range extends Interceptor {
  factory Range() => document.createRange();

  factory Range.fromPoint(Point point) =>
      document._caretRangeFromPoint(point.x, point.y);
  // To suppress missing implicit constructor warnings.
  factory Range._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Range.END_TO_END')
  @DocsEditable()
  static const int END_TO_END = 2;

  @DomName('Range.END_TO_START')
  @DocsEditable()
  static const int END_TO_START = 3;

  @DomName('Range.START_TO_END')
  @DocsEditable()
  static const int START_TO_END = 1;

  @DomName('Range.START_TO_START')
  @DocsEditable()
  static const int START_TO_START = 0;

  @DomName('Range.collapsed')
  @DocsEditable()
  final bool collapsed;

  @DomName('Range.commonAncestorContainer')
  @DocsEditable()
  final Node commonAncestorContainer;

  @DomName('Range.endContainer')
  @DocsEditable()
  final Node endContainer;

  @DomName('Range.endOffset')
  @DocsEditable()
  final int endOffset;

  @DomName('Range.startContainer')
  @DocsEditable()
  final Node startContainer;

  @DomName('Range.startOffset')
  @DocsEditable()
  final int startOffset;

  @DomName('Range.cloneContents')
  @DocsEditable()
  DocumentFragment cloneContents() native;

  @DomName('Range.cloneRange')
  @DocsEditable()
  Range cloneRange() native;

  @DomName('Range.collapse')
  @DocsEditable()
  void collapse([bool toStart]) native;

  @DomName('Range.compareBoundaryPoints')
  @DocsEditable()
  @Experimental() // untriaged
  int compareBoundaryPoints(int how, Range sourceRange) native;

  @DomName('Range.comparePoint')
  @DocsEditable()
  int comparePoint(Node node, int offset) native;

  @DomName('Range.createContextualFragment')
  @DocsEditable()
  DocumentFragment createContextualFragment(String fragment) 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|Null')
  @Creates('_ClientRectList')
  List<Rectangle> getClientRects() native;

  @DomName('Range.insertNode')
  @DocsEditable()
  void insertNode(Node node) native;

  @DomName('Range.isPointInRange')
  @DocsEditable()
  bool isPointInRange(Node node, int offset) native;

  @DomName('Range.selectNode')
  @DocsEditable()
  void selectNode(Node node) native;

  @DomName('Range.selectNodeContents')
  @DocsEditable()
  void selectNodeContents(Node node) native;

  @DomName('Range.setEnd')
  @DocsEditable()
  void setEnd(Node node, int offset) native;

  @DomName('Range.setEndAfter')
  @DocsEditable()
  void setEndAfter(Node node) native;

  @DomName('Range.setEndBefore')
  @DocsEditable()
  void setEndBefore(Node node) native;

  @DomName('Range.setStart')
  @DocsEditable()
  void setStart(Node node, int offset) native;

  @DomName('Range.setStartAfter')
  @DocsEditable()
  void setStartAfter(Node node) native;

  @DomName('Range.setStartBefore')
  @DocsEditable()
  void setStartBefore(Node node) native;

  @DomName('Range.surroundContents')
  @DocsEditable()
  void surroundContents(Node newParent) native;

  /**
   * Checks if createContextualFragment is supported.
   *
   * See also:
   *
   * * [createContextualFragment]
   */
  static bool get supportsCreateContextualFragment =>
      JS('bool', '("createContextualFragment" in window.Range.prototype)');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('ReadableByteStream')
@Experimental() // untriaged
@Native("ReadableByteStream")
class ReadableByteStream extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ReadableByteStream._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('ReadableByteStream.cancel')
  @DocsEditable()
  @Experimental() // untriaged
  Future cancel([Object reason]) native;

  @DomName('ReadableByteStream.getReader')
  @DocsEditable()
  @Experimental() // untriaged
  ReadableByteStreamReader getReader() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('ReadableByteStreamReader')
@Experimental() // untriaged
@Native("ReadableByteStreamReader")
class ReadableByteStreamReader extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ReadableByteStreamReader._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('ReadableByteStreamReader.closed')
  @DocsEditable()
  @Experimental() // untriaged
  final Future closed;

  @DomName('ReadableByteStreamReader.cancel')
  @DocsEditable()
  @Experimental() // untriaged
  Future cancel([Object reason]) native;

  @DomName('ReadableByteStreamReader.read')
  @DocsEditable()
  @Experimental() // untriaged
  Future read() native;

  @DomName('ReadableByteStreamReader.releaseLock')
  @DocsEditable()
  @Experimental() // untriaged
  void releaseLock() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('ReadableStreamReader')
@Experimental() // untriaged
@Native("ReadableStreamReader")
class ReadableStreamReader extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ReadableStreamReader._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('ReadableStreamReader.closed')
  @DocsEditable()
  @Experimental() // untriaged
  final Future closed;

  @DomName('ReadableStreamReader.cancel')
  @DocsEditable()
  @Experimental() // untriaged
  Future cancel([Object reason]) native;

  @DomName('ReadableStreamReader.read')
  @DocsEditable()
  @Experimental() // untriaged
  Future read() native;

  @DomName('ReadableStreamReader.releaseLock')
  @DocsEditable()
  @Experimental() // untriaged
  void releaseLock() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('RelatedEvent')
@Experimental() // untriaged
@Native("RelatedEvent")
class RelatedEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory RelatedEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('RelatedEvent.RelatedEvent')
  @DocsEditable()
  factory RelatedEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return RelatedEvent._create_1(type, eventInitDict_1);
    }
    return RelatedEvent._create_2(type);
  }
  static RelatedEvent _create_1(type, eventInitDict) =>
      JS('RelatedEvent', 'new RelatedEvent(#,#)', type, eventInitDict);
  static RelatedEvent _create_2(type) =>
      JS('RelatedEvent', 'new RelatedEvent(#)', type);

  @DomName('RelatedEvent.relatedTarget')
  @DocsEditable()
  @Experimental() // untriaged
  EventTarget get relatedTarget =>
      _convertNativeToDart_EventTarget(this._get_relatedTarget);
  @JSName('relatedTarget')
  @DomName('RelatedEvent.relatedTarget')
  @DocsEditable()
  @Experimental() // untriaged
  final dynamic _get_relatedTarget;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('RequestAnimationFrameCallback')
typedef void RequestAnimationFrameCallback(num highResTime);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('Rotation')
@Experimental() // untriaged
@Native("Rotation")
class Rotation extends TransformComponent {
  // To suppress missing implicit constructor warnings.
  factory Rotation._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Rotation.Rotation')
  @DocsEditable()
  factory Rotation(num angle, [num x, num y, num z]) {
    if ((angle is num) && x == null && y == null && z == null) {
      return Rotation._create_1(angle);
    }
    if ((z is num) && (y is num) && (x is num) && (angle is num)) {
      return Rotation._create_2(angle, x, y, z);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static Rotation _create_1(angle) => JS('Rotation', 'new Rotation(#)', angle);
  static Rotation _create_2(angle, x, y, z) =>
      JS('Rotation', 'new Rotation(#,#,#,#)', angle, x, y, z);

  @DomName('Rotation.angle')
  @DocsEditable()
  @Experimental() // untriaged
  final double angle;

  @DomName('Rotation.x')
  @DocsEditable()
  @Experimental() // untriaged
  final double x;

  @DomName('Rotation.y')
  @DocsEditable()
  @Experimental() // untriaged
  final double y;

  @DomName('Rotation.z')
  @DocsEditable()
  @Experimental() // untriaged
  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('RTCCertificate')
@Experimental() // untriaged
@Native("RTCCertificate")
class RtcCertificate extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory RtcCertificate._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('RTCCertificate.expires')
  @DocsEditable()
  @Experimental() // untriaged
  final int expires;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('RTCDataChannel')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCDataChannel
@Experimental()
@Native("RTCDataChannel,DataChannel")
class RtcDataChannel extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory RtcDataChannel._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `close` events to event
   * handlers that are not necessarily instances of [RtcDataChannel].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCDataChannel.closeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> closeEvent =
      const EventStreamProvider<Event>('close');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [RtcDataChannel].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCDataChannel.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [RtcDataChannel].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCDataChannel.messageEvent')
  @DocsEditable()
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  /**
   * Static factory designed to expose `open` events to event
   * handlers that are not necessarily instances of [RtcDataChannel].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCDataChannel.openEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> openEvent =
      const EventStreamProvider<Event>('open');

  @DomName('RTCDataChannel.binaryType')
  @DocsEditable()
  String binaryType;

  @DomName('RTCDataChannel.bufferedAmount')
  @DocsEditable()
  final int bufferedAmount;

  @DomName('RTCDataChannel.bufferedAmountLowThreshold')
  @DocsEditable()
  @Experimental() // untriaged
  int bufferedAmountLowThreshold;

  @DomName('RTCDataChannel.id')
  @DocsEditable()
  @Experimental() // untriaged
  final int id;

  @DomName('RTCDataChannel.label')
  @DocsEditable()
  final String label;

  @DomName('RTCDataChannel.maxRetransmitTime')
  @DocsEditable()
  @Experimental() // untriaged
  final int maxRetransmitTime;

  @DomName('RTCDataChannel.maxRetransmits')
  @DocsEditable()
  @Experimental() // untriaged
  final int maxRetransmits;

  @DomName('RTCDataChannel.negotiated')
  @DocsEditable()
  @Experimental() // untriaged
  final bool negotiated;

  @DomName('RTCDataChannel.ordered')
  @DocsEditable()
  @Experimental() // untriaged
  final bool ordered;

  @DomName('RTCDataChannel.protocol')
  @DocsEditable()
  @Experimental() // untriaged
  final String protocol;

  @DomName('RTCDataChannel.readyState')
  @DocsEditable()
  final String readyState;

  @DomName('RTCDataChannel.reliable')
  @DocsEditable()
  final bool reliable;

  @DomName('RTCDataChannel.close')
  @DocsEditable()
  void close() native;

  @DomName('RTCDataChannel.send')
  @DocsEditable()
  void send(data) native;

  @JSName('send')
  @DomName('RTCDataChannel.send')
  @DocsEditable()
  void sendBlob(Blob data) native;

  @JSName('send')
  @DomName('RTCDataChannel.send')
  @DocsEditable()
  void sendByteBuffer(ByteBuffer data) native;

  @JSName('send')
  @DomName('RTCDataChannel.send')
  @DocsEditable()
  void sendString(String data) native;

  @JSName('send')
  @DomName('RTCDataChannel.send')
  @DocsEditable()
  void sendTypedData(TypedData data) native;

  /// Stream of `close` events handled by this [RtcDataChannel].
  @DomName('RTCDataChannel.onclose')
  @DocsEditable()
  Stream<Event> get onClose => closeEvent.forTarget(this);

  /// Stream of `error` events handled by this [RtcDataChannel].
  @DomName('RTCDataChannel.onerror')
  @DocsEditable()
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `message` events handled by this [RtcDataChannel].
  @DomName('RTCDataChannel.onmessage')
  @DocsEditable()
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  /// Stream of `open` events handled by this [RtcDataChannel].
  @DomName('RTCDataChannel.onopen')
  @DocsEditable()
  Stream<Event> get onOpen => openEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('RTCDataChannelEvent')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#rtcdatachannelevent
@Experimental()
@Native("RTCDataChannelEvent")
class RtcDataChannelEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory RtcDataChannelEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('RTCDataChannelEvent.channel')
  @DocsEditable()
  final RtcDataChannel channel;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('RTCDTMFSender')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCDTMFSender
@Experimental()
@Native("RTCDTMFSender")
class RtcDtmfSender extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory RtcDtmfSender._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `tonechange` events to event
   * handlers that are not necessarily instances of [RtcDtmfSender].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCDTMFSender.tonechangeEvent')
  @DocsEditable()
  static const EventStreamProvider<RtcDtmfToneChangeEvent> toneChangeEvent =
      const EventStreamProvider<RtcDtmfToneChangeEvent>('tonechange');

  @JSName('canInsertDTMF')
  @DomName('RTCDTMFSender.canInsertDTMF')
  @DocsEditable()
  final bool canInsertDtmf;

  @DomName('RTCDTMFSender.duration')
  @DocsEditable()
  final int duration;

  @DomName('RTCDTMFSender.interToneGap')
  @DocsEditable()
  final int interToneGap;

  @DomName('RTCDTMFSender.toneBuffer')
  @DocsEditable()
  final String toneBuffer;

  @DomName('RTCDTMFSender.track')
  @DocsEditable()
  final MediaStreamTrack track;

  @JSName('insertDTMF')
  @DomName('RTCDTMFSender.insertDTMF')
  @DocsEditable()
  void insertDtmf(String tones, [int duration, int interToneGap]) native;

  /// Stream of `tonechange` events handled by this [RtcDtmfSender].
  @DomName('RTCDTMFSender.ontonechange')
  @DocsEditable()
  Stream<RtcDtmfToneChangeEvent> get onToneChange =>
      toneChangeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('RTCDTMFToneChangeEvent')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCDTMFToneChangeEvent
@Experimental()
@Native("RTCDTMFToneChangeEvent")
class RtcDtmfToneChangeEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory RtcDtmfToneChangeEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('RTCDTMFToneChangeEvent.RTCDTMFToneChangeEvent')
  @DocsEditable()
  factory RtcDtmfToneChangeEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return RtcDtmfToneChangeEvent._create_1(type, eventInitDict_1);
  }
  static RtcDtmfToneChangeEvent _create_1(type, eventInitDict) => JS(
      'RtcDtmfToneChangeEvent',
      'new RTCDTMFToneChangeEvent(#,#)',
      type,
      eventInitDict);

  @DomName('RTCDTMFToneChangeEvent.tone')
  @DocsEditable()
  final String tone;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DomName('RTCIceCandidate')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCIceCandidate
@Native("RTCIceCandidate,mozRTCIceCandidate")
class RtcIceCandidate extends Interceptor {
  factory RtcIceCandidate(Map dictionary) {
    // TODO(efortuna): Remove this check if when you can actually construct with
    // the unprefixed RTCIceCandidate in Firefox (currently both are defined,
    // but one can't be used as a constructor).
    var constructorName = JS(
        '',
        'window[#]',
        Device.isFirefox
            ? '${Device.propertyPrefix}RTCIceCandidate'
            : 'RTCIceCandidate');
    return JS('RtcIceCandidate', 'new #(#)', constructorName,
        convertDartToNative_SerializedScriptValue(dictionary));
  }
  // To suppress missing implicit constructor warnings.
  factory RtcIceCandidate._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('RTCIceCandidate.candidate')
  @DocsEditable()
  String candidate;

  @DomName('RTCIceCandidate.sdpMLineIndex')
  @DocsEditable()
  int sdpMLineIndex;

  @DomName('RTCIceCandidate.sdpMid')
  @DocsEditable()
  String sdpMid;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('RTCIceCandidateEvent')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#rtcicecandidate-type
@Experimental()
@Native("RTCIceCandidateEvent,RTCPeerConnectionIceEvent")
class RtcIceCandidateEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory RtcIceCandidateEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('RTCIceCandidateEvent.candidate')
  @DocsEditable()
  final RtcIceCandidate candidate;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DomName('RTCPeerConnection')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCPeerConnection
@Native("RTCPeerConnection,webkitRTCPeerConnection,mozRTCPeerConnection")
class RtcPeerConnection extends EventTarget {
  factory RtcPeerConnection(Map rtcIceServers, [Map mediaConstraints]) {
    var constructorName = JS('RtcPeerConnection', 'window[#]',
        '${Device.propertyPrefix}RTCPeerConnection');
    if (mediaConstraints != null) {
      return JS(
          'RtcPeerConnection',
          'new #(#,#)',
          constructorName,
          convertDartToNative_SerializedScriptValue(rtcIceServers),
          convertDartToNative_SerializedScriptValue(mediaConstraints));
    } else {
      return JS('RtcPeerConnection', 'new #(#)', constructorName,
          convertDartToNative_SerializedScriptValue(rtcIceServers));
    }
  }

  /**
   * Checks if Real Time Communication (RTC) APIs are supported and enabled on
   * the current platform.
   */
  static bool get supported {
    // Currently in Firefox some of the RTC elements are defined but throw an
    // error unless the user has specifically enabled them in their
    // about:config. So we have to construct an element to actually test if RTC
    // is supported at the given time.
    try {
      new RtcPeerConnection({
        "iceServers": [
          {"url": "stun:localhost"}
        ]
      });
      return true;
    } catch (_) {
      return false;
    }
    return false;
  }

  Future<RtcSessionDescription> createOffer([Map mediaConstraints]) {
    var completer = new Completer<RtcSessionDescription>();
    _createOffer((value) {
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    }, mediaConstraints);
    return completer.future;
  }

  Future<RtcSessionDescription> createAnswer([Map mediaConstraints]) {
    var completer = new Completer<RtcSessionDescription>();
    _createAnswer((value) {
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    }, mediaConstraints);
    return completer.future;
  }

  @DomName('RTCPeerConnection.getStats')
  Future<RtcStatsResponse> getStats(MediaStreamTrack selector) {
    var completer = new Completer<RtcStatsResponse>();
    _getStats((value) {
      completer.complete(value);
    }, selector);
    return completer.future;
  }

  @DomName('RTCPeerConnection.generateCertificate')
  @DocsEditable()
  @Experimental() // untriaged
  static Future generateCertificate(/*AlgorithmIdentifier*/ keygenAlgorithm) =>
      JS('dynamic', 'generateCertificate(#)', keygenAlgorithm);

  // 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()
  Future addIceCandidate(candidate,
      [VoidCallback successCallback,
      RtcPeerConnectionErrorCallback 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,
      RtcPeerConnectionErrorCallback 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,
      RtcPeerConnectionErrorCallback failureCallback, mediaConstraints) native;
  @JSName('createAnswer')
  @DomName('RTCPeerConnection.createAnswer')
  @DocsEditable()
  void _createAnswer_2(_RtcSessionDescriptionCallback successCallback,
      RtcPeerConnectionErrorCallback 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,
      RtcPeerConnectionErrorCallback failureCallback,
      [Map rtcOfferOptions]) {
    if (rtcOfferOptions != null) {
      var rtcOfferOptions_1 = convertDartToNative_Dictionary(rtcOfferOptions);
      _createOffer_1(successCallback, failureCallback, rtcOfferOptions_1);
      return;
    }
    _createOffer_2(successCallback, failureCallback);
    return;
  }

  @JSName('createOffer')
  @DomName('RTCPeerConnection.createOffer')
  @DocsEditable()
  void _createOffer_1(_RtcSessionDescriptionCallback successCallback,
      RtcPeerConnectionErrorCallback failureCallback, rtcOfferOptions) native;
  @JSName('createOffer')
  @DomName('RTCPeerConnection.createOffer')
  @DocsEditable()
  void _createOffer_2(_RtcSessionDescriptionCallback successCallback,
      RtcPeerConnectionErrorCallback 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()
  Future _setLocalDescription(
      RtcSessionDescription description, VoidCallback successCallback,
      [RtcPeerConnectionErrorCallback 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()
  Future _setRemoteDescription(
      RtcSessionDescription description, VoidCallback successCallback,
      [RtcPeerConnectionErrorCallback failureCallback]) native;

  @JSName('setRemoteDescription')
  @DomName('RTCPeerConnection.setRemoteDescription')
  @DocsEditable()
  Future setRemoteDescription(RtcSessionDescription description) {
    var completer = new Completer();
    _setRemoteDescription(description, () {
      completer.complete();
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  @DomName('RTCPeerConnection.updateIce')
  @DocsEditable()
  void updateIce([Map configuration, Map mediaConstraints]) {
    if (mediaConstraints != null) {
      var configuration_1 = convertDartToNative_Dictionary(configuration);
      var mediaConstraints_2 = convertDartToNative_Dictionary(mediaConstraints);
      _updateIce_1(configuration_1, mediaConstraints_2);
      return;
    }
    if (configuration != null) {
      var configuration_1 = convertDartToNative_Dictionary(configuration);
      _updateIce_2(configuration_1);
      return;
    }
    _updateIce_3();
    return;
  }

  @JSName('updateIce')
  @DomName('RTCPeerConnection.updateIce')
  @DocsEditable()
  void _updateIce_1(configuration, mediaConstraints) native;
  @JSName('updateIce')
  @DomName('RTCPeerConnection.updateIce')
  @DocsEditable()
  void _updateIce_2(configuration) native;
  @JSName('updateIce')
  @DomName('RTCPeerConnection.updateIce')
  @DocsEditable()
  void _updateIce_3() native;

  /// Stream of `addstream` events handled by this [RtcPeerConnection].
  @DomName('RTCPeerConnection.onaddstream')
  @DocsEditable()
  Stream<MediaStreamEvent> get onAddStream => addStreamEvent.forTarget(this);

  /// Stream of `datachannel` events handled by this [RtcPeerConnection].
  @DomName('RTCPeerConnection.ondatachannel')
  @DocsEditable()
  Stream<RtcDataChannelEvent> get onDataChannel =>
      dataChannelEvent.forTarget(this);

  /// Stream of `icecandidate` events handled by this [RtcPeerConnection].
  @DomName('RTCPeerConnection.onicecandidate')
  @DocsEditable()
  Stream<RtcIceCandidateEvent> get onIceCandidate =>
      iceCandidateEvent.forTarget(this);

  /// Stream of `iceconnectionstatechange` events handled by this [RtcPeerConnection].
  @DomName('RTCPeerConnection.oniceconnectionstatechange')
  @DocsEditable()
  Stream<Event> get onIceConnectionStateChange =>
      iceConnectionStateChangeEvent.forTarget(this);

  /// Stream of `negotiationneeded` events handled by this [RtcPeerConnection].
  @DomName('RTCPeerConnection.onnegotiationneeded')
  @DocsEditable()
  Stream<Event> get onNegotiationNeeded =>
      negotiationNeededEvent.forTarget(this);

  /// Stream of `removestream` events handled by this [RtcPeerConnection].
  @DomName('RTCPeerConnection.onremovestream')
  @DocsEditable()
  Stream<MediaStreamEvent> get onRemoveStream =>
      removeStreamEvent.forTarget(this);

  /// Stream of `signalingstatechange` events handled by this [RtcPeerConnection].
  @DomName('RTCPeerConnection.onsignalingstatechange')
  @DocsEditable()
  Stream<Event> get onSignalingStateChange =>
      signalingStateChangeEvent.forTarget(this);
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DomName('RTCSessionDescription')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCSessionDescription
@Native("RTCSessionDescription,mozRTCSessionDescription")
class RtcSessionDescription extends Interceptor {
  factory RtcSessionDescription(Map dictionary) {
    // TODO(efortuna): Remove this check if when you can actually construct with
    // the unprefixed RTCIceCandidate in Firefox (currently both are defined,
    // but one can't be used as a constructor).
    var constructorName = JS(
        '',
        'window[#]',
        Device.isFirefox
            ? '${Device.propertyPrefix}RTCSessionDescription'
            : 'RTCSessionDescription');
    return JS('RtcSessionDescription', 'new #(#)', constructorName,
        convertDartToNative_SerializedScriptValue(dictionary));
  }
  // To suppress missing implicit constructor warnings.
  factory RtcSessionDescription._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('RTCSessionDescription.sdp')
  @DocsEditable()
  String sdp;

  @DomName('RTCSessionDescription.type')
  @DocsEditable()
  String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('RTCStatsReport')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCStatsReport
@Experimental()
@Native("RTCStatsReport")
class RtcStatsReport extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory RtcStatsReport._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('RTCStatsReport.id')
  @DocsEditable()
  final String id;

  @DomName('RTCStatsReport.timestamp')
  @DocsEditable()
  DateTime get timestamp => convertNativeToDart_DateTime(this._get_timestamp);
  @JSName('timestamp')
  @DomName('RTCStatsReport.timestamp')
  @DocsEditable()
  @Creates('Null')
  final dynamic _get_timestamp;

  @DomName('RTCStatsReport.type')
  @DocsEditable()
  final String type;

  @DomName('RTCStatsReport.names')
  @DocsEditable()
  List<String> names() native;

  @DomName('RTCStatsReport.stat')
  @DocsEditable()
  String stat(String name) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('RTCStatsResponse')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#widl-RTCStatsReport-RTCStats-getter-DOMString-id
@Experimental()
@Native("RTCStatsResponse")
class RtcStatsResponse extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory RtcStatsResponse._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('RTCStatsResponse.namedItem')
  @DocsEditable()
  RtcStatsReport namedItem(String name) native;

  @DomName('RTCStatsResponse.result')
  @DocsEditable()
  List<RtcStatsReport> result() native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('Screen')
@Native("Screen")
class Screen extends Interceptor {
  @DomName('Screen.availHeight')
  @DomName('Screen.availLeft')
  @DomName('Screen.availTop')
  @DomName('Screen.availWidth')
  Rectangle get available =>
      new Rectangle(_availLeft, _availTop, _availWidth, _availHeight);
  // To suppress missing implicit constructor warnings.
  factory Screen._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('availHeight')
  @DomName('Screen.availHeight')
  @DocsEditable()
  final int _availHeight;

  @JSName('availLeft')
  @DomName('Screen.availLeft')
  @DocsEditable()
  @Experimental() // nonstandard
  final int _availLeft;

  @JSName('availTop')
  @DomName('Screen.availTop')
  @DocsEditable()
  @Experimental() // nonstandard
  final int _availTop;

  @JSName('availWidth')
  @DomName('Screen.availWidth')
  @DocsEditable()
  final int _availWidth;

  @DomName('Screen.colorDepth')
  @DocsEditable()
  final int colorDepth;

  @DomName('Screen.height')
  @DocsEditable()
  final int height;

  @DomName('Screen.keepAwake')
  @DocsEditable()
  @Experimental() // untriaged
  bool keepAwake;

  @DomName('Screen.orientation')
  @DocsEditable()
  @Experimental() // untriaged
  final ScreenOrientation orientation;

  @DomName('Screen.pixelDepth')
  @DocsEditable()
  final int pixelDepth;

  @DomName('Screen.width')
  @DocsEditable()
  final int width;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('ScreenOrientation')
@Experimental() // untriaged
@Native("ScreenOrientation")
class ScreenOrientation extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory ScreenOrientation._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('ScreenOrientation.changeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  @DomName('ScreenOrientation.angle')
  @DocsEditable()
  @Experimental() // untriaged
  final int angle;

  @DomName('ScreenOrientation.type')
  @DocsEditable()
  @Experimental() // untriaged
  final String type;

  @DomName('ScreenOrientation.lock')
  @DocsEditable()
  @Experimental() // untriaged
  Future lock(String orientation) native;

  @DomName('ScreenOrientation.unlock')
  @DocsEditable()
  @Experimental() // untriaged
  void unlock() native;

  @DomName('ScreenOrientation.onchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onChange => changeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLScriptElement')
@Native("HTMLScriptElement")
class ScriptElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ScriptElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLScriptElement.HTMLScriptElement')
  @DocsEditable()
  factory ScriptElement() => JS(
      'returns:ScriptElement;creates:ScriptElement;new:true',
      '#.createElement(#)',
      document,
      "script");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ScriptElement.created() : super.created();

  @DomName('HTMLScriptElement.async')
  @DocsEditable()
  bool async;

  @DomName('HTMLScriptElement.charset')
  @DocsEditable()
  String charset;

  @DomName('HTMLScriptElement.crossOrigin')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#attr-script-crossorigin
  @Experimental()
  String crossOrigin;

  @DomName('HTMLScriptElement.defer')
  @DocsEditable()
  bool defer;

  @DomName('HTMLScriptElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String integrity;

  @DomName('HTMLScriptElement.nonce')
  @DocsEditable()
  // https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#interaction-with-the-script-src-directive
  @Experimental()
  String nonce;

  @DomName('HTMLScriptElement.src')
  @DocsEditable()
  String src;

  @DomName('HTMLScriptElement.type')
  @DocsEditable()
  String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('ScrollState')
@Experimental() // untriaged
@Native("ScrollState")
class ScrollState extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ScrollState._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('ScrollState.ScrollState')
  @DocsEditable()
  factory ScrollState([Map scrollStateInit]) {
    if (scrollStateInit != null) {
      var scrollStateInit_1 = convertDartToNative_Dictionary(scrollStateInit);
      return ScrollState._create_1(scrollStateInit_1);
    }
    return ScrollState._create_2();
  }
  static ScrollState _create_1(scrollStateInit) =>
      JS('ScrollState', 'new ScrollState(#)', scrollStateInit);
  static ScrollState _create_2() => JS('ScrollState', 'new ScrollState()');

  @DomName('ScrollState.deltaGranularity')
  @DocsEditable()
  @Experimental() // untriaged
  final double deltaGranularity;

  @DomName('ScrollState.deltaX')
  @DocsEditable()
  @Experimental() // untriaged
  final double deltaX;

  @DomName('ScrollState.deltaY')
  @DocsEditable()
  @Experimental() // untriaged
  final double deltaY;

  @DomName('ScrollState.fromUserInput')
  @DocsEditable()
  @Experimental() // untriaged
  final bool fromUserInput;

  @DomName('ScrollState.inInertialPhase')
  @DocsEditable()
  @Experimental() // untriaged
  final bool inInertialPhase;

  @DomName('ScrollState.isBeginning')
  @DocsEditable()
  @Experimental() // untriaged
  final bool isBeginning;

  @DomName('ScrollState.isDirectManipulation')
  @DocsEditable()
  @Experimental() // untriaged
  final bool isDirectManipulation;

  @DomName('ScrollState.isEnding')
  @DocsEditable()
  @Experimental() // untriaged
  final bool isEnding;

  @DomName('ScrollState.shouldPropagate')
  @DocsEditable()
  @Experimental() // untriaged
  final bool shouldPropagate;

  @DomName('ScrollState.startPositionX')
  @DocsEditable()
  @Experimental() // untriaged
  final int startPositionX;

  @DomName('ScrollState.startPositionY')
  @DocsEditable()
  @Experimental() // untriaged
  final int startPositionY;

  @DomName('ScrollState.velocityX')
  @DocsEditable()
  @Experimental() // untriaged
  final double velocityX;

  @DomName('ScrollState.velocityY')
  @DocsEditable()
  @Experimental() // untriaged
  final double velocityY;

  @DomName('ScrollState.consumeDelta')
  @DocsEditable()
  @Experimental() // untriaged
  void consumeDelta(num x, num y) native;

  @DomName('ScrollState.distributeToScrollChainDescendant')
  @DocsEditable()
  @Experimental() // untriaged
  void distributeToScrollChainDescendant() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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('ScrollStateCallback')
@Experimental() // untriaged
typedef void ScrollStateCallback(ScrollState scrollState);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('SecurityPolicyViolationEvent')
// https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#securitypolicyviolationevent-events
@Experimental()
@Native("SecurityPolicyViolationEvent")
class SecurityPolicyViolationEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory SecurityPolicyViolationEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('SecurityPolicyViolationEvent.SecurityPolicyViolationEvent')
  @DocsEditable()
  factory SecurityPolicyViolationEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return SecurityPolicyViolationEvent._create_1(type, eventInitDict_1);
    }
    return SecurityPolicyViolationEvent._create_2(type);
  }
  static SecurityPolicyViolationEvent _create_1(type, eventInitDict) => JS(
      'SecurityPolicyViolationEvent',
      'new SecurityPolicyViolationEvent(#,#)',
      type,
      eventInitDict);
  static SecurityPolicyViolationEvent _create_2(type) => JS(
      'SecurityPolicyViolationEvent',
      'new SecurityPolicyViolationEvent(#)',
      type);

  @JSName('blockedURI')
  @DomName('SecurityPolicyViolationEvent.blockedURI')
  @DocsEditable()
  final String blockedUri;

  @DomName('SecurityPolicyViolationEvent.columnNumber')
  @DocsEditable()
  final int columnNumber;

  @JSName('documentURI')
  @DomName('SecurityPolicyViolationEvent.documentURI')
  @DocsEditable()
  final String documentUri;

  @DomName('SecurityPolicyViolationEvent.effectiveDirective')
  @DocsEditable()
  final String effectiveDirective;

  @DomName('SecurityPolicyViolationEvent.lineNumber')
  @DocsEditable()
  final int lineNumber;

  @DomName('SecurityPolicyViolationEvent.originalPolicy')
  @DocsEditable()
  final String originalPolicy;

  @DomName('SecurityPolicyViolationEvent.referrer')
  @DocsEditable()
  final String referrer;

  @DomName('SecurityPolicyViolationEvent.sourceFile')
  @DocsEditable()
  final String sourceFile;

  @DomName('SecurityPolicyViolationEvent.statusCode')
  @DocsEditable()
  @Experimental() // untriaged
  final int statusCode;

  @DomName('SecurityPolicyViolationEvent.violatedDirective')
  @DocsEditable()
  final String violatedDirective;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DomName('HTMLSelectElement')
@Native("HTMLSelectElement")
class SelectElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory SelectElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLSelectElement.HTMLSelectElement')
  @DocsEditable()
  factory SelectElement() => JS(
      'returns:SelectElement;creates:SelectElement;new:true',
      '#.createElement(#)',
      document,
      "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|Null')
  @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 option) native;

  @DomName('HTMLSelectElement.add')
  @DocsEditable()
  @Experimental() // untriaged
  void add(Object element, Object before) native;

  @DomName('HTMLSelectElement.checkValidity')
  @DocsEditable()
  bool checkValidity() native;

  @DomName('HTMLSelectElement.item')
  @DocsEditable()
  Element item(int index) native;

  @DomName('HTMLSelectElement.namedItem')
  @DocsEditable()
  OptionElement namedItem(String name) native;

  @DomName('HTMLSelectElement.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() 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<OptionElement>('option');
    return new UnmodifiableListView(options.toList());
  }

  List<OptionElement> get selectedOptions {
    // IE does not change the selected flag for single-selection items.
    if (this.multiple) {
      var options = this.options.where((o) => o.selected).toList();
      return new UnmodifiableListView(options);
    } else {
      return [this.options[this.selectedIndex]];
    }
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('Selection')
@Native("Selection")
class Selection extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Selection._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Selection.anchorNode')
  @DocsEditable()
  final Node anchorNode;

  @DomName('Selection.anchorOffset')
  @DocsEditable()
  final int anchorOffset;

  @DomName('Selection.baseNode')
  @DocsEditable()
  @Experimental() // non-standard
  final Node baseNode;

  @DomName('Selection.baseOffset')
  @DocsEditable()
  @Experimental() // non-standard
  final int baseOffset;

  @DomName('Selection.extentNode')
  @DocsEditable()
  @Experimental() // non-standard
  final Node extentNode;

  @DomName('Selection.extentOffset')
  @DocsEditable()
  @Experimental() // non-standard
  final int extentOffset;

  @DomName('Selection.focusNode')
  @DocsEditable()
  final Node focusNode;

  @DomName('Selection.focusOffset')
  @DocsEditable()
  final int focusOffset;

  @DomName('Selection.isCollapsed')
  @DocsEditable()
  final bool isCollapsed;

  @DomName('Selection.rangeCount')
  @DocsEditable()
  final int rangeCount;

  @DomName('Selection.type')
  @DocsEditable()
  @Experimental() // non-standard
  final String type;

  @DomName('Selection.addRange')
  @DocsEditable()
  void addRange(Range range) native;

  @DomName('Selection.collapse')
  @DocsEditable()
  void collapse(Node node, [int offset]) native;

  @DomName('Selection.collapseToEnd')
  @DocsEditable()
  void collapseToEnd() native;

  @DomName('Selection.collapseToStart')
  @DocsEditable()
  void collapseToStart() native;

  @DomName('Selection.containsNode')
  @DocsEditable()
  @Experimental() // non-standard
  bool containsNode(Node node, [bool allowPartialContainment]) native;

  @DomName('Selection.deleteFromDocument')
  @DocsEditable()
  void deleteFromDocument() native;

  @DomName('Selection.empty')
  @DocsEditable()
  @Experimental() // non-standard
  void empty() native;

  @DomName('Selection.extend')
  @DocsEditable()
  void extend(Node node, [int offset]) native;

  @DomName('Selection.getRangeAt')
  @DocsEditable()
  Range getRangeAt(int index) native;

  @DomName('Selection.modify')
  @DocsEditable()
  @Experimental() // non-standard
  void modify(String alter, String direction, String granularity) native;

  @DomName('Selection.removeAllRanges')
  @DocsEditable()
  void removeAllRanges() native;

  @DomName('Selection.selectAllChildren')
  @DocsEditable()
  void selectAllChildren(Node node) native;

  @DomName('Selection.setBaseAndExtent')
  @DocsEditable()
  @Experimental() // non-standard
  void setBaseAndExtent(
      Node baseNode, int baseOffset, Node extentNode, int extentOffset) native;

  @DomName('Selection.setPosition')
  @DocsEditable()
  @Experimental() // non-standard
  void setPosition(Node node, [int offset]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('ServicePort')
@Experimental() // untriaged
@Native("ServicePort")
class ServicePort extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ServicePort._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('ServicePort.data')
  @DocsEditable()
  @Experimental() // untriaged
  final Object data;

  @DomName('ServicePort.name')
  @DocsEditable()
  @Experimental() // untriaged
  final String name;

  @JSName('targetURL')
  @DomName('ServicePort.targetURL')
  @DocsEditable()
  @Experimental() // untriaged
  final String targetUrl;

  @DomName('ServicePort.close')
  @DocsEditable()
  @Experimental() // untriaged
  void close() native;

  @DomName('ServicePort.postMessage')
  @DocsEditable()
  @Experimental() // untriaged
  void postMessage(/*SerializedScriptValue*/ message,
      [List<MessagePort> transfer]) {
    if (transfer != null) {
      var message_1 = convertDartToNative_SerializedScriptValue(message);
      _postMessage_1(message_1, transfer);
      return;
    }
    var message_1 = convertDartToNative_SerializedScriptValue(message);
    _postMessage_2(message_1);
    return;
  }

  @JSName('postMessage')
  @DomName('ServicePort.postMessage')
  @DocsEditable()
  @Experimental() // untriaged
  void _postMessage_1(message, List<MessagePort> transfer) native;
  @JSName('postMessage')
  @DomName('ServicePort.postMessage')
  @DocsEditable()
  @Experimental() // untriaged
  void _postMessage_2(message) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('ServicePortCollection')
@Experimental() // untriaged
@Native("ServicePortCollection")
class ServicePortCollection extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory ServicePortCollection._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('ServicePortCollection.messageEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  @DomName('ServicePortCollection.connect')
  @DocsEditable()
  @Experimental() // untriaged
  Future connect(String url, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _connect_1(url, options_1);
    }
    return _connect_2(url);
  }

  @JSName('connect')
  @DomName('ServicePortCollection.connect')
  @DocsEditable()
  @Experimental() // untriaged
  Future _connect_1(url, options) native;
  @JSName('connect')
  @DomName('ServicePortCollection.connect')
  @DocsEditable()
  @Experimental() // untriaged
  Future _connect_2(url) native;

  @DomName('ServicePortCollection.match')
  @DocsEditable()
  @Experimental() // untriaged
  Future match(Map options) {
    var options_1 = convertDartToNative_Dictionary(options);
    return _match_1(options_1);
  }

  @JSName('match')
  @DomName('ServicePortCollection.match')
  @DocsEditable()
  @Experimental() // untriaged
  Future _match_1(options) native;

  @DomName('ServicePortCollection.matchAll')
  @DocsEditable()
  @Experimental() // untriaged
  Future matchAll([Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _matchAll_1(options_1);
    }
    return _matchAll_2();
  }

  @JSName('matchAll')
  @DomName('ServicePortCollection.matchAll')
  @DocsEditable()
  @Experimental() // untriaged
  Future _matchAll_1(options) native;
  @JSName('matchAll')
  @DomName('ServicePortCollection.matchAll')
  @DocsEditable()
  @Experimental() // untriaged
  Future _matchAll_2() native;

  @DomName('ServicePortCollection.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('ServicePortConnectEvent')
@Experimental() // untriaged
@Native("ServicePortConnectEvent")
class ServicePortConnectEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory ServicePortConnectEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('ServicePortConnectEvent.ServicePortConnectEvent')
  @DocsEditable()
  factory ServicePortConnectEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return ServicePortConnectEvent._create_1(type, eventInitDict_1);
    }
    return ServicePortConnectEvent._create_2(type);
  }
  static ServicePortConnectEvent _create_1(type, eventInitDict) => JS(
      'ServicePortConnectEvent',
      'new ServicePortConnectEvent(#,#)',
      type,
      eventInitDict);
  static ServicePortConnectEvent _create_2(type) =>
      JS('ServicePortConnectEvent', 'new ServicePortConnectEvent(#)', type);

  @DomName('ServicePortConnectEvent.origin')
  @DocsEditable()
  @Experimental() // untriaged
  final String origin;

  @JSName('targetURL')
  @DomName('ServicePortConnectEvent.targetURL')
  @DocsEditable()
  @Experimental() // untriaged
  final String targetUrl;

  @DomName('ServicePortConnectEvent.respondWith')
  @DocsEditable()
  @Experimental() // untriaged
  Future respondWith(Future 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('ServiceWorkerContainer')
@Experimental() // untriaged
@Native("ServiceWorkerContainer")
class ServiceWorkerContainer extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory ServiceWorkerContainer._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('ServiceWorkerContainer.messageEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  @DomName('ServiceWorkerContainer.controller')
  @DocsEditable()
  @Experimental() // untriaged
  final _ServiceWorker controller;

  @DomName('ServiceWorkerContainer.ready')
  @DocsEditable()
  @Experimental() // untriaged
  final Future ready;

  @DomName('ServiceWorkerContainer.getRegistration')
  @DocsEditable()
  @Experimental() // untriaged
  Future getRegistration([String documentURL]) native;

  @DomName('ServiceWorkerContainer.getRegistrations')
  @DocsEditable()
  @Experimental() // untriaged
  Future getRegistrations() native;

  @DomName('ServiceWorkerContainer.register')
  @DocsEditable()
  @Experimental() // untriaged
  Future register(String url, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _register_1(url, options_1);
    }
    return _register_2(url);
  }

  @JSName('register')
  @DomName('ServiceWorkerContainer.register')
  @DocsEditable()
  @Experimental() // untriaged
  Future _register_1(url, options) native;
  @JSName('register')
  @DomName('ServiceWorkerContainer.register')
  @DocsEditable()
  @Experimental() // untriaged
  Future _register_2(url) native;

  @DomName('ServiceWorkerContainer.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('ServiceWorkerGlobalScope')
@Experimental() // untriaged
@Native("ServiceWorkerGlobalScope")
class ServiceWorkerGlobalScope extends WorkerGlobalScope {
  // To suppress missing implicit constructor warnings.
  factory ServiceWorkerGlobalScope._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('ServiceWorkerGlobalScope.messageEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  @DomName('ServiceWorkerGlobalScope.clients')
  @DocsEditable()
  @Experimental() // untriaged
  final Clients clients;

  @DomName('ServiceWorkerGlobalScope.registration')
  @DocsEditable()
  @Experimental() // untriaged
  final ServiceWorkerRegistration registration;

  @DomName('ServiceWorkerGlobalScope.skipWaiting')
  @DocsEditable()
  @Experimental() // untriaged
  Future skipWaiting() native;

  @DomName('ServiceWorkerGlobalScope.onmessage')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
}
// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
// for 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.

// TODO(alanknight): Provide a nicer constructor that uses named parameters
// rather than an initialization map.
@DomName('ServiceWorkerMessageEvent')
@Experimental() // untriaged
@Native("ServiceWorkerMessageEvent")
class ServiceWorkerMessageEvent extends Event {
  // TODO(alanknight): This really should be generated by the
  // _OutputConversion in the systemnative.py script, but that doesn't
  // use those conversions right now, so do this as a one-off.
  @DomName('ServiceWorkerMessageEvent.data')
  @DocsEditable()
  dynamic get data => convertNativeToDart_SerializedScriptValue(this._get_data);

  @JSName('data')
  @DomName('ServiceWorkerMessageEvent.data')
  @DocsEditable()
  @annotation_Creates_SerializedScriptValue
  @annotation_Returns_SerializedScriptValue
  final dynamic _get_data;

  // To suppress missing implicit constructor warnings.
  factory ServiceWorkerMessageEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('ServiceWorkerMessageEvent.lastEventId')
  @DocsEditable()
  @Experimental() // untriaged
  final String lastEventId;

  @DomName('ServiceWorkerMessageEvent.origin')
  @DocsEditable()
  @Experimental() // untriaged
  final String origin;

  @DomName('ServiceWorkerMessageEvent.ports')
  @DocsEditable()
  @Experimental() // untriaged
  final List<MessagePort> ports;

  @DomName('ServiceWorkerMessageEvent.source')
  @DocsEditable()
  @Experimental() // untriaged
  @Creates('Null')
  @Returns('_ServiceWorker|MessagePort')
  final Object source;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('ServiceWorkerRegistration')
@Experimental() // untriaged
@Native("ServiceWorkerRegistration")
class ServiceWorkerRegistration extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory ServiceWorkerRegistration._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('ServiceWorkerRegistration.active')
  @DocsEditable()
  @Experimental() // untriaged
  final _ServiceWorker active;

  @DomName('ServiceWorkerRegistration.geofencing')
  @DocsEditable()
  @Experimental() // untriaged
  final Geofencing geofencing;

  @DomName('ServiceWorkerRegistration.installing')
  @DocsEditable()
  @Experimental() // untriaged
  final _ServiceWorker installing;

  @DomName('ServiceWorkerRegistration.pushManager')
  @DocsEditable()
  @Experimental() // untriaged
  final PushManager pushManager;

  @DomName('ServiceWorkerRegistration.scope')
  @DocsEditable()
  @Experimental() // untriaged
  final String scope;

  @DomName('ServiceWorkerRegistration.sync')
  @DocsEditable()
  @Experimental() // untriaged
  final SyncManager sync;

  @DomName('ServiceWorkerRegistration.waiting')
  @DocsEditable()
  @Experimental() // untriaged
  final _ServiceWorker waiting;

  @DomName('ServiceWorkerRegistration.getNotifications')
  @DocsEditable()
  @Experimental() // untriaged
  Future getNotifications([Map filter]) {
    if (filter != null) {
      var filter_1 = convertDartToNative_Dictionary(filter);
      return _getNotifications_1(filter_1);
    }
    return _getNotifications_2();
  }

  @JSName('getNotifications')
  @DomName('ServiceWorkerRegistration.getNotifications')
  @DocsEditable()
  @Experimental() // untriaged
  Future _getNotifications_1(filter) native;
  @JSName('getNotifications')
  @DomName('ServiceWorkerRegistration.getNotifications')
  @DocsEditable()
  @Experimental() // untriaged
  Future _getNotifications_2() native;

  @DomName('ServiceWorkerRegistration.showNotification')
  @DocsEditable()
  @Experimental() // untriaged
  Future showNotification(String title, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _showNotification_1(title, options_1);
    }
    return _showNotification_2(title);
  }

  @JSName('showNotification')
  @DomName('ServiceWorkerRegistration.showNotification')
  @DocsEditable()
  @Experimental() // untriaged
  Future _showNotification_1(title, options) native;
  @JSName('showNotification')
  @DomName('ServiceWorkerRegistration.showNotification')
  @DocsEditable()
  @Experimental() // untriaged
  Future _showNotification_2(title) native;

  @DomName('ServiceWorkerRegistration.unregister')
  @DocsEditable()
  @Experimental() // untriaged
  Future unregister() native;

  @DomName('ServiceWorkerRegistration.update')
  @DocsEditable()
  @Experimental() // untriaged
  Future update() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLShadowElement')
@SupportedBrowser(SupportedBrowser.CHROME, '26')
@Experimental()
// https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#shadow-element
@Native("HTMLShadowElement")
class ShadowElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ShadowElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLShadowElement.HTMLShadowElement')
  @DocsEditable()
  factory ShadowElement() => document.createElement("shadow");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  ShadowElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('shadow');

  @DomName('HTMLShadowElement.getDistributedNodes')
  @DocsEditable()
  @Experimental() // untriaged
  @Returns('NodeList|Null')
  @Creates('NodeList')
  List<Node> getDistributedNodes() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('ShadowRoot')
@SupportedBrowser(SupportedBrowser.CHROME, '26')
@Experimental()
// https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#api-shadow-root
@Native("ShadowRoot")
class ShadowRoot extends DocumentFragment {
  // To suppress missing implicit constructor warnings.
  factory ShadowRoot._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('ShadowRoot.activeElement')
  @DocsEditable()
  final Element activeElement;

  @DomName('ShadowRoot.delegatesFocus')
  @DocsEditable()
  @Experimental() // untriaged
  final bool delegatesFocus;

  @DomName('ShadowRoot.host')
  @DocsEditable()
  @Experimental() // untriaged
  final Element host;

  @JSName('innerHTML')
  @DomName('ShadowRoot.innerHTML')
  @DocsEditable()
  String innerHtml;

  @DomName('ShadowRoot.olderShadowRoot')
  @DocsEditable()
  @Experimental() // untriaged
  final ShadowRoot olderShadowRoot;

  @DomName('ShadowRoot.styleSheets')
  @DocsEditable()
  @Experimental() // untriaged
  @Returns('_StyleSheetList|Null')
  @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.elementsFromPoint')
  @DocsEditable()
  @Experimental() // untriaged
  List<Element> elementsFromPoint(int x, int y) native;

  @DomName('ShadowRoot.getSelection')
  @DocsEditable()
  Selection getSelection() native;

  static bool get supported => JS(
      'bool',
      '!!(Element.prototype.createShadowRoot||'
      'Element.prototype.webkitCreateShadowRoot)');

  static bool _shadowRootDeprecationReported = false;
  static void _shadowRootDeprecationReport() {
    if (!_shadowRootDeprecationReported) {
      window.console.warn('''
ShadowRoot.resetStyleInheritance and ShadowRoot.applyAuthorStyles now deprecated in dart:html.
Please remove them from your code.
''');
      _shadowRootDeprecationReported = true;
    }
  }

  @deprecated
  bool get resetStyleInheritance {
    _shadowRootDeprecationReport();
    // Default value from when it was specified.
    return false;
  }

  @deprecated
  set resetStyleInheritance(bool value) {
    _shadowRootDeprecationReport();
  }

  @deprecated
  bool get applyAuthorStyles {
    _shadowRootDeprecationReport();
    // Default value from when it was specified.
    return false;
  }

  @deprecated
  set applyAuthorStyles(bool value) {
    _shadowRootDeprecationReport();
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('SharedArrayBuffer')
@Experimental() // untriaged
@Native("SharedArrayBuffer")
class SharedArrayBuffer extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory SharedArrayBuffer._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('SharedArrayBuffer.byteLength')
  @DocsEditable()
  @Experimental() // untriaged
  final int byteLength;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('SharedWorker')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#shared-workers-and-the-sharedworker-interface
@Experimental()
@Native("SharedWorker")
class SharedWorker extends EventTarget implements AbstractWorker {
  // To suppress missing implicit constructor warnings.
  factory SharedWorker._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('SharedWorker.errorEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  @DomName('SharedWorker.SharedWorker')
  @DocsEditable()
  factory SharedWorker(String scriptURL, [String name]) {
    if (name != null) {
      return SharedWorker._create_1(scriptURL, name);
    }
    return SharedWorker._create_2(scriptURL);
  }
  static SharedWorker _create_1(scriptURL, name) =>
      JS('SharedWorker', 'new SharedWorker(#,#)', scriptURL, name);
  static SharedWorker _create_2(scriptURL) =>
      JS('SharedWorker', 'new SharedWorker(#)', scriptURL);

  @DomName('SharedWorker.port')
  @DocsEditable()
  final MessagePort port;

  @DomName('SharedWorker.workerStart')
  @DocsEditable()
  @Experimental() // untriaged
  final double workerStart;

  @DomName('SharedWorker.onerror')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onError => errorEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('SharedWorkerGlobalScope')
@Experimental() // untriaged
@Native("SharedWorkerGlobalScope")
class SharedWorkerGlobalScope extends WorkerGlobalScope {
  // To suppress missing implicit constructor warnings.
  factory SharedWorkerGlobalScope._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `connect` events to event
   * handlers that are not necessarily instances of [SharedWorkerGlobalScope].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SharedWorkerGlobalScope.connectEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> connectEvent =
      const EventStreamProvider<Event>('connect');

  @DomName('SharedWorkerGlobalScope.PERSISTENT')
  @DocsEditable()
  @Experimental() // untriaged
  static const int PERSISTENT = 1;

  @DomName('SharedWorkerGlobalScope.TEMPORARY')
  @DocsEditable()
  @Experimental() // untriaged
  static const int TEMPORARY = 0;

  @DomName('SharedWorkerGlobalScope.name')
  @DocsEditable()
  @Experimental() // untriaged
  final String name;

  @JSName('webkitRequestFileSystem')
  @DomName('SharedWorkerGlobalScope.webkitRequestFileSystem')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // untriaged
  void _webkitRequestFileSystem(int type, int size,
      [_FileSystemCallback successCallback,
      _ErrorCallback errorCallback]) native;

  @JSName('webkitRequestFileSystemSync')
  @DomName('SharedWorkerGlobalScope.webkitRequestFileSystemSync')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // untriaged
  _DOMFileSystemSync requestFileSystemSync(int type, int size) native;

  @JSName('webkitResolveLocalFileSystemSyncURL')
  @DomName('SharedWorkerGlobalScope.webkitResolveLocalFileSystemSyncURL')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // untriaged
  _EntrySync resolveLocalFileSystemSyncUrl(String url) native;

  @JSName('webkitResolveLocalFileSystemURL')
  @DomName('SharedWorkerGlobalScope.webkitResolveLocalFileSystemURL')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // untriaged
  void _webkitResolveLocalFileSystemUrl(
      String url, _EntryCallback successCallback,
      [_ErrorCallback errorCallback]) native;

  /// 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('SimpleLength')
@Experimental() // untriaged
@Native("SimpleLength")
class SimpleLength extends LengthValue {
  // To suppress missing implicit constructor warnings.
  factory SimpleLength._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('SimpleLength.SimpleLength')
  @DocsEditable()
  factory SimpleLength(num value, String type) {
    return SimpleLength._create_1(value, type);
  }
  static SimpleLength _create_1(value, type) =>
      JS('SimpleLength', 'new SimpleLength(#,#)', value, type);

  @DomName('SimpleLength.type')
  @DocsEditable()
  @Experimental() // untriaged
  final String type;

  @DomName('SimpleLength.value')
  @DocsEditable()
  @Experimental() // untriaged
  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('Skew')
@Experimental() // untriaged
@Native("Skew")
class Skew extends TransformComponent {
  // To suppress missing implicit constructor warnings.
  factory Skew._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Skew.Skew')
  @DocsEditable()
  factory Skew(num ax, num ay) {
    return Skew._create_1(ax, ay);
  }
  static Skew _create_1(ax, ay) => JS('Skew', 'new Skew(#,#)', ax, ay);

  @DomName('Skew.ax')
  @DocsEditable()
  @Experimental() // untriaged
  final double ax;

  @DomName('Skew.ay')
  @DocsEditable()
  @Experimental() // untriaged
  final double ay;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLSlotElement')
@Experimental() // untriaged
@Native("HTMLSlotElement")
class SlotElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory SlotElement._() {
    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.
   */
  SlotElement.created() : super.created();

  @DomName('HTMLSlotElement.name')
  @DocsEditable()
  @Experimental() // untriaged
  String name;

  @DomName('HTMLSlotElement.getAssignedNodes')
  @DocsEditable()
  @Experimental() // untriaged
  List<Node> getAssignedNodes([Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _getAssignedNodes_1(options_1);
    }
    return _getAssignedNodes_2();
  }

  @JSName('getAssignedNodes')
  @DomName('HTMLSlotElement.getAssignedNodes')
  @DocsEditable()
  @Experimental() // untriaged
  List<Node> _getAssignedNodes_1(options) native;
  @JSName('getAssignedNodes')
  @DomName('HTMLSlotElement.getAssignedNodes')
  @DocsEditable()
  @Experimental() // untriaged
  List<Node> _getAssignedNodes_2() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('SourceBuffer')
// https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#sourcebuffer
@Experimental()
@Native("SourceBuffer")
class SourceBuffer extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory SourceBuffer._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('SourceBuffer.appendWindowEnd')
  @DocsEditable()
  @Experimental() // untriaged
  num appendWindowEnd;

  @DomName('SourceBuffer.appendWindowStart')
  @DocsEditable()
  @Experimental() // untriaged
  num appendWindowStart;

  @DomName('SourceBuffer.buffered')
  @DocsEditable()
  final TimeRanges buffered;

  @DomName('SourceBuffer.mode')
  @DocsEditable()
  @Experimental() // untriaged
  String mode;

  @DomName('SourceBuffer.timestampOffset')
  @DocsEditable()
  num timestampOffset;

  @DomName('SourceBuffer.trackDefaults')
  @DocsEditable()
  @Experimental() // untriaged
  TrackDefaultList trackDefaults;

  @DomName('SourceBuffer.updating')
  @DocsEditable()
  @Experimental() // untriaged
  final bool updating;

  @DomName('SourceBuffer.abort')
  @DocsEditable()
  void abort() native;

  @DomName('SourceBuffer.appendBuffer')
  @DocsEditable()
  @Experimental() // untriaged
  void appendBuffer(ByteBuffer data) native;

  @DomName('SourceBuffer.appendStream')
  @DocsEditable()
  @Experimental() // untriaged
  void appendStream(FileStream stream, [int maxSize]) native;

  @JSName('appendBuffer')
  @DomName('SourceBuffer.appendBuffer')
  @DocsEditable()
  @Experimental() // untriaged
  void appendTypedData(TypedData data) native;

  @DomName('SourceBuffer.remove')
  @DocsEditable()
  @Experimental() // untriaged
  void remove(num start, num end) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('SourceBufferList')
// https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#sourcebufferlist
@Experimental()
@Native("SourceBufferList")
class SourceBufferList extends EventTarget
    with ListMixin<SourceBuffer>, ImmutableListMixin<SourceBuffer>
    implements JavaScriptIndexingBehavior<SourceBuffer>, List<SourceBuffer> {
  // To suppress missing implicit constructor warnings.
  factory SourceBufferList._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('SourceBufferList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  SourceBuffer operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("SourceBuffer", "#[#]", this, index);
  }

  void operator []=(int index, SourceBuffer value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<SourceBuffer> mixins.
  // SourceBuffer is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  SourceBuffer get first {
    if (this.length > 0) {
      return JS('SourceBuffer', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  SourceBuffer get last {
    int len = this.length;
    if (len > 0) {
      return JS('SourceBuffer', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  SourceBuffer get single {
    int len = this.length;
    if (len == 1) {
      return JS('SourceBuffer', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  SourceBuffer elementAt(int index) => this[index];
  // -- end List<SourceBuffer> mixins.

  @DomName('SourceBufferList.item')
  @DocsEditable()
  SourceBuffer item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLSourceElement')
@Native("HTMLSourceElement")
class SourceElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory SourceElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLSourceElement.HTMLSourceElement')
  @DocsEditable()
  factory SourceElement() => JS(
      'returns:SourceElement;creates:SourceElement;new:true',
      '#.createElement(#)',
      document,
      "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.sizes')
  @DocsEditable()
  @Experimental() // untriaged
  String sizes;

  @DomName('HTMLSourceElement.src')
  @DocsEditable()
  String src;

  @DomName('HTMLSourceElement.srcset')
  @DocsEditable()
  @Experimental() // untriaged
  String srcset;

  @DomName('HTMLSourceElement.type')
  @DocsEditable()
  String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('SourceInfo')
@Experimental() // untriaged
@Native("SourceInfo")
class SourceInfo extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory SourceInfo._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('SourceInfo.facing')
  @DocsEditable()
  @Experimental() // untriaged
  final String facing;

  @DomName('SourceInfo.id')
  @DocsEditable()
  @Experimental() // untriaged
  final String id;

  @DomName('SourceInfo.kind')
  @DocsEditable()
  @Experimental() // untriaged
  final String kind;

  @DomName('SourceInfo.label')
  @DocsEditable()
  @Experimental() // untriaged
  final String label;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLSpanElement')
@Native("HTMLSpanElement")
class SpanElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory SpanElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLSpanElement.HTMLSpanElement')
  @DocsEditable()
  factory SpanElement() => JS(
      'returns:SpanElement;creates:SpanElement;new:true',
      '#.createElement(#)',
      document,
      "span");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  SpanElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('SpeechGrammar')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#dfn-speechgrammar
@Experimental()
@Native("SpeechGrammar")
class SpeechGrammar extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory SpeechGrammar._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('SpeechGrammar.SpeechGrammar')
  @DocsEditable()
  factory SpeechGrammar() {
    return SpeechGrammar._create_1();
  }
  static SpeechGrammar _create_1() =>
      JS('SpeechGrammar', 'new SpeechGrammar()');

  @DomName('SpeechGrammar.src')
  @DocsEditable()
  String src;

  @DomName('SpeechGrammar.weight')
  @DocsEditable()
  num weight;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('SpeechGrammarList')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#dfn-speechgrammarlist
@Experimental()
@Native("SpeechGrammarList")
class SpeechGrammarList extends Interceptor
    with ListMixin<SpeechGrammar>, ImmutableListMixin<SpeechGrammar>
    implements JavaScriptIndexingBehavior<SpeechGrammar>, List<SpeechGrammar> {
  // To suppress missing implicit constructor warnings.
  factory SpeechGrammarList._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('SpeechGrammarList.SpeechGrammarList')
  @DocsEditable()
  factory SpeechGrammarList() {
    return SpeechGrammarList._create_1();
  }
  static SpeechGrammarList _create_1() =>
      JS('SpeechGrammarList', 'new SpeechGrammarList()');

  @DomName('SpeechGrammarList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  SpeechGrammar operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("SpeechGrammar", "#[#]", this, index);
  }

  void operator []=(int index, SpeechGrammar value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<SpeechGrammar> mixins.
  // SpeechGrammar is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  SpeechGrammar get first {
    if (this.length > 0) {
      return JS('SpeechGrammar', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  SpeechGrammar get last {
    int len = this.length;
    if (len > 0) {
      return JS('SpeechGrammar', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  SpeechGrammar get single {
    int len = this.length;
    if (len == 1) {
      return JS('SpeechGrammar', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  SpeechGrammar elementAt(int index) => this[index];
  // -- end List<SpeechGrammar> mixins.

  @DomName('SpeechGrammarList.addFromString')
  @DocsEditable()
  void addFromString(String string, [num weight]) native;

  @DomName('SpeechGrammarList.addFromUri')
  @DocsEditable()
  void addFromUri(String src, [num weight]) native;

  @DomName('SpeechGrammarList.item')
  @DocsEditable()
  SpeechGrammar item(int index) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DomName('SpeechRecognition')
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechreco-section
@Native("SpeechRecognition")
class SpeechRecognition extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognition._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `audioend` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.audioendEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> audioEndEvent =
      const EventStreamProvider<Event>('audioend');

  /**
   * Static factory designed to expose `audiostart` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.audiostartEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> audioStartEvent =
      const EventStreamProvider<Event>('audiostart');

  /**
   * Static factory designed to expose `end` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.endEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> endEvent =
      const EventStreamProvider<Event>('end');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<SpeechRecognitionError> errorEvent =
      const EventStreamProvider<SpeechRecognitionError>('error');

  /**
   * Static factory designed to expose `nomatch` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.nomatchEvent')
  @DocsEditable()
  static const EventStreamProvider<SpeechRecognitionEvent> noMatchEvent =
      const EventStreamProvider<SpeechRecognitionEvent>('nomatch');

  /**
   * Static factory designed to expose `result` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.resultEvent')
  @DocsEditable()
  static const EventStreamProvider<SpeechRecognitionEvent> resultEvent =
      const EventStreamProvider<SpeechRecognitionEvent>('result');

  /**
   * Static factory designed to expose `soundend` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.soundendEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> soundEndEvent =
      const EventStreamProvider<Event>('soundend');

  /**
   * Static factory designed to expose `soundstart` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.soundstartEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> soundStartEvent =
      const EventStreamProvider<Event>('soundstart');

  /**
   * Static factory designed to expose `speechend` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.speechendEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> speechEndEvent =
      const EventStreamProvider<Event>('speechend');

  /**
   * Static factory designed to expose `speechstart` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.speechstartEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> speechStartEvent =
      const EventStreamProvider<Event>('speechstart');

  /**
   * Static factory designed to expose `start` events to event
   * handlers that are not necessarily instances of [SpeechRecognition].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechRecognition.startEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> startEvent =
      const EventStreamProvider<Event>('start');

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS(
      'bool', '!!(window.SpeechRecognition || window.webkitSpeechRecognition)');

  @DomName('SpeechRecognition.audioTrack')
  @DocsEditable()
  @Experimental() // untriaged
  MediaStreamTrack audioTrack;

  @DomName('SpeechRecognition.continuous')
  @DocsEditable()
  bool continuous;

  @DomName('SpeechRecognition.grammars')
  @DocsEditable()
  SpeechGrammarList grammars;

  @DomName('SpeechRecognition.interimResults')
  @DocsEditable()
  bool interimResults;

  @DomName('SpeechRecognition.lang')
  @DocsEditable()
  String lang;

  @DomName('SpeechRecognition.maxAlternatives')
  @DocsEditable()
  int maxAlternatives;

  @DomName('SpeechRecognition.abort')
  @DocsEditable()
  void abort() native;

  @DomName('SpeechRecognition.start')
  @DocsEditable()
  void start() native;

  @DomName('SpeechRecognition.stop')
  @DocsEditable()
  void stop() native;

  /// Stream of `audioend` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onaudioend')
  @DocsEditable()
  Stream<Event> get onAudioEnd => audioEndEvent.forTarget(this);

  /// Stream of `audiostart` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onaudiostart')
  @DocsEditable()
  Stream<Event> get onAudioStart => audioStartEvent.forTarget(this);

  /// Stream of `end` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onend')
  @DocsEditable()
  Stream<Event> get onEnd => endEvent.forTarget(this);

  /// Stream of `error` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onerror')
  @DocsEditable()
  Stream<SpeechRecognitionError> get onError => errorEvent.forTarget(this);

  /// Stream of `nomatch` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onnomatch')
  @DocsEditable()
  Stream<SpeechRecognitionEvent> get onNoMatch => noMatchEvent.forTarget(this);

  /// Stream of `result` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onresult')
  @DocsEditable()
  Stream<SpeechRecognitionEvent> get onResult => resultEvent.forTarget(this);

  /// Stream of `soundend` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onsoundend')
  @DocsEditable()
  Stream<Event> get onSoundEnd => soundEndEvent.forTarget(this);

  /// Stream of `soundstart` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onsoundstart')
  @DocsEditable()
  Stream<Event> get onSoundStart => soundStartEvent.forTarget(this);

  /// Stream of `speechend` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onspeechend')
  @DocsEditable()
  Stream<Event> get onSpeechEnd => speechEndEvent.forTarget(this);

  /// Stream of `speechstart` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onspeechstart')
  @DocsEditable()
  Stream<Event> get onSpeechStart => speechStartEvent.forTarget(this);

  /// Stream of `start` events handled by this [SpeechRecognition].
  @DomName('SpeechRecognition.onstart')
  @DocsEditable()
  Stream<Event> get onStart => startEvent.forTarget(this);

  factory SpeechRecognition() {
    return JS('SpeechRecognition',
        'new (window.SpeechRecognition || window.webkitSpeechRecognition)()');
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('SpeechRecognitionAlternative')
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechrecognitionalternative
@Native("SpeechRecognitionAlternative")
class SpeechRecognitionAlternative extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionAlternative._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('SpeechRecognitionAlternative.confidence')
  @DocsEditable()
  final double confidence;

  @DomName('SpeechRecognitionAlternative.transcript')
  @DocsEditable()
  final String transcript;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('SpeechRecognitionError')
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechreco-error
@Native("SpeechRecognitionError")
class SpeechRecognitionError extends Event {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionError._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('SpeechRecognitionError.SpeechRecognitionError')
  @DocsEditable()
  factory SpeechRecognitionError(String type, [Map initDict]) {
    if (initDict != null) {
      var initDict_1 = convertDartToNative_Dictionary(initDict);
      return SpeechRecognitionError._create_1(type, initDict_1);
    }
    return SpeechRecognitionError._create_2(type);
  }
  static SpeechRecognitionError _create_1(type, initDict) => JS(
      'SpeechRecognitionError',
      'new SpeechRecognitionError(#,#)',
      type,
      initDict);
  static SpeechRecognitionError _create_2(type) =>
      JS('SpeechRecognitionError', 'new SpeechRecognitionError(#)', type);

  @DomName('SpeechRecognitionError.error')
  @DocsEditable()
  final String error;

  @DomName('SpeechRecognitionError.message')
  @DocsEditable()
  final String message;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('SpeechRecognitionEvent')
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechreco-event
@Native("SpeechRecognitionEvent")
class SpeechRecognitionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('SpeechRecognitionEvent.SpeechRecognitionEvent')
  @DocsEditable()
  factory SpeechRecognitionEvent(String type, [Map initDict]) {
    if (initDict != null) {
      var initDict_1 = convertDartToNative_Dictionary(initDict);
      return SpeechRecognitionEvent._create_1(type, initDict_1);
    }
    return SpeechRecognitionEvent._create_2(type);
  }
  static SpeechRecognitionEvent _create_1(type, initDict) => JS(
      'SpeechRecognitionEvent',
      'new SpeechRecognitionEvent(#,#)',
      type,
      initDict);
  static SpeechRecognitionEvent _create_2(type) =>
      JS('SpeechRecognitionEvent', 'new SpeechRecognitionEvent(#)', type);

  @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|Null')
  @Creates('_SpeechRecognitionResultList')
  final List<SpeechRecognitionResult> results;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('SpeechRecognitionResult')
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechrecognitionresult
@Native("SpeechRecognitionResult")
class SpeechRecognitionResult extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionResult._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('SpeechRecognitionResult.isFinal')
  @DocsEditable()
  final bool isFinal;

  @DomName('SpeechRecognitionResult.length')
  @DocsEditable()
  final int length;

  @DomName('SpeechRecognitionResult.item')
  @DocsEditable()
  SpeechRecognitionAlternative item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('SpeechSynthesis')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section
@Experimental()
@Native("SpeechSynthesis")
class SpeechSynthesis extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory SpeechSynthesis._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('SpeechSynthesis.paused')
  @DocsEditable()
  final bool paused;

  @DomName('SpeechSynthesis.pending')
  @DocsEditable()
  final bool pending;

  @DomName('SpeechSynthesis.speaking')
  @DocsEditable()
  final bool speaking;

  @DomName('SpeechSynthesis.cancel')
  @DocsEditable()
  void cancel() native;

  @DomName('SpeechSynthesis.getVoices')
  @DocsEditable()
  List<SpeechSynthesisVoice> getVoices() native;

  @DomName('SpeechSynthesis.pause')
  @DocsEditable()
  void pause() native;

  @DomName('SpeechSynthesis.resume')
  @DocsEditable()
  void resume() native;

  @DomName('SpeechSynthesis.speak')
  @DocsEditable()
  void speak(SpeechSynthesisUtterance utterance) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('SpeechSynthesisEvent')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section
@Experimental()
@Native("SpeechSynthesisEvent")
class SpeechSynthesisEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory SpeechSynthesisEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('SpeechSynthesisEvent.charIndex')
  @DocsEditable()
  final int charIndex;

  @DomName('SpeechSynthesisEvent.elapsedTime')
  @DocsEditable()
  final double elapsedTime;

  @DomName('SpeechSynthesisEvent.name')
  @DocsEditable()
  final String name;

  @DomName('SpeechSynthesisEvent.utterance')
  @DocsEditable()
  @Experimental() // untriaged
  final SpeechSynthesisUtterance utterance;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('SpeechSynthesisUtterance')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section
@Experimental()
@Native("SpeechSynthesisUtterance")
class SpeechSynthesisUtterance extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory SpeechSynthesisUtterance._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `boundary` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechSynthesisUtterance.boundaryEvent')
  @DocsEditable()
  static const EventStreamProvider<SpeechSynthesisEvent> boundaryEvent =
      const EventStreamProvider<SpeechSynthesisEvent>('boundary');

  /**
   * Static factory designed to expose `end` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechSynthesisUtterance.endEvent')
  @DocsEditable()
  static const EventStreamProvider<SpeechSynthesisEvent> endEvent =
      const EventStreamProvider<SpeechSynthesisEvent>('end');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechSynthesisUtterance.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `mark` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechSynthesisUtterance.markEvent')
  @DocsEditable()
  static const EventStreamProvider<SpeechSynthesisEvent> markEvent =
      const EventStreamProvider<SpeechSynthesisEvent>('mark');

  /**
   * Static factory designed to expose `pause` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechSynthesisUtterance.pauseEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> pauseEvent =
      const EventStreamProvider<Event>('pause');

  /**
   * Static factory designed to expose `resume` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechSynthesisUtterance.resumeEvent')
  @DocsEditable()
  static const EventStreamProvider<SpeechSynthesisEvent> resumeEvent =
      const EventStreamProvider<SpeechSynthesisEvent>('resume');

  /**
   * Static factory designed to expose `start` events to event
   * handlers that are not necessarily instances of [SpeechSynthesisUtterance].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('SpeechSynthesisUtterance.startEvent')
  @DocsEditable()
  static const EventStreamProvider<SpeechSynthesisEvent> startEvent =
      const EventStreamProvider<SpeechSynthesisEvent>('start');

  @DomName('SpeechSynthesisUtterance.SpeechSynthesisUtterance')
  @DocsEditable()
  factory SpeechSynthesisUtterance([String text]) {
    if (text != null) {
      return SpeechSynthesisUtterance._create_1(text);
    }
    return SpeechSynthesisUtterance._create_2();
  }
  static SpeechSynthesisUtterance _create_1(text) =>
      JS('SpeechSynthesisUtterance', 'new SpeechSynthesisUtterance(#)', text);
  static SpeechSynthesisUtterance _create_2() =>
      JS('SpeechSynthesisUtterance', 'new SpeechSynthesisUtterance()');

  @DomName('SpeechSynthesisUtterance.lang')
  @DocsEditable()
  String lang;

  @DomName('SpeechSynthesisUtterance.pitch')
  @DocsEditable()
  num pitch;

  @DomName('SpeechSynthesisUtterance.rate')
  @DocsEditable()
  num rate;

  @DomName('SpeechSynthesisUtterance.text')
  @DocsEditable()
  String text;

  @DomName('SpeechSynthesisUtterance.voice')
  @DocsEditable()
  SpeechSynthesisVoice voice;

  @DomName('SpeechSynthesisUtterance.volume')
  @DocsEditable()
  num volume;

  /// Stream of `boundary` events handled by this [SpeechSynthesisUtterance].
  @DomName('SpeechSynthesisUtterance.onboundary')
  @DocsEditable()
  Stream<SpeechSynthesisEvent> get onBoundary => boundaryEvent.forTarget(this);

  /// Stream of `end` events handled by this [SpeechSynthesisUtterance].
  @DomName('SpeechSynthesisUtterance.onend')
  @DocsEditable()
  Stream<SpeechSynthesisEvent> get onEnd => endEvent.forTarget(this);

  /// Stream of `error` events handled by this [SpeechSynthesisUtterance].
  @DomName('SpeechSynthesisUtterance.onerror')
  @DocsEditable()
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `mark` events handled by this [SpeechSynthesisUtterance].
  @DomName('SpeechSynthesisUtterance.onmark')
  @DocsEditable()
  Stream<SpeechSynthesisEvent> get onMark => markEvent.forTarget(this);

  /// Stream of `pause` events handled by this [SpeechSynthesisUtterance].
  @DomName('SpeechSynthesisUtterance.onpause')
  @DocsEditable()
  Stream<Event> get onPause => pauseEvent.forTarget(this);

  /// Stream of `resume` events handled by this [SpeechSynthesisUtterance].
  @DomName('SpeechSynthesisUtterance.onresume')
  @DocsEditable()
  Stream<SpeechSynthesisEvent> get onResume => resumeEvent.forTarget(this);

  /// Stream of `start` events handled by this [SpeechSynthesisUtterance].
  @DomName('SpeechSynthesisUtterance.onstart')
  @DocsEditable()
  Stream<SpeechSynthesisEvent> get onStart => startEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('SpeechSynthesisVoice')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section
@Experimental()
@Native("SpeechSynthesisVoice")
class SpeechSynthesisVoice extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory SpeechSynthesisVoice._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('default')
  @DomName('SpeechSynthesisVoice.default')
  @DocsEditable()
  final bool defaultValue;

  @DomName('SpeechSynthesisVoice.lang')
  @DocsEditable()
  final String lang;

  @DomName('SpeechSynthesisVoice.localService')
  @DocsEditable()
  final bool localService;

  @DomName('SpeechSynthesisVoice.name')
  @DocsEditable()
  final String name;

  @JSName('voiceURI')
  @DomName('SpeechSynthesisVoice.voiceURI')
  @DocsEditable()
  final String voiceUri;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * The type used by the
 * [Window.localStorage] and [Window.sessionStorage] properties.
 * Storage is implemented as a Map&lt;String, String>.
 *
 * To store and get values, use Dart's built-in map syntax:
 *
 *     window.localStorage['key1'] = 'val1';
 *     window.localStorage['key2'] = 'val2';
 *     window.localStorage['key3'] = 'val3';
 *     assert(window.localStorage['key3'] == 'val3');
 *
 * You can use [Map](http://api.dartlang.org/dart_core/Map.html) APIs
 * such as containsValue(), clear(), and length:
 *
 *     assert(window.localStorage.containsValue('does not exist') == false);
 *     window.localStorage.clear();
 *     assert(window.localStorage.length == 0);
 *
 * For more examples of using this API, see
 * [localstorage_test.dart](http://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/tests/html/localstorage_test.dart).
 * For details on using the Map API, see the
 * [Maps](https://www.dartlang.org/guides/libraries/library-tour#maps)
 * section of the library tour.
 */
@DomName('Storage')
@Unstable()
@Native("Storage")
class Storage extends Interceptor implements Map<String, String> {
  void addAll(Map<String, String> other) {
    other.forEach((k, v) {
      this[k] = v;
    });
  }

  // TODO(nweiz): update this when maps support lazy iteration
  bool containsValue(Object value) => values.any((e) => e == value);

  bool containsKey(Object key) => _getItem(key) != null;

  String operator [](Object 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(Object 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 = <String>[];
    forEach((k, v) => keys.add(k));
    return keys;
  }

  Iterable<String> get values {
    final values = <String>[];
    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 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('StorageErrorCallback')
// http://www.w3.org/TR/quota-api/#storageerrorcallback-callback
@Experimental()
typedef void StorageErrorCallback(DomError error);
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('StorageEvent')
@Unstable()
@Native("StorageEvent")
class StorageEvent extends Event {
  factory StorageEvent(String type,
      {bool canBubble: false,
      bool cancelable: false,
      String key,
      String oldValue,
      String newValue,
      String url,
      Storage storageArea}) {
    StorageEvent e = document._createEvent("StorageEvent");
    e._initStorageEvent(
        type, canBubble, cancelable, key, oldValue, newValue, url, storageArea);
    return e;
  }

  @DomName('StorageEvent.StorageEvent')
  @DocsEditable()
  factory StorageEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return StorageEvent._create_1(type, eventInitDict_1);
    }
    return StorageEvent._create_2(type);
  }
  static StorageEvent _create_1(type, eventInitDict) =>
      JS('StorageEvent', 'new StorageEvent(#,#)', type, eventInitDict);
  static StorageEvent _create_2(type) =>
      JS('StorageEvent', 'new StorageEvent(#)', type);

  @DomName('StorageEvent.key')
  @DocsEditable()
  final String key;

  @DomName('StorageEvent.newValue')
  @DocsEditable()
  final String newValue;

  @DomName('StorageEvent.oldValue')
  @DocsEditable()
  final String oldValue;

  @DomName('StorageEvent.storageArea')
  @DocsEditable()
  final Storage storageArea;

  @DomName('StorageEvent.url')
  @DocsEditable()
  final String url;

  @JSName('initStorageEvent')
  @DomName('StorageEvent.initStorageEvent')
  @DocsEditable()
  void _initStorageEvent(
      String typeArg,
      bool canBubbleArg,
      bool cancelableArg,
      String keyArg,
      String oldValueArg,
      String newValueArg,
      String urlArg,
      Storage storageAreaArg) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('StorageInfo')
// http://www.w3.org/TR/file-system-api/
@Experimental()
@Native("StorageInfo")
class StorageInfo extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory StorageInfo._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('StorageInfo.quota')
  @DocsEditable()
  @Experimental() // untriaged
  final int quota;

  @DomName('StorageInfo.usage')
  @DocsEditable()
  @Experimental() // untriaged
  final int usage;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('StorageManager')
@Experimental() // untriaged
@Native("StorageManager")
class StorageManager extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory StorageManager._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('StorageManager.persistentPermission')
  @DocsEditable()
  @Experimental() // untriaged
  Future persistentPermission() native;

  @DomName('StorageManager.requestPersistent')
  @DocsEditable()
  @Experimental() // untriaged
  Future requestPersistent() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('StorageQuota')
// http://www.w3.org/TR/quota-api/#idl-def-StorageQuota
@Experimental()
@Native("StorageQuota")
class StorageQuota extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory StorageQuota._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('StorageQuota.supportedTypes')
  @DocsEditable()
  @Experimental() // untriaged
  final List<String> supportedTypes;

  @DomName('StorageQuota.queryInfo')
  @DocsEditable()
  @Experimental() // untriaged
  Future queryInfo(String type) native;

  @DomName('StorageQuota.requestPersistentQuota')
  @DocsEditable()
  @Experimental() // untriaged
  Future requestPersistentQuota(int newQuota) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('StorageQuotaCallback')
// http://www.w3.org/TR/quota-api/#idl-def-StorageQuotaCallback
@Experimental()
typedef void StorageQuotaCallback(int grantedQuotaInBytes);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('StorageUsageCallback')
// http://www.w3.org/TR/quota-api/#idl-def-StorageUsageCallback
@Experimental()
typedef void StorageUsageCallback(
    int currentUsageInBytes, int currentQuotaInBytes);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('StringCallback')
// http://www.w3.org/TR/2011/WD-html5-20110113/dnd.html#the-datatransferitem-interface
@Experimental()
typedef void _StringCallback(String data);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLStyleElement')
@Native("HTMLStyleElement")
class StyleElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory StyleElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLStyleElement.HTMLStyleElement')
  @DocsEditable()
  factory StyleElement() => JS(
      'returns:StyleElement;creates:StyleElement;new:true',
      '#.createElement(#)',
      document,
      "style");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  StyleElement.created() : super.created();

  @DomName('HTMLStyleElement.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('HTMLStyleElement.media')
  @DocsEditable()
  String media;

  @DomName('HTMLStyleElement.sheet')
  @DocsEditable()
  final StyleSheet sheet;

  @DomName('HTMLStyleElement.type')
  @DocsEditable()
  String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('StyleMedia')
// http://developer.apple.com/library/safari/#documentation/SafariDOMAdditions/Reference/StyleMedia/StyleMedia/StyleMedia.html
@Experimental() // nonstandard
@Native("StyleMedia")
class StyleMedia extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory StyleMedia._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('StyleMedia.type')
  @DocsEditable()
  final String type;

  @DomName('StyleMedia.matchMedium')
  @DocsEditable()
  bool matchMedium(String mediaquery) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('StylePropertyMap')
@Experimental() // untriaged
@Native("StylePropertyMap")
class StylePropertyMap extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory StylePropertyMap._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('StylePropertyMap.append')
  @DocsEditable()
  @Experimental() // untriaged
  void append(String property, Object value) native;

  @DomName('StylePropertyMap.delete')
  @DocsEditable()
  @Experimental() // untriaged
  void delete(String property) native;

  @DomName('StylePropertyMap.get')
  @DocsEditable()
  @Experimental() // untriaged
  StyleValue get(String property) native;

  @DomName('StylePropertyMap.getAll')
  @DocsEditable()
  @Experimental() // untriaged
  List<StyleValue> getAll(String property) native;

  @DomName('StylePropertyMap.getProperties')
  @DocsEditable()
  @Experimental() // untriaged
  List<String> getProperties() native;

  @DomName('StylePropertyMap.has')
  @DocsEditable()
  @Experimental() // untriaged
  bool has(String property) native;

  @DomName('StylePropertyMap.set')
  @DocsEditable()
  @Experimental() // untriaged
  void set(String property, 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('StyleSheet')
@Native("StyleSheet")
class StyleSheet extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory StyleSheet._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('StyleSheet.disabled')
  @DocsEditable()
  bool disabled;

  @DomName('StyleSheet.href')
  @DocsEditable()
  final String href;

  @DomName('StyleSheet.media')
  @DocsEditable()
  final MediaList media;

  @DomName('StyleSheet.ownerNode')
  @DocsEditable()
  final Node ownerNode;

  @DomName('StyleSheet.parentStyleSheet')
  @DocsEditable()
  final StyleSheet parentStyleSheet;

  @DomName('StyleSheet.title')
  @DocsEditable()
  final String title;

  @DomName('StyleSheet.type')
  @DocsEditable()
  final String type;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('StyleValue')
@Experimental() // untriaged
@Native("StyleValue")
class StyleValue extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory StyleValue._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('StyleValue.cssString')
  @DocsEditable()
  @Experimental() // untriaged
  final String cssString;

  @DomName('StyleValue.parse')
  @DocsEditable()
  @Experimental() // untriaged
  static Object parse(String property, String cssText) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('SyncEvent')
@Experimental() // untriaged
@Native("SyncEvent")
class SyncEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory SyncEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('SyncEvent.SyncEvent')
  @DocsEditable()
  factory SyncEvent(String type, Map init) {
    var init_1 = convertDartToNative_Dictionary(init);
    return SyncEvent._create_1(type, init_1);
  }
  static SyncEvent _create_1(type, init) =>
      JS('SyncEvent', 'new SyncEvent(#,#)', type, init);

  @DomName('SyncEvent.lastChance')
  @DocsEditable()
  @Experimental() // untriaged
  final bool lastChance;

  @DomName('SyncEvent.tag')
  @DocsEditable()
  @Experimental() // untriaged
  final String tag;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('SyncManager')
@Experimental() // untriaged
@Native("SyncManager")
class SyncManager extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory SyncManager._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('SyncManager.getTags')
  @DocsEditable()
  @Experimental() // untriaged
  Future getTags() native;

  @DomName('SyncManager.register')
  @DocsEditable()
  @Experimental() // untriaged
  Future register(String tag) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLTableCaptionElement')
@Native("HTMLTableCaptionElement")
class TableCaptionElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory TableCaptionElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLTableCaptionElement.HTMLTableCaptionElement')
  @DocsEditable()
  factory TableCaptionElement() => JS(
      'returns:TableCaptionElement;creates:TableCaptionElement;new:true',
      '#.createElement(#)',
      document,
      "caption");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableCaptionElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLTableCellElement')
@Native(
    "HTMLTableCellElement,HTMLTableDataCellElement,HTMLTableHeaderCellElement")
class TableCellElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory TableCellElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLTableCellElement.HTMLTableCellElement')
  @DocsEditable()
  factory TableCellElement() => JS(
      'returns:TableCellElement;creates:TableCellElement;new:true',
      '#.createElement(#)',
      document,
      "td");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableCellElement.created() : super.created();

  @DomName('HTMLTableCellElement.cellIndex')
  @DocsEditable()
  final int cellIndex;

  @DomName('HTMLTableCellElement.colSpan')
  @DocsEditable()
  int colSpan;

  @DomName('HTMLTableCellElement.headers')
  @DocsEditable()
  String headers;

  @DomName('HTMLTableCellElement.rowSpan')
  @DocsEditable()
  int rowSpan;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLTableColElement')
@Native("HTMLTableColElement")
class TableColElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory TableColElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLTableColElement.HTMLTableColElement')
  @DocsEditable()
  factory TableColElement() => JS(
      'returns:TableColElement;creates:TableColElement;new:true',
      '#.createElement(#)',
      document,
      "col");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableColElement.created() : super.created();

  @DomName('HTMLTableColElement.span')
  @DocsEditable()
  int span;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLTableElement')
@Native("HTMLTableElement")
class TableElement extends HtmlElement {
  @DomName('HTMLTableElement.tBodies')
  List<TableSectionElement> get tBodies =>
      new _WrappedList<TableSectionElement>(_tBodies);

  @DomName('HTMLTableElement.rows')
  List<TableRowElement> get rows => new _WrappedList<TableRowElement>(_rows);

  TableRowElement addRow() {
    return insertRow(-1);
  }

  TableCaptionElement createCaption() => _createCaption();
  TableSectionElement createTBody() => _createTBody();
  TableSectionElement createTFoot() => _createTFoot();
  TableSectionElement createTHead() => _createTHead();
  TableRowElement insertRow(int index) => _insertRow(index);

  TableSectionElement _createTBody() {
    if (JS('bool', '!!#.createTBody', this)) {
      return this._nativeCreateTBody();
    }
    var tbody = new Element.tag('tbody');
    this.children.add(tbody);
    return tbody;
  }

  @JSName('createTBody')
  TableSectionElement _nativeCreateTBody() native;

  DocumentFragment createFragment(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    if (Range.supportsCreateContextualFragment) {
      return super.createFragment(html,
          validator: validator, treeSanitizer: treeSanitizer);
    }
    // IE9 workaround which does not support innerHTML on Table elements.
    var contextualHtml = '<table>$html</table>';
    var table = new Element.html(contextualHtml,
        validator: validator, treeSanitizer: treeSanitizer);
    var fragment = new DocumentFragment();
    fragment.nodes.addAll(table.nodes);

    return fragment;
  }

  // To suppress missing implicit constructor warnings.
  factory TableElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLTableElement.HTMLTableElement')
  @DocsEditable()
  factory TableElement() => JS(
      'returns:TableElement;creates:TableElement;new:true',
      '#.createElement(#)',
      document,
      "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|Null')
  @Creates('HtmlCollection')
  final List<Node> _rows;

  @JSName('tBodies')
  @DomName('HTMLTableElement.tBodies')
  @DocsEditable()
  @Returns('HtmlCollection|Null')
  @Creates('HtmlCollection')
  final List<Node> _tBodies;

  @DomName('HTMLTableElement.tFoot')
  @DocsEditable()
  TableSectionElement tFoot;

  @DomName('HTMLTableElement.tHead')
  @DocsEditable()
  TableSectionElement tHead;

  @JSName('createCaption')
  @DomName('HTMLTableElement.createCaption')
  @DocsEditable()
  TableCaptionElement _createCaption() native;

  @JSName('createTFoot')
  @DomName('HTMLTableElement.createTFoot')
  @DocsEditable()
  TableSectionElement _createTFoot() native;

  @JSName('createTHead')
  @DomName('HTMLTableElement.createTHead')
  @DocsEditable()
  TableSectionElement _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()
  TableRowElement _insertRow([int index]) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLTableRowElement')
@Native("HTMLTableRowElement")
class TableRowElement extends HtmlElement {
  @DomName('HTMLTableRowElement.cells')
  List<TableCellElement> get cells =>
      new _WrappedList<TableCellElement>(_cells);

  TableCellElement addCell() {
    return insertCell(-1);
  }

  TableCellElement insertCell(int index) => _insertCell(index);

  DocumentFragment createFragment(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    if (Range.supportsCreateContextualFragment) {
      return super.createFragment(html,
          validator: validator, treeSanitizer: treeSanitizer);
    }
    // IE9 workaround which does not support innerHTML on Table elements.
    var fragment = new DocumentFragment();
    var section = new TableElement()
        .createFragment(html,
            validator: validator, treeSanitizer: treeSanitizer)
        .nodes
        .single;
    var row = section.nodes.single;
    fragment.nodes.addAll(row.nodes);
    return fragment;
  }

  // To suppress missing implicit constructor warnings.
  factory TableRowElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLTableRowElement.HTMLTableRowElement')
  @DocsEditable()
  factory TableRowElement() => JS(
      'returns:TableRowElement;creates:TableRowElement;new:true',
      '#.createElement(#)',
      document,
      "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|Null')
  @Creates('HtmlCollection')
  final List<Node> _cells;

  @DomName('HTMLTableRowElement.rowIndex')
  @DocsEditable()
  final int rowIndex;

  @DomName('HTMLTableRowElement.sectionRowIndex')
  @DocsEditable()
  final int sectionRowIndex;

  @DomName('HTMLTableRowElement.deleteCell')
  @DocsEditable()
  void deleteCell(int index) native;

  @JSName('insertCell')
  @DomName('HTMLTableRowElement.insertCell')
  @DocsEditable()
  HtmlElement _insertCell([int index]) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLTableSectionElement')
@Native("HTMLTableSectionElement")
class TableSectionElement extends HtmlElement {
  @DomName('HTMLTableSectionElement.rows')
  List<TableRowElement> get rows => new _WrappedList<TableRowElement>(_rows);

  TableRowElement addRow() {
    return insertRow(-1);
  }

  TableRowElement insertRow(int index) => _insertRow(index);

  DocumentFragment createFragment(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    if (Range.supportsCreateContextualFragment) {
      return super.createFragment(html,
          validator: validator, treeSanitizer: treeSanitizer);
    }
    // IE9 workaround which does not support innerHTML on Table elements.
    var fragment = new DocumentFragment();
    var section = new TableElement()
        .createFragment(html,
            validator: validator, treeSanitizer: treeSanitizer)
        .nodes
        .single;
    fragment.nodes.addAll(section.nodes);
    return fragment;
  }

  // To suppress missing implicit constructor warnings.
  factory TableSectionElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TableSectionElement.created() : super.created();

  @JSName('rows')
  @DomName('HTMLTableSectionElement.rows')
  @DocsEditable()
  @Returns('HtmlCollection|Null')
  @Creates('HtmlCollection')
  final List<Node> _rows;

  @DomName('HTMLTableSectionElement.deleteRow')
  @DocsEditable()
  void deleteRow(int index) native;

  @JSName('insertRow')
  @DomName('HTMLTableSectionElement.insertRow')
  @DocsEditable()
  HtmlElement _insertRow([int index]) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@Experimental()
@DomName('HTMLTemplateElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#template-element
@Native("HTMLTemplateElement")
class TemplateElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory TemplateElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLTemplateElement.HTMLTemplateElement')
  @DocsEditable()
  factory TemplateElement() => document.createElement("template");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TemplateElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('template');

  @DomName('HTMLTemplateElement.content')
  @DocsEditable()
  final DocumentFragment content;

  /**
   * An override to place the contents into content rather than as child nodes.
   *
   * See also:
   *
   * * <https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#innerhtml-on-templates>
   */
  void setInnerHtml(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    text = null;
    var fragment = createFragment(html,
        validator: validator, treeSanitizer: treeSanitizer);

    content.append(fragment);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('Text')
@Native("Text")
class Text extends CharacterData {
  factory Text(String data) => JS(
      'returns:Text;depends:none;effects:none;new:true',
      '#.createTextNode(#)',
      document,
      data);
  // To suppress missing implicit constructor warnings.
  factory Text._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Text.assignedSlot')
  @DocsEditable()
  @Experimental() // untriaged
  final SlotElement assignedSlot;

  @DomName('Text.wholeText')
  @DocsEditable()
  final String wholeText;

  @DomName('Text.getDestinationInsertionPoints')
  @DocsEditable()
  @Experimental() // untriaged
  @Returns('NodeList|Null')
  @Creates('NodeList')
  List<Node> getDestinationInsertionPoints() native;

  @DomName('Text.splitText')
  @DocsEditable()
  Text splitText(int offset) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLTextAreaElement')
@Native("HTMLTextAreaElement")
class TextAreaElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory TextAreaElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLTextAreaElement.HTMLTextAreaElement')
  @DocsEditable()
  factory TextAreaElement() => JS(
      'returns:TextAreaElement;creates:TextAreaElement;new:true',
      '#.createElement(#)',
      document,
      "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.autocapitalize')
  @DocsEditable()
  @Experimental() // untriaged
  String autocapitalize;

  @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|Null')
  @Creates('NodeList')
  final List<Node> labels;

  @DomName('HTMLTextAreaElement.maxLength')
  @DocsEditable()
  int maxLength;

  @DomName('HTMLTextAreaElement.minLength')
  @DocsEditable()
  @Experimental() // untriaged
  int minLength;

  @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.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() native;

  @DomName('HTMLTextAreaElement.select')
  @DocsEditable()
  void select() native;

  @DomName('HTMLTextAreaElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) native;

  @DomName('HTMLTextAreaElement.setRangeText')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#dom-textarea/input-setrangetext
  @Experimental()
  void setRangeText(String replacement,
      {int start, int end, String selectionMode}) native;

  @DomName('HTMLTextAreaElement.setSelectionRange')
  @DocsEditable()
  void setSelectionRange(int start, int end, [String direction]) native;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('TextEvent')
@Unstable()
@Native("TextEvent")
class TextEvent extends UIEvent {
  factory TextEvent(String type,
      {bool canBubble: false,
      bool cancelable: false,
      Window view,
      String data}) {
    if (view == null) {
      view = window;
    }
    TextEvent 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 type, bool bubbles, bool cancelable, Window view,
      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.

@DocsEditable()
@DomName('TextMetrics')
@Native("TextMetrics")
class TextMetrics extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory TextMetrics._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('TextMetrics.actualBoundingBoxAscent')
  @DocsEditable()
  @Experimental() // untriaged
  final double actualBoundingBoxAscent;

  @DomName('TextMetrics.actualBoundingBoxDescent')
  @DocsEditable()
  @Experimental() // untriaged
  final double actualBoundingBoxDescent;

  @DomName('TextMetrics.actualBoundingBoxLeft')
  @DocsEditable()
  @Experimental() // untriaged
  final double actualBoundingBoxLeft;

  @DomName('TextMetrics.actualBoundingBoxRight')
  @DocsEditable()
  @Experimental() // untriaged
  final double actualBoundingBoxRight;

  @DomName('TextMetrics.alphabeticBaseline')
  @DocsEditable()
  @Experimental() // untriaged
  final double alphabeticBaseline;

  @DomName('TextMetrics.emHeightAscent')
  @DocsEditable()
  @Experimental() // untriaged
  final double emHeightAscent;

  @DomName('TextMetrics.emHeightDescent')
  @DocsEditable()
  @Experimental() // untriaged
  final double emHeightDescent;

  @DomName('TextMetrics.fontBoundingBoxAscent')
  @DocsEditable()
  @Experimental() // untriaged
  final double fontBoundingBoxAscent;

  @DomName('TextMetrics.fontBoundingBoxDescent')
  @DocsEditable()
  @Experimental() // untriaged
  final double fontBoundingBoxDescent;

  @DomName('TextMetrics.hangingBaseline')
  @DocsEditable()
  @Experimental() // untriaged
  final double hangingBaseline;

  @DomName('TextMetrics.ideographicBaseline')
  @DocsEditable()
  @Experimental() // untriaged
  final double ideographicBaseline;

  @DomName('TextMetrics.width')
  @DocsEditable()
  final double width;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('TextTrack')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#texttrack
@Experimental()
@Native("TextTrack")
class TextTrack extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory TextTrack._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `cuechange` events to event
   * handlers that are not necessarily instances of [TextTrack].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('TextTrack.cuechangeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> cueChangeEvent =
      const EventStreamProvider<Event>('cuechange');

  @DomName('TextTrack.activeCues')
  @DocsEditable()
  final TextTrackCueList activeCues;

  @DomName('TextTrack.cues')
  @DocsEditable()
  final TextTrackCueList cues;

  @DomName('TextTrack.id')
  @DocsEditable()
  @Experimental() // untriaged
  final String id;

  @DomName('TextTrack.kind')
  @DocsEditable()
  final String kind;

  @DomName('TextTrack.label')
  @DocsEditable()
  final String label;

  @DomName('TextTrack.language')
  @DocsEditable()
  final String language;

  @DomName('TextTrack.mode')
  @DocsEditable()
  String mode;

  @DomName('TextTrack.regions')
  @DocsEditable()
  @Experimental() // untriaged
  final VttRegionList regions;

  @DomName('TextTrack.addCue')
  @DocsEditable()
  void addCue(TextTrackCue cue) native;

  @DomName('TextTrack.addRegion')
  @DocsEditable()
  @Experimental() // untriaged
  void addRegion(VttRegion region) native;

  @DomName('TextTrack.removeCue')
  @DocsEditable()
  void removeCue(TextTrackCue cue) native;

  @DomName('TextTrack.removeRegion')
  @DocsEditable()
  @Experimental() // untriaged
  void removeRegion(VttRegion region) native;

  /// Stream of `cuechange` events handled by this [TextTrack].
  @DomName('TextTrack.oncuechange')
  @DocsEditable()
  Stream<Event> get onCueChange => cueChangeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('TextTrackCue')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#texttrackcue
@Experimental()
@Native("TextTrackCue")
class TextTrackCue extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory TextTrackCue._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `enter` events to event
   * handlers that are not necessarily instances of [TextTrackCue].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('TextTrackCue.enterEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> enterEvent =
      const EventStreamProvider<Event>('enter');

  /**
   * Static factory designed to expose `exit` events to event
   * handlers that are not necessarily instances of [TextTrackCue].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('TextTrackCue.exitEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> exitEvent =
      const EventStreamProvider<Event>('exit');

  @DomName('TextTrackCue.endTime')
  @DocsEditable()
  num endTime;

  @DomName('TextTrackCue.id')
  @DocsEditable()
  String id;

  @DomName('TextTrackCue.pauseOnExit')
  @DocsEditable()
  bool pauseOnExit;

  @DomName('TextTrackCue.startTime')
  @DocsEditable()
  num startTime;

  @DomName('TextTrackCue.track')
  @DocsEditable()
  final TextTrack track;

  /// Stream of `enter` events handled by this [TextTrackCue].
  @DomName('TextTrackCue.onenter')
  @DocsEditable()
  Stream<Event> get onEnter => enterEvent.forTarget(this);

  /// Stream of `exit` events handled by this [TextTrackCue].
  @DomName('TextTrackCue.onexit')
  @DocsEditable()
  Stream<Event> get onExit => exitEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('TextTrackCueList')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#texttrackcuelist
@Experimental()
@Native("TextTrackCueList")
class TextTrackCueList extends Interceptor
    with ListMixin<TextTrackCue>, ImmutableListMixin<TextTrackCue>
    implements List<TextTrackCue>, JavaScriptIndexingBehavior<TextTrackCue> {
  // To suppress missing implicit constructor warnings.
  factory TextTrackCueList._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('TextTrackCueList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  TextTrackCue operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("TextTrackCue", "#[#]", this, index);
  }

  void operator []=(int index, TextTrackCue value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<TextTrackCue> mixins.
  // TextTrackCue is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  TextTrackCue get first {
    if (this.length > 0) {
      return JS('TextTrackCue', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  TextTrackCue get last {
    int len = this.length;
    if (len > 0) {
      return JS('TextTrackCue', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  TextTrackCue get single {
    int len = this.length;
    if (len == 1) {
      return JS('TextTrackCue', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  TextTrackCue elementAt(int index) => this[index];
  // -- end List<TextTrackCue> mixins.

  @DomName('TextTrackCueList.__getter__')
  @DocsEditable()
  @Experimental() // untriaged
  TextTrackCue __getter__(int index) native;

  @DomName('TextTrackCueList.getCueById')
  @DocsEditable()
  TextTrackCue getCueById(String id) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('TextTrackList')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#texttracklist
@Experimental()
@Native("TextTrackList")
class TextTrackList extends EventTarget
    with ListMixin<TextTrack>, ImmutableListMixin<TextTrack>
    implements List<TextTrack>, JavaScriptIndexingBehavior<TextTrack> {
  // To suppress missing implicit constructor warnings.
  factory TextTrackList._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `addtrack` events to event
   * handlers that are not necessarily instances of [TextTrackList].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('TextTrackList.addtrackEvent')
  @DocsEditable()
  static const EventStreamProvider<TrackEvent> addTrackEvent =
      const EventStreamProvider<TrackEvent>('addtrack');

  @DomName('TextTrackList.changeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  @DomName('TextTrackList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  TextTrack operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("TextTrack", "#[#]", this, index);
  }

  void operator []=(int index, TextTrack value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<TextTrack> mixins.
  // TextTrack is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  TextTrack get first {
    if (this.length > 0) {
      return JS('TextTrack', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  TextTrack get last {
    int len = this.length;
    if (len > 0) {
      return JS('TextTrack', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  TextTrack get single {
    int len = this.length;
    if (len == 1) {
      return JS('TextTrack', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  TextTrack elementAt(int index) => this[index];
  // -- end List<TextTrack> mixins.

  @DomName('TextTrackList.__getter__')
  @DocsEditable()
  @Experimental() // untriaged
  TextTrack __getter__(int index) native;

  @DomName('TextTrackList.getTrackById')
  @DocsEditable()
  @Experimental() // untriaged
  TextTrack getTrackById(String id) native;

  /// Stream of `addtrack` events handled by this [TextTrackList].
  @DomName('TextTrackList.onaddtrack')
  @DocsEditable()
  Stream<TrackEvent> get onAddTrack => addTrackEvent.forTarget(this);

  @DomName('TextTrackList.onchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onChange => changeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('TimeRanges')
@Unstable()
@Native("TimeRanges")
class TimeRanges extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory TimeRanges._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('TimeRanges.length')
  @DocsEditable()
  final int length;

  @DomName('TimeRanges.end')
  @DocsEditable()
  double end(int index) native;

  @DomName('TimeRanges.start')
  @DocsEditable()
  double start(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('TimeoutHandler')
typedef void TimeoutHandler();
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLTitleElement')
@Native("HTMLTitleElement")
class TitleElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory TitleElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLTitleElement.HTMLTitleElement')
  @DocsEditable()
  factory TitleElement() => JS(
      'returns:TitleElement;creates:TitleElement;new:true',
      '#.createElement(#)',
      document,
      "title");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TitleElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('Touch')
// http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
@Experimental()
@Native("Touch")
class Touch extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory Touch._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Touch.Touch')
  @DocsEditable()
  factory Touch(Map initDict) {
    var initDict_1 = convertDartToNative_Dictionary(initDict);
    return Touch._create_1(initDict_1);
  }
  static Touch _create_1(initDict) => JS('Touch', 'new Touch(#)', initDict);

  @JSName('clientX')
  @DomName('Touch.clientX')
  @DocsEditable()
  final double _clientX;

  @JSName('clientY')
  @DomName('Touch.clientY')
  @DocsEditable()
  final double _clientY;

  @DomName('Touch.force')
  @DocsEditable()
  @Experimental() // untriaged
  final double force;

  @DomName('Touch.identifier')
  @DocsEditable()
  final int identifier;

  @JSName('pageX')
  @DomName('Touch.pageX')
  @DocsEditable()
  final double _pageX;

  @JSName('pageY')
  @DomName('Touch.pageY')
  @DocsEditable()
  final double _pageY;

  @JSName('radiusX')
  @DomName('Touch.radiusX')
  @DocsEditable()
  @Experimental() // untriaged
  final double _radiusX;

  @JSName('radiusY')
  @DomName('Touch.radiusY')
  @DocsEditable()
  @Experimental() // untriaged
  final double _radiusY;

  @DomName('Touch.region')
  @DocsEditable()
  @Experimental() // untriaged
  final String region;

  @DomName('Touch.rotationAngle')
  @DocsEditable()
  @Experimental() // untriaged
  final double rotationAngle;

  @JSName('screenX')
  @DomName('Touch.screenX')
  @DocsEditable()
  final double _screenX;

  @JSName('screenY')
  @DomName('Touch.screenY')
  @DocsEditable()
  final double _screenY;

  @DomName('Touch.target')
  @DocsEditable()
  EventTarget get target => _convertNativeToDart_EventTarget(this._get_target);
  @JSName('target')
  @DomName('Touch.target')
  @DocsEditable()
  @Creates('Element|Document')
  @Returns('Element|Document')
  final dynamic _get_target;

// As of Chrome 37, these all changed from long to double.  This code
// preserves backwards compatibility for the time being.
  int get __clientX => JS('num', '#.clientX', this).round();
  int get __clientY => JS('num', '#.clientY', this).round();
  int get __screenX => JS('num', '#.screenX', this).round();
  int get __screenY => JS('num', '#.screenY', this).round();
  int get __pageX => JS('num', '#.pageX', this).round();
  int get __pageY => JS('num', '#.pageY', this).round();
  int get __radiusX => JS('num', '#.radiusX', this).round();
  int get __radiusY => JS('num', '#.radiusY', this).round();

  @DomName('Touch.clientX')
  @DomName('Touch.clientY')
  Point get client => new Point/*<num>*/(__clientX, __clientY);

  @DomName('Touch.pageX')
  @DomName('Touch.pageY')
  Point get page => new Point/*<num>*/(__pageX, __pageY);

  @DomName('Touch.screenX')
  @DomName('Touch.screenY')
  Point get screen => new Point/*<num>*/(__screenX, __screenY);

  @DomName('Touch.radiusX')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  int get radiusX => __radiusX;

  @DomName('Touch.radiusY')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  int get radiusY => __radiusY;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('TouchEvent')
// http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
@Experimental()
@Native("TouchEvent")
class TouchEvent extends UIEvent {
  factory TouchEvent(TouchList touches, TouchList targetTouches,
      TouchList changedTouches, String type,
      {Window view,
      int screenX: 0,
      int screenY: 0,
      int clientX: 0,
      int clientY: 0,
      bool ctrlKey: false,
      bool altKey: false,
      bool shiftKey: false,
      bool metaKey: false}) {
    if (view == null) {
      view = window;
    }
    TouchEvent e = document._createEvent("TouchEvent");
    e._initTouchEvent(touches, targetTouches, changedTouches, type, view,
        screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey);
    return e;
  }
  // To suppress missing implicit constructor warnings.
  factory TouchEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('TouchEvent.altKey')
  @DocsEditable()
  final bool altKey;

  @DomName('TouchEvent.changedTouches')
  @DocsEditable()
  final TouchList changedTouches;

  @DomName('TouchEvent.ctrlKey')
  @DocsEditable()
  final bool ctrlKey;

  @DomName('TouchEvent.metaKey')
  @DocsEditable()
  final bool metaKey;

  @DomName('TouchEvent.shiftKey')
  @DocsEditable()
  final bool shiftKey;

  @DomName('TouchEvent.targetTouches')
  @DocsEditable()
  final TouchList targetTouches;

  @DomName('TouchEvent.touches')
  @DocsEditable()
  final TouchList touches;

  @JSName('initTouchEvent')
  @DomName('TouchEvent.initTouchEvent')
  @DocsEditable()
  void _initTouchEvent(
      TouchList touches,
      TouchList targetTouches,
      TouchList changedTouches,
      String type,
      Window view,
      int unused1,
      int unused2,
      int unused3,
      int unused4,
      bool ctrlKey,
      bool altKey,
      bool shiftKey,
      bool metaKey) native;

  /**
   * Checks if touch events supported on the current platform.
   *
   * Note that touch events are only supported if the user is using a touch
   * device.
   */
  static bool get supported => Device.isEventTypeSupported('TouchEvent');
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('TouchList')
// http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
@Experimental()
@Native("TouchList")
class TouchList extends Interceptor
    with ListMixin<Touch>, ImmutableListMixin<Touch>
    implements JavaScriptIndexingBehavior<Touch>, List<Touch> {
  /// NB: This constructor likely does not work as you might expect it to! This
  /// constructor will simply fail (returning null) if you are not on a device
  /// with touch enabled. See dartbug.com/8314.
  // TODO(5760): createTouchList now uses varargs.
  factory TouchList() => null; //document._createTouchList();
  // To suppress missing implicit constructor warnings.
  factory TouchList._() {
    throw new UnsupportedError("Not supported");
  }

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!document.createTouchList');

  @DomName('TouchList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  Touch operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("Touch", "#[#]", this, index);
  }

  void operator []=(int index, Touch value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Touch> mixins.
  // Touch is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Touch get first {
    if (this.length > 0) {
      return JS('Touch', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Touch get last {
    int len = this.length;
    if (len > 0) {
      return JS('Touch', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Touch get single {
    int len = this.length;
    if (len == 1) {
      return JS('Touch', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Touch elementAt(int index) => this[index];
  // -- end List<Touch> mixins.

  @DomName('TouchList.item')
  @DocsEditable()
  Touch item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('TrackDefault')
@Experimental() // untriaged
@Native("TrackDefault")
class TrackDefault extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory TrackDefault._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('TrackDefault.TrackDefault')
  @DocsEditable()
  factory TrackDefault(
      String type, String language, String label, List<String> kinds,
      [String byteStreamTrackID]) {
    if (byteStreamTrackID != null) {
      List kinds_1 = convertDartToNative_StringArray(kinds);
      return TrackDefault._create_1(
          type, language, label, kinds_1, byteStreamTrackID);
    }
    List kinds_1 = convertDartToNative_StringArray(kinds);
    return TrackDefault._create_2(type, language, label, kinds_1);
  }
  static TrackDefault _create_1(
          type, language, label, kinds, byteStreamTrackID) =>
      JS('TrackDefault', 'new TrackDefault(#,#,#,#,#)', type, language, label,
          kinds, byteStreamTrackID);
  static TrackDefault _create_2(type, language, label, kinds) => JS(
      'TrackDefault',
      'new TrackDefault(#,#,#,#)',
      type,
      language,
      label,
      kinds);

  @DomName('TrackDefault.byteStreamTrackID')
  @DocsEditable()
  @Experimental() // untriaged
  final String byteStreamTrackID;

  @DomName('TrackDefault.kinds')
  @DocsEditable()
  @Experimental() // untriaged
  final List<String> kinds;

  @DomName('TrackDefault.label')
  @DocsEditable()
  @Experimental() // untriaged
  final String label;

  @DomName('TrackDefault.language')
  @DocsEditable()
  @Experimental() // untriaged
  final String language;

  @DomName('TrackDefault.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('TrackDefaultList')
@Experimental() // untriaged
@Native("TrackDefaultList")
class TrackDefaultList extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory TrackDefaultList._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('TrackDefaultList.TrackDefaultList')
  @DocsEditable()
  factory TrackDefaultList([List<TrackDefault> trackDefaults]) {
    if (trackDefaults != null) {
      return TrackDefaultList._create_1(trackDefaults);
    }
    return TrackDefaultList._create_2();
  }
  static TrackDefaultList _create_1(trackDefaults) =>
      JS('TrackDefaultList', 'new TrackDefaultList(#)', trackDefaults);
  static TrackDefaultList _create_2() =>
      JS('TrackDefaultList', 'new TrackDefaultList()');

  @DomName('TrackDefaultList.length')
  @DocsEditable()
  @Experimental() // untriaged
  final int length;

  @DomName('TrackDefaultList.item')
  @DocsEditable()
  @Experimental() // untriaged
  TrackDefault item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLTrackElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#the-track-element
@Experimental()
@Native("HTMLTrackElement")
class TrackElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory TrackElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLTrackElement.HTMLTrackElement')
  @DocsEditable()
  factory TrackElement() => document.createElement("track");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TrackElement.created() : super.created();

  /// Checks if this type is supported on the current platform.
  static bool get supported => Element.isTagSupported('track');

  @DomName('HTMLTrackElement.ERROR')
  @DocsEditable()
  static const int ERROR = 3;

  @DomName('HTMLTrackElement.LOADED')
  @DocsEditable()
  static const int LOADED = 2;

  @DomName('HTMLTrackElement.LOADING')
  @DocsEditable()
  static const int LOADING = 1;

  @DomName('HTMLTrackElement.NONE')
  @DocsEditable()
  static const int NONE = 0;

  @JSName('default')
  @DomName('HTMLTrackElement.default')
  @DocsEditable()
  bool defaultValue;

  @DomName('HTMLTrackElement.kind')
  @DocsEditable()
  String kind;

  @DomName('HTMLTrackElement.label')
  @DocsEditable()
  String label;

  @DomName('HTMLTrackElement.readyState')
  @DocsEditable()
  final int readyState;

  @DomName('HTMLTrackElement.src')
  @DocsEditable()
  String src;

  @DomName('HTMLTrackElement.srclang')
  @DocsEditable()
  String srclang;

  @DomName('HTMLTrackElement.track')
  @DocsEditable()
  final TextTrack track;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('TrackEvent')
@Unstable()
@Native("TrackEvent")
class TrackEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory TrackEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('TrackEvent.TrackEvent')
  @DocsEditable()
  factory TrackEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return TrackEvent._create_1(type, eventInitDict_1);
    }
    return TrackEvent._create_2(type);
  }
  static TrackEvent _create_1(type, eventInitDict) =>
      JS('TrackEvent', 'new TrackEvent(#,#)', type, eventInitDict);
  static TrackEvent _create_2(type) =>
      JS('TrackEvent', 'new TrackEvent(#)', type);

  @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('TransformComponent')
@Experimental() // untriaged
@Native("TransformComponent")
class TransformComponent extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory TransformComponent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('TransformComponent.cssString')
  @DocsEditable()
  @Experimental() // untriaged
  final String cssString;

  @DomName('TransformComponent.asMatrix')
  @DocsEditable()
  @Experimental() // untriaged
  Matrix asMatrix() native;

  @DomName('TransformComponent.is2DComponent')
  @DocsEditable()
  @Experimental() // untriaged
  bool is2DComponent() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('TransformValue')
@Experimental() // untriaged
@Native("TransformValue")
class TransformValue extends StyleValue {
  // To suppress missing implicit constructor warnings.
  factory TransformValue._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('TransformValue.TransformValue')
  @DocsEditable()
  factory TransformValue([List<TransformComponent> transformComponents]) {
    if (transformComponents == null) {
      return TransformValue._create_1();
    }
    if ((transformComponents is List<TransformComponent>)) {
      return TransformValue._create_2(transformComponents);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static TransformValue _create_1() =>
      JS('TransformValue', 'new TransformValue()');
  static TransformValue _create_2(transformComponents) =>
      JS('TransformValue', 'new TransformValue(#)', transformComponents);

  @DomName('TransformValue.is2D')
  @DocsEditable()
  @Experimental() // untriaged
  bool is2D() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('TransitionEvent')
@Native("TransitionEvent,WebKitTransitionEvent")
class TransitionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory TransitionEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('TransitionEvent.TransitionEvent')
  @DocsEditable()
  factory TransitionEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return TransitionEvent._create_1(type, eventInitDict_1);
    }
    return TransitionEvent._create_2(type);
  }
  static TransitionEvent _create_1(type, eventInitDict) =>
      JS('TransitionEvent', 'new TransitionEvent(#,#)', type, eventInitDict);
  static TransitionEvent _create_2(type) =>
      JS('TransitionEvent', 'new TransitionEvent(#)', type);

  @DomName('TransitionEvent.elapsedTime')
  @DocsEditable()
  final double elapsedTime;

  @DomName('TransitionEvent.propertyName')
  @DocsEditable()
  final String propertyName;

  @DomName('TransitionEvent.pseudoElement')
  @DocsEditable()
  final String pseudoElement;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('Translation')
@Experimental() // untriaged
@Native("Translation")
class Translation extends TransformComponent {
  // To suppress missing implicit constructor warnings.
  factory Translation._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Translation.Translation')
  @DocsEditable()
  factory Translation(LengthValue x, LengthValue y, [LengthValue z]) {
    if ((y is LengthValue) && (x is LengthValue) && z == null) {
      return Translation._create_1(x, y);
    }
    if ((z is LengthValue) && (y is LengthValue) && (x is LengthValue)) {
      return Translation._create_2(x, y, z);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }
  static Translation _create_1(x, y) =>
      JS('Translation', 'new Translation(#,#)', x, y);
  static Translation _create_2(x, y, z) =>
      JS('Translation', 'new Translation(#,#,#)', x, y, z);

  @DomName('Translation.x')
  @DocsEditable()
  @Experimental() // untriaged
  final LengthValue x;

  @DomName('Translation.y')
  @DocsEditable()
  @Experimental() // untriaged
  final LengthValue y;

  @DomName('Translation.z')
  @DocsEditable()
  @Experimental() // untriaged
  final LengthValue z;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DomName('TreeWalker')
@Unstable()
@Native("TreeWalker")
class TreeWalker extends Interceptor {
  factory TreeWalker(Node root, int whatToShow) {
    return document._createTreeWalker(root, whatToShow, null);
  }
  // To suppress missing implicit constructor warnings.
  factory TreeWalker._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('TreeWalker.currentNode')
  @DocsEditable()
  Node currentNode;

  @DomName('TreeWalker.filter')
  @DocsEditable()
  final NodeFilter filter;

  @DomName('TreeWalker.root')
  @DocsEditable()
  final Node root;

  @DomName('TreeWalker.whatToShow')
  @DocsEditable()
  final int whatToShow;

  @DomName('TreeWalker.firstChild')
  @DocsEditable()
  Node firstChild() native;

  @DomName('TreeWalker.lastChild')
  @DocsEditable()
  Node lastChild() native;

  @DomName('TreeWalker.nextNode')
  @DocsEditable()
  Node nextNode() native;

  @DomName('TreeWalker.nextSibling')
  @DocsEditable()
  Node nextSibling() native;

  @DomName('TreeWalker.parentNode')
  @DocsEditable()
  Node parentNode() native;

  @DomName('TreeWalker.previousNode')
  @DocsEditable()
  Node previousNode() native;

  @DomName('TreeWalker.previousSibling')
  @DocsEditable()
  Node previousSibling() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('UIEvent')
@Native("UIEvent")
class UIEvent extends Event {
  // In JS, canBubble and cancelable are technically required parameters to
  // init*Event. In practice, though, if they aren't provided they simply
  // default to false (since that's Boolean(undefined)).
  //
  // Contrary to JS, we default canBubble and cancelable to true, since that's
  // what people want most of the time anyway.
  factory UIEvent(String type,
      {Window view,
      int detail: 0,
      bool canBubble: true,
      bool cancelable: true}) {
    if (view == null) {
      view = window;
    }
    UIEvent e = document._createEvent("UIEvent");
    e._initUIEvent(type, canBubble, cancelable, view, detail);
    return e;
  }

  @DomName('UIEvent.UIEvent')
  @DocsEditable()
  factory UIEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return UIEvent._create_1(type, eventInitDict_1);
    }
    return UIEvent._create_2(type);
  }
  static UIEvent _create_1(type, eventInitDict) =>
      JS('UIEvent', 'new UIEvent(#,#)', type, eventInitDict);
  static UIEvent _create_2(type) => JS('UIEvent', 'new UIEvent(#)', type);

  @DomName('UIEvent.detail')
  @DocsEditable()
  final int detail;

  @DomName('UIEvent.sourceCapabilities')
  @DocsEditable()
  @Experimental() // untriaged
  final InputDeviceCapabilities sourceCapabilities;

  @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;

  @JSName('which')
  @DomName('UIEvent.which')
  @DocsEditable()
  @Unstable()
  final int _which;

  @JSName('initUIEvent')
  @DomName('UIEvent.initUIEvent')
  @DocsEditable()
  void _initUIEvent(String type, bool bubbles, bool cancelable, Window view,
      int detail) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLUListElement')
@Native("HTMLUListElement")
class UListElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory UListElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLUListElement.HTMLUListElement')
  @DocsEditable()
  factory UListElement() => JS(
      'returns:UListElement;creates:UListElement;new:true',
      '#.createElement(#)',
      document,
      "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('UnderlyingSourceBase')
@Experimental() // untriaged
@Native("UnderlyingSourceBase")
class UnderlyingSourceBase extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory UnderlyingSourceBase._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('UnderlyingSourceBase.cancel')
  @DocsEditable()
  @Experimental() // untriaged
  Future cancel(Object reason) native;

  @DomName('UnderlyingSourceBase.pull')
  @DocsEditable()
  @Experimental() // untriaged
  Future pull() native;

  @DomName('UnderlyingSourceBase.start')
  @DocsEditable()
  @Experimental() // untriaged
  Future start(Object stream) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLUnknownElement')
@Native("HTMLUnknownElement")
class UnknownElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory UnknownElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  UnknownElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DomName('URL')
@Native("URL")
class Url extends Interceptor implements UrlUtils {
  static String createObjectUrl(blob_OR_source_OR_stream) => JS(
      'String',
      '(self.URL || self.webkitURL).createObjectURL(#)',
      blob_OR_source_OR_stream);

  static String createObjectUrlFromSource(MediaSource source) =>
      JS('String', '(self.URL || self.webkitURL).createObjectURL(#)', source);

  static String createObjectUrlFromStream(MediaStream stream) =>
      JS('String', '(self.URL || self.webkitURL).createObjectURL(#)', stream);

  static String createObjectUrlFromBlob(Blob blob) =>
      JS('String', '(self.URL || self.webkitURL).createObjectURL(#)', blob);

  static void revokeObjectUrl(String url) =>
      JS('void', '(self.URL || self.webkitURL).revokeObjectURL(#)', url);

  @DomName('URL.toString')
  @DocsEditable()
  String toString() => JS('String', 'String(#)', this);

  // To suppress missing implicit constructor warnings.
  factory Url._() {
    throw new UnsupportedError("Not supported");
  }

  // From URLUtils

  @DomName('URL.hash')
  @DocsEditable()
  @Experimental() // untriaged
  String hash;

  @DomName('URL.host')
  @DocsEditable()
  @Experimental() // untriaged
  String host;

  @DomName('URL.hostname')
  @DocsEditable()
  @Experimental() // untriaged
  String hostname;

  @DomName('URL.href')
  @DocsEditable()
  @Experimental() // untriaged
  String href;

  @DomName('URL.origin')
  @DocsEditable()
  @Experimental() // untriaged
  final String origin;

  @DomName('URL.password')
  @DocsEditable()
  @Experimental() // untriaged
  String password;

  @DomName('URL.pathname')
  @DocsEditable()
  @Experimental() // untriaged
  String pathname;

  @DomName('URL.port')
  @DocsEditable()
  @Experimental() // untriaged
  String port;

  @DomName('URL.protocol')
  @DocsEditable()
  @Experimental() // untriaged
  String protocol;

  @DomName('URL.search')
  @DocsEditable()
  @Experimental() // untriaged
  String search;

  @DomName('URL.username')
  @DocsEditable()
  @Experimental() // untriaged
  String username;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('URLSearchParams')
@Experimental() // untriaged
@Native("URLSearchParams")
class UrlSearchParams extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory UrlSearchParams._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('URLSearchParams.URLSearchParams')
  @DocsEditable()
  factory UrlSearchParams([Object init]) {
    if (init != null) {
      return UrlSearchParams._create_1(init);
    }
    return UrlSearchParams._create_2();
  }
  static UrlSearchParams _create_1(init) =>
      JS('UrlSearchParams', 'new URLSearchParams(#)', init);
  static UrlSearchParams _create_2() =>
      JS('UrlSearchParams', 'new URLSearchParams()');

  @DomName('URLSearchParams.append')
  @DocsEditable()
  @Experimental() // untriaged
  void append(String name, String value) native;

  @DomName('URLSearchParams.delete')
  @DocsEditable()
  @Experimental() // untriaged
  void delete(String name) native;

  @DomName('URLSearchParams.get')
  @DocsEditable()
  @Experimental() // untriaged
  String get(String name) native;

  @DomName('URLSearchParams.getAll')
  @DocsEditable()
  @Experimental() // untriaged
  List<String> getAll(String name) native;

  @DomName('URLSearchParams.has')
  @DocsEditable()
  @Experimental() // untriaged
  bool has(String name) native;

  @DomName('URLSearchParams.set')
  @DocsEditable()
  @Experimental() // untriaged
  void set(String name, String 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('URLUtils')
@Experimental() // untriaged
abstract class UrlUtils extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory UrlUtils._() {
    throw new UnsupportedError("Not supported");
  }

  String hash;

  String host;

  String hostname;

  String href;

  final String origin;

  String password;

  String pathname;

  String port;

  String protocol;

  String search;

  String username;

  String toString();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('URLUtilsReadOnly')
@Experimental() // untriaged
abstract class UrlUtilsReadOnly extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory UrlUtilsReadOnly._() {
    throw new UnsupportedError("Not supported");
  }

  final String hash;

  final String host;

  final String hostname;

  final String href;

  final String origin;

  final String pathname;

  final String port;

  final String protocol;

  final String search;

  String toString();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('VRDevice')
@Experimental() // untriaged
@Native("VRDevice")
class VRDevice extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VRDevice._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('VRDevice.deviceId')
  @DocsEditable()
  @Experimental() // untriaged
  final String deviceId;

  @DomName('VRDevice.deviceName')
  @DocsEditable()
  @Experimental() // untriaged
  final String deviceName;

  @DomName('VRDevice.hardwareUnitId')
  @DocsEditable()
  @Experimental() // untriaged
  final String hardwareUnitId;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('VREyeParameters')
@Experimental() // untriaged
@Native("VREyeParameters")
class VREyeParameters extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VREyeParameters._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('VREyeParameters.currentFieldOfView')
  @DocsEditable()
  @Experimental() // untriaged
  final VRFieldOfView currentFieldOfView;

  @DomName('VREyeParameters.eyeTranslation')
  @DocsEditable()
  @Experimental() // untriaged
  final DomPoint eyeTranslation;

  @DomName('VREyeParameters.maximumFieldOfView')
  @DocsEditable()
  @Experimental() // untriaged
  final VRFieldOfView maximumFieldOfView;

  @DomName('VREyeParameters.minimumFieldOfView')
  @DocsEditable()
  @Experimental() // untriaged
  final VRFieldOfView minimumFieldOfView;

  @DomName('VREyeParameters.recommendedFieldOfView')
  @DocsEditable()
  @Experimental() // untriaged
  final VRFieldOfView recommendedFieldOfView;

  @DomName('VREyeParameters.renderRect')
  @DocsEditable()
  @Experimental() // untriaged
  final _DomRect renderRect;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('VRFieldOfView')
@Experimental() // untriaged
@Native("VRFieldOfView")
class VRFieldOfView extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VRFieldOfView._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('VRFieldOfView.VRFieldOfView')
  @DocsEditable()
  factory VRFieldOfView([Map fov]) {
    if (fov != null) {
      var fov_1 = convertDartToNative_Dictionary(fov);
      return VRFieldOfView._create_1(fov_1);
    }
    return VRFieldOfView._create_2();
  }
  static VRFieldOfView _create_1(fov) =>
      JS('VRFieldOfView', 'new VRFieldOfView(#)', fov);
  static VRFieldOfView _create_2() =>
      JS('VRFieldOfView', 'new VRFieldOfView()');

  @DomName('VRFieldOfView.downDegrees')
  @DocsEditable()
  @Experimental() // untriaged
  num downDegrees;

  @DomName('VRFieldOfView.leftDegrees')
  @DocsEditable()
  @Experimental() // untriaged
  num leftDegrees;

  @DomName('VRFieldOfView.rightDegrees')
  @DocsEditable()
  @Experimental() // untriaged
  num rightDegrees;

  @DomName('VRFieldOfView.upDegrees')
  @DocsEditable()
  @Experimental() // untriaged
  num upDegrees;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('VRPositionState')
@Experimental() // untriaged
@Native("VRPositionState")
class VRPositionState extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VRPositionState._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('VRPositionState.angularAcceleration')
  @DocsEditable()
  @Experimental() // untriaged
  final DomPoint angularAcceleration;

  @DomName('VRPositionState.angularVelocity')
  @DocsEditable()
  @Experimental() // untriaged
  final DomPoint angularVelocity;

  @DomName('VRPositionState.linearAcceleration')
  @DocsEditable()
  @Experimental() // untriaged
  final DomPoint linearAcceleration;

  @DomName('VRPositionState.linearVelocity')
  @DocsEditable()
  @Experimental() // untriaged
  final DomPoint linearVelocity;

  @DomName('VRPositionState.orientation')
  @DocsEditable()
  @Experimental() // untriaged
  final DomPoint orientation;

  @DomName('VRPositionState.position')
  @DocsEditable()
  @Experimental() // untriaged
  final DomPoint position;

  @DomName('VRPositionState.timeStamp')
  @DocsEditable()
  @Experimental() // untriaged
  final double 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('ValidityState')
@Native("ValidityState")
class ValidityState extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory ValidityState._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('ValidityState.badInput')
  @DocsEditable()
  final bool badInput;

  @DomName('ValidityState.customError')
  @DocsEditable()
  final bool customError;

  @DomName('ValidityState.patternMismatch')
  @DocsEditable()
  final bool patternMismatch;

  @DomName('ValidityState.rangeOverflow')
  @DocsEditable()
  final bool rangeOverflow;

  @DomName('ValidityState.rangeUnderflow')
  @DocsEditable()
  final bool rangeUnderflow;

  @DomName('ValidityState.stepMismatch')
  @DocsEditable()
  final bool stepMismatch;

  @DomName('ValidityState.tooLong')
  @DocsEditable()
  final bool tooLong;

  @DomName('ValidityState.tooShort')
  @DocsEditable()
  @Experimental() // untriaged
  final bool tooShort;

  @DomName('ValidityState.typeMismatch')
  @DocsEditable()
  final bool typeMismatch;

  @DomName('ValidityState.valid')
  @DocsEditable()
  final bool valid;

  @DomName('ValidityState.valueMissing')
  @DocsEditable()
  final bool valueMissing;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DomName('HTMLVideoElement')
@Native("HTMLVideoElement")
class VideoElement extends MediaElement implements CanvasImageSource {
  // To suppress missing implicit constructor warnings.
  factory VideoElement._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('HTMLVideoElement.HTMLVideoElement')
  @DocsEditable()
  factory VideoElement() => JS(
      'returns:VideoElement;creates:VideoElement;new:true',
      '#.createElement(#)',
      document,
      "video");
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  VideoElement.created() : super.created();

  @DomName('HTMLVideoElement.height')
  @DocsEditable()
  int height;

  @DomName('HTMLVideoElement.poster')
  @DocsEditable()
  String poster;

  @DomName('HTMLVideoElement.videoHeight')
  @DocsEditable()
  final int videoHeight;

  @DomName('HTMLVideoElement.videoWidth')
  @DocsEditable()
  final int videoWidth;

  @JSName('webkitDecodedFrameCount')
  @DomName('HTMLVideoElement.webkitDecodedFrameCount')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  final int decodedFrameCount;

  @JSName('webkitDroppedFrameCount')
  @DomName('HTMLVideoElement.webkitDroppedFrameCount')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  final int droppedFrameCount;

  @DomName('HTMLVideoElement.width')
  @DocsEditable()
  int width;

  @DomName('HTMLVideoElement.getVideoPlaybackQuality')
  @DocsEditable()
  @Experimental() // untriaged
  VideoPlaybackQuality getVideoPlaybackQuality() native;

  @JSName('webkitEnterFullscreen')
  @DomName('HTMLVideoElement.webkitEnterFullscreen')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  void enterFullscreen() native;

  @JSName('webkitExitFullscreen')
  @DomName('HTMLVideoElement.webkitExitFullscreen')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#dom-document-exitfullscreen
  void exitFullscreen() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('VideoPlaybackQuality')
@Experimental() // untriaged
@Native("VideoPlaybackQuality")
class VideoPlaybackQuality extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VideoPlaybackQuality._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('VideoPlaybackQuality.corruptedVideoFrames')
  @DocsEditable()
  @Experimental() // untriaged
  final int corruptedVideoFrames;

  @DomName('VideoPlaybackQuality.creationTime')
  @DocsEditable()
  @Experimental() // untriaged
  final double creationTime;

  @DomName('VideoPlaybackQuality.droppedVideoFrames')
  @DocsEditable()
  @Experimental() // untriaged
  final int droppedVideoFrames;

  @DomName('VideoPlaybackQuality.totalVideoFrames')
  @DocsEditable()
  @Experimental() // untriaged
  final int totalVideoFrames;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('VideoTrack')
@Experimental() // untriaged
@Native("VideoTrack")
class VideoTrack extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VideoTrack._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('VideoTrack.id')
  @DocsEditable()
  @Experimental() // untriaged
  final String id;

  @DomName('VideoTrack.kind')
  @DocsEditable()
  @Experimental() // untriaged
  final String kind;

  @DomName('VideoTrack.label')
  @DocsEditable()
  @Experimental() // untriaged
  final String label;

  @DomName('VideoTrack.language')
  @DocsEditable()
  @Experimental() // untriaged
  final String language;

  @DomName('VideoTrack.selected')
  @DocsEditable()
  @Experimental() // untriaged
  bool selected;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('VideoTrackList')
@Experimental() // untriaged
@Native("VideoTrackList")
class VideoTrackList extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory VideoTrackList._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('VideoTrackList.changeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> changeEvent =
      const EventStreamProvider<Event>('change');

  @DomName('VideoTrackList.length')
  @DocsEditable()
  @Experimental() // untriaged
  final int length;

  @DomName('VideoTrackList.selectedIndex')
  @DocsEditable()
  @Experimental() // untriaged
  final int selectedIndex;

  @DomName('VideoTrackList.__getter__')
  @DocsEditable()
  @Experimental() // untriaged
  VideoTrack __getter__(int index) native;

  @DomName('VideoTrackList.getTrackById')
  @DocsEditable()
  @Experimental() // untriaged
  VideoTrack getTrackById(String id) native;

  @DomName('VideoTrackList.onchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onChange => changeEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('VoidCallback')
// http://www.w3.org/TR/file-system-api/#the-voidcallback-interface
@Experimental()
typedef void VoidCallback();
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('VTTCue')
@Experimental() // untriaged
@Native("VTTCue")
class VttCue extends TextTrackCue {
  // To suppress missing implicit constructor warnings.
  factory VttCue._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('VTTCue.VTTCue')
  @DocsEditable()
  factory VttCue(num startTime, num endTime, String text) {
    return VttCue._create_1(startTime, endTime, text);
  }
  static VttCue _create_1(startTime, endTime, text) =>
      JS('VttCue', 'new VTTCue(#,#,#)', startTime, endTime, text);

  @DomName('VTTCue.align')
  @DocsEditable()
  @Experimental() // untriaged
  String align;

  @DomName('VTTCue.line')
  @DocsEditable()
  @Experimental() // untriaged
  @Creates('Null')
  @Returns('num|String')
  Object line;

  @DomName('VTTCue.position')
  @DocsEditable()
  @Experimental() // untriaged
  @Creates('Null')
  @Returns('num|String')
  Object position;

  @DomName('VTTCue.regionId')
  @DocsEditable()
  @Experimental() // untriaged
  String regionId;

  @DomName('VTTCue.size')
  @DocsEditable()
  @Experimental() // untriaged
  num size;

  @DomName('VTTCue.snapToLines')
  @DocsEditable()
  @Experimental() // untriaged
  bool snapToLines;

  @DomName('VTTCue.text')
  @DocsEditable()
  @Experimental() // untriaged
  String text;

  @DomName('VTTCue.vertical')
  @DocsEditable()
  @Experimental() // untriaged
  String vertical;

  @JSName('getCueAsHTML')
  @DomName('VTTCue.getCueAsHTML')
  @DocsEditable()
  @Experimental() // untriaged
  DocumentFragment getCueAsHtml() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('VTTRegion')
@Experimental() // untriaged
@Native("VTTRegion")
class VttRegion extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VttRegion._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('VTTRegion.VTTRegion')
  @DocsEditable()
  factory VttRegion() {
    return VttRegion._create_1();
  }
  static VttRegion _create_1() => JS('VttRegion', 'new VTTRegion()');

  @DomName('VTTRegion.height')
  @DocsEditable()
  @Experimental() // untriaged
  int height;

  @DomName('VTTRegion.id')
  @DocsEditable()
  @Experimental() // untriaged
  String id;

  @DomName('VTTRegion.regionAnchorX')
  @DocsEditable()
  @Experimental() // untriaged
  num regionAnchorX;

  @DomName('VTTRegion.regionAnchorY')
  @DocsEditable()
  @Experimental() // untriaged
  num regionAnchorY;

  @DomName('VTTRegion.scroll')
  @DocsEditable()
  @Experimental() // untriaged
  String scroll;

  @DomName('VTTRegion.track')
  @DocsEditable()
  @Experimental() // untriaged
  final TextTrack track;

  @DomName('VTTRegion.viewportAnchorX')
  @DocsEditable()
  @Experimental() // untriaged
  num viewportAnchorX;

  @DomName('VTTRegion.viewportAnchorY')
  @DocsEditable()
  @Experimental() // untriaged
  num viewportAnchorY;

  @DomName('VTTRegion.width')
  @DocsEditable()
  @Experimental() // untriaged
  num width;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('VTTRegionList')
@Experimental() // untriaged
@Native("VTTRegionList")
class VttRegionList extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory VttRegionList._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('VTTRegionList.length')
  @DocsEditable()
  @Experimental() // untriaged
  final int length;

  @DomName('VTTRegionList.getRegionById')
  @DocsEditable()
  @Experimental() // untriaged
  VttRegion getRegionById(String id) native;

  @DomName('VTTRegionList.item')
  @DocsEditable()
  @Experimental() // untriaged
  VttRegion item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
/**
 * Use the WebSocket interface to connect to a WebSocket,
 * and to send and receive data on that WebSocket.
 *
 * To use a WebSocket in your web app, first create a WebSocket object,
 * passing the WebSocket URL as an argument to the constructor.
 *
 *     var webSocket = new WebSocket('ws://127.0.0.1:1337/ws');
 *
 * To send data on the WebSocket, use the [send] method.
 *
 *     if (webSocket != null && webSocket.readyState == WebSocket.OPEN) {
 *       webSocket.send(data);
 *     } else {
 *       print('WebSocket not connected, message $data not sent');
 *     }
 *
 * To receive data on the WebSocket, register a listener for message events.
 *
 *     webSocket.onMessage.listen((MessageEvent e) {
 *       receivedData(e.data);
 *     });
 *
 * The message event handler receives a [MessageEvent] object
 * as its sole argument.
 * You can also define open, close, and error handlers,
 * as specified by [WebSocketEvents].
 *
 * For more information, see the
 * [WebSockets](http://www.dartlang.org/docs/library-tour/#html-websockets)
 * section of the library tour and
 * [Introducing WebSockets](http://www.html5rocks.com/en/tutorials/websockets/basics/),
 * an HTML5Rocks.com tutorial.
 */
@DomName('WebSocket')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
@Native("WebSocket")
class WebSocket extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory WebSocket._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `close` events to event
   * handlers that are not necessarily instances of [WebSocket].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('WebSocket.closeEvent')
  @DocsEditable()
  static const EventStreamProvider<CloseEvent> closeEvent =
      const EventStreamProvider<CloseEvent>('close');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [WebSocket].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('WebSocket.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [WebSocket].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('WebSocket.messageEvent')
  @DocsEditable()
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  /**
   * Static factory designed to expose `open` events to event
   * handlers that are not necessarily instances of [WebSocket].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('WebSocket.openEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> openEvent =
      const EventStreamProvider<Event>('open');

  @DomName('WebSocket.WebSocket')
  @DocsEditable()
  factory WebSocket(String url, [Object protocols]) {
    if (protocols != null) {
      return WebSocket._create_1(url, protocols);
    }
    return WebSocket._create_2(url);
  }
  static WebSocket _create_1(url, protocols) =>
      JS('WebSocket', 'new WebSocket(#,#)', url, protocols);
  static WebSocket _create_2(url) => JS('WebSocket', 'new WebSocket(#)', url);

  /// 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 contrast, 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 contrast, 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 contrast, 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 contrast, 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 contrast, only accept data of the specified type.
   */
  @DomName('WebSocket.send')
  @DocsEditable()
  void sendTypedData(TypedData data) native;

  /// Stream of `close` events handled by this [WebSocket].
  @DomName('WebSocket.onclose')
  @DocsEditable()
  Stream<CloseEvent> get onClose => closeEvent.forTarget(this);

  /// Stream of `error` events handled by this [WebSocket].
  @DomName('WebSocket.onerror')
  @DocsEditable()
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `message` events handled by this [WebSocket].
  @DomName('WebSocket.onmessage')
  @DocsEditable()
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  /// Stream of `open` events handled by this [WebSocket].
  @DomName('WebSocket.onopen')
  @DocsEditable()
  Stream<Event> get onOpen => openEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DomName('WheelEvent')
@Native("WheelEvent")
class WheelEvent extends MouseEvent {
  factory WheelEvent(String type,
      {Window view,
      num deltaX: 0,
      num deltaY: 0,
      num deltaZ: 0,
      int deltaMode: 0,
      int detail: 0,
      int screenX: 0,
      int screenY: 0,
      int clientX: 0,
      int clientY: 0,
      int button: 0,
      bool canBubble: true,
      bool cancelable: true,
      bool ctrlKey: false,
      bool altKey: false,
      bool shiftKey: false,
      bool metaKey: false,
      EventTarget relatedTarget}) {
    var options = {
      'view': view,
      'deltaMode': deltaMode,
      'deltaX': deltaX,
      'deltaY': deltaY,
      'deltaZ': deltaZ,
      'detail': detail,
      'screenX': screenX,
      'screenY': screenY,
      'clientX': clientX,
      'clientY': clientY,
      'button': button,
      'bubbles': canBubble,
      'cancelable': cancelable,
      'ctrlKey': ctrlKey,
      'altKey': altKey,
      'shiftKey': shiftKey,
      'metaKey': metaKey,
      'relatedTarget': relatedTarget,
    };

    if (view == null) {
      view = window;
    }

    return JS('WheelEvent', 'new WheelEvent(#, #)', type,
        convertDartToNative_Dictionary(options));
  }

  @DomName('WheelEvent.WheelEvent')
  @DocsEditable()
  factory WheelEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return WheelEvent._create_1(type, eventInitDict_1);
    }
    return WheelEvent._create_2(type);
  }
  static WheelEvent _create_1(type, eventInitDict) =>
      JS('WheelEvent', 'new WheelEvent(#,#)', type, eventInitDict);
  static WheelEvent _create_2(type) =>
      JS('WheelEvent', 'new WheelEvent(#)', type);

  @DomName('WheelEvent.DOM_DELTA_LINE')
  @DocsEditable()
  static const int DOM_DELTA_LINE = 0x01;

  @DomName('WheelEvent.DOM_DELTA_PAGE')
  @DocsEditable()
  static const int DOM_DELTA_PAGE = 0x02;

  @DomName('WheelEvent.DOM_DELTA_PIXEL')
  @DocsEditable()
  static const int DOM_DELTA_PIXEL = 0x00;

  @JSName('deltaX')
  @DomName('WheelEvent.deltaX')
  @DocsEditable()
  final double _deltaX;

  @JSName('deltaY')
  @DomName('WheelEvent.deltaY')
  @DocsEditable()
  final double _deltaY;

  @DomName('WheelEvent.deltaZ')
  @DocsEditable()
  final double deltaZ;

  /**
   * The amount that is expected to scroll vertically, in units determined by
   * [deltaMode].
   *
   * See also:
   *
   * * [WheelEvent.deltaY](http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-WheelEvent-deltaY) from the W3C.
   */
  @DomName('WheelEvent.deltaY')
  num get deltaY {
    if (JS('bool', '#.deltaY !== undefined', this)) {
      // W3C WheelEvent
      return this._deltaY;
    }
    throw new UnsupportedError('deltaY is not supported');
  }

  /**
   * The amount that is expected to scroll horizontally, in units determined by
   * [deltaMode].
   *
   * See also:
   *
   * * [WheelEvent.deltaX](http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-WheelEvent-deltaX) from the W3C.
   */
  @DomName('WheelEvent.deltaX')
  num get deltaX {
    if (JS('bool', '#.deltaX !== undefined', this)) {
      // W3C WheelEvent
      return this._deltaX;
    }
    throw new UnsupportedError('deltaX is not supported');
  }

  @DomName('WheelEvent.deltaMode')
  int get deltaMode {
    if (JS('bool', '!!(#.deltaMode)', this)) {
      return JS('int', '#.deltaMode', this);
    }
    // If not available then we're poly-filling and doing pixel scroll.
    return 0;
  }

  num get _wheelDelta => JS('num', '#.wheelDelta', this);
  num get _wheelDeltaX => JS('num', '#.wheelDeltaX', this);
  num get _detail => JS('num', '#.detail', this);

  bool get _hasInitMouseScrollEvent =>
      JS('bool', '!!(#.initMouseScrollEvent)', this);

  @JSName('initMouseScrollEvent')
  void _initMouseScrollEvent(
      String type,
      bool canBubble,
      bool cancelable,
      Window view,
      int detail,
      int screenX,
      int screenY,
      int clientX,
      int clientY,
      bool ctrlKey,
      bool altKey,
      bool shiftKey,
      bool metaKey,
      int button,
      EventTarget relatedTarget,
      int axis) native;

  bool get _hasInitWheelEvent => JS('bool', '!!(#.initWheelEvent)', this);
  @JSName('initWheelEvent')
  void _initWheelEvent(
      String eventType,
      bool canBubble,
      bool cancelable,
      Window view,
      int detail,
      int screenX,
      int screenY,
      int clientX,
      int clientY,
      int button,
      EventTarget relatedTarget,
      String modifiersList,
      int deltaX,
      int deltaY,
      int deltaZ,
      int deltaMode) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
/**
 * Top-level container for the current browser tab or window.
 *
 * In a web browser, each window has a [Window] object, but within the context
 * of a script, this object represents only the current window.
 * Each other window, tab, and iframe has its own [Window] object.
 *
 * Each window contains a [Document] object, which contains all of the window's
 * content.
 *
 * Use the top-level `window` object to access the current window.
 * For example:
 *
 *     // Draw a scene when the window repaints.
 *     drawScene(num delta) {...}
 *     window.animationFrame.then(drawScene);.
 *
 *     // Write to the console.
 *     window.console.log('Jinkies!');
 *     window.console.error('Jeepers!');
 *
 * **Note:** This class represents only the current window, while [WindowBase]
 * is a representation of any window, including other tabs, windows, and frames.
 *
 * ## See also
 *
 * * [WindowBase]
 *
 * ## Other resources
 *
 * * [DOM Window](https://developer.mozilla.org/en-US/docs/DOM/window) from MDN.
 * * [Window](http://www.w3.org/TR/Window/) from the W3C.
 */
@DomName('Window')
@Native("Window,DOMWindow")
class Window extends EventTarget
    implements
        WindowEventHandlers,
        WindowBase,
        GlobalEventHandlers,
        _WindowTimers,
        WindowBase64 {
  /**
   * Returns a Future that completes just before the window is about to
   * repaint so the user can draw an animation frame.
   *
   * If you need to later cancel this animation, use [requestAnimationFrame]
   * instead.
   *
   * The [Future] completes to a timestamp that represents a floating
   * point value of the number of milliseconds that have elapsed since the page
   * started to load (which is also the timestamp at this call to
   * animationFrame).
   *
   * Note: The code that runs when the future completes should call
   * [animationFrame] again for the animation to continue.
   */
  Future<num> get animationFrame {
    var completer = new Completer<num>.sync();
    requestAnimationFrame((time) {
      completer.complete(time);
    });
    return completer.future;
  }

  /**
   * The newest document in this window.
   *
   * ## Other resources
   *
   * * [Loading web
   *   pages](https://html.spec.whatwg.org/multipage/browsers.html)
   *   from WHATWG.
   */
  Document get document => JS('Document', '#.document', this);

  WindowBase _open2(url, name) =>
      JS('Window|Null', '#.open(#,#)', this, url, name);

  WindowBase _open3(url, name, options) =>
      JS('Window|Null', '#.open(#,#,#)', this, url, name, options);

  /**
   * Opens a new window.
   *
   * ## Other resources
   *
   * * [Window.open](https://developer.mozilla.org/en-US/docs/Web/API/Window.open)
   *   from MDN.
   * * [Window open](http://docs.webplatform.org/wiki/dom/methods/open)
   *   from WebPlatform.org.
   */
  WindowBase open(String url, String name, [String options]) {
    if (options == null) {
      return _DOMWindowCrossFrame._createSafe(_open2(url, name));
    } else {
      return _DOMWindowCrossFrame._createSafe(_open3(url, name, options));
    }
  }

  // API level getter and setter for Location.
  // TODO: The cross domain safe wrapper can be inserted here.
  /**
   * The current location of this window.
   *
   *     Location currentLocation = window.location;
   *     print(currentLocation.href); // 'http://www.example.com:80/'
   */
  Location get location => _location;

  // TODO: consider forcing users to do: window.location.assign('string').
  /**
   * Sets the window's location, which causes the browser to navigate to the new
   * location. [value] may be a Location object or a String.
   */
  set location(value) {
    _location = value;
  }

  // Native getter and setter to access raw Location object.
  dynamic get _location => JS('Location|Null', '#.location', this);
  set _location(value) {
    JS('void', '#.location = #', this, value);
  }

  /**
   * Called to draw an animation frame and then request the window to repaint
   * after [callback] has finished (creating the animation).
   *
   * Use this method only if you need to later call [cancelAnimationFrame]. If
   * not, the preferred Dart idiom is to set animation frames by calling
   * [animationFrame], which returns a Future.
   *
   * Returns a non-zero valued integer to represent the request id for this
   * request. This value only needs to be saved if you intend to call
   * [cancelAnimationFrame] so you can specify the particular animation to
   * cancel.
   *
   * Note: The supplied [callback] needs to call [requestAnimationFrame] again
   * for the animation to continue.
   */
  @DomName('Window.requestAnimationFrame')
  int requestAnimationFrame(FrameRequestCallback callback) {
    _ensureRequestAnimationFrame();
    return _requestAnimationFrame(_wrapZone/*<num, dynamic>*/(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(FrameRequestCallback callback) native;

  @JSName('cancelAnimationFrame')
  void _cancelAnimationFrame(int id) native;

  _ensureRequestAnimationFrame() {
    if (JS('bool', '!!(#.requestAnimationFrame && #.cancelAnimationFrame)',
        this, this)) return;

    JS(
        'void',
        r"""
  (function($this) {
   var vendors = ['ms', 'moz', 'webkit', 'o'];
   for (var i = 0; i < vendors.length && !$this.requestAnimationFrame; ++i) {
     $this.requestAnimationFrame = $this[vendors[i] + 'RequestAnimationFrame'];
     $this.cancelAnimationFrame =
         $this[vendors[i]+'CancelAnimationFrame'] ||
         $this[vendors[i]+'CancelRequestAnimationFrame'];
   }
   if ($this.requestAnimationFrame && $this.cancelAnimationFrame) return;
   $this.requestAnimationFrame = function(callback) {
      return window.setTimeout(function() {
        callback(Date.now());
      }, 16 /* 16ms ~= 60fps */);
   };
   $this.cancelAnimationFrame = function(id) { clearTimeout(id); }
  })(#)""",
        this);
  }

  /**
   * Gets an instance of the Indexed DB factory to being using Indexed DB.
   *
   * Use [indexed_db.IdbFactory.supported] to check if Indexed DB is supported on the
   * current platform.
   */
  @SupportedBrowser(SupportedBrowser.CHROME, '23.0')
  @SupportedBrowser(SupportedBrowser.FIREFOX, '15.0')
  @SupportedBrowser(SupportedBrowser.IE, '10.0')
  @Experimental()
  IdbFactory get indexedDB => JS(
      'IdbFactory|Null', // If not supported, returns null.
      '#.indexedDB || #.webkitIndexedDB || #.mozIndexedDB',
      this,
      this,
      this);

  /// The debugging console for this window.
  @DomName('Window.console')
  Console get console => Console._safeConsole;

  /**
   * Access a sandboxed file system of the specified `size`. If `persistent` is
   * true, the application will request permission from the user to create
   * lasting storage. This storage cannot be freed without the user's
   * permission. Returns a [Future] whose value stores a reference to the
   * sandboxed file system for use. Because the file system is sandboxed,
   * applications cannot access file systems created in other web pages.
   */
  Future<FileSystem> requestFileSystem(int size, {bool persistent: false}) {
    return _requestFileSystem(persistent ? 1 : 0, size);
  }

  /**
   * convertPointFromNodeToPage and convertPointFromPageToNode are removed.
   * see http://dev.w3.org/csswg/cssom-view/#geometry
   */
  static bool get supportsPointConversions => DomPoint.supported;
  // To suppress missing implicit constructor warnings.
  factory Window._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `contentloaded` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.DOMContentLoadedEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> contentLoadedEvent =
      const EventStreamProvider<Event>('DOMContentLoaded');

  /**
   * Static factory designed to expose `devicemotion` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.devicemotionEvent')
  @DocsEditable()
  // http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
  @Experimental()
  static const EventStreamProvider<DeviceMotionEvent> deviceMotionEvent =
      const EventStreamProvider<DeviceMotionEvent>('devicemotion');

  /**
   * Static factory designed to expose `deviceorientation` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.deviceorientationEvent')
  @DocsEditable()
  // http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
  @Experimental()
  static const EventStreamProvider<DeviceOrientationEvent>
      deviceOrientationEvent =
      const EventStreamProvider<DeviceOrientationEvent>('deviceorientation');

  /**
   * Static factory designed to expose `hashchange` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.hashchangeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> hashChangeEvent =
      const EventStreamProvider<Event>('hashchange');

  @DomName('Window.loadstartEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> loadStartEvent =
      const EventStreamProvider<Event>('loadstart');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.messageEvent')
  @DocsEditable()
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  /**
   * Static factory designed to expose `offline` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.offlineEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> offlineEvent =
      const EventStreamProvider<Event>('offline');

  /**
   * Static factory designed to expose `online` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.onlineEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> onlineEvent =
      const EventStreamProvider<Event>('online');

  /**
   * Static factory designed to expose `pagehide` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.pagehideEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> pageHideEvent =
      const EventStreamProvider<Event>('pagehide');

  /**
   * Static factory designed to expose `pageshow` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.pageshowEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> pageShowEvent =
      const EventStreamProvider<Event>('pageshow');

  /**
   * Static factory designed to expose `popstate` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.popstateEvent')
  @DocsEditable()
  static const EventStreamProvider<PopStateEvent> popStateEvent =
      const EventStreamProvider<PopStateEvent>('popstate');

  @DomName('Window.progressEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> progressEvent =
      const EventStreamProvider<Event>('progress');

  /**
   * Static factory designed to expose `storage` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.storageEvent')
  @DocsEditable()
  static const EventStreamProvider<StorageEvent> storageEvent =
      const EventStreamProvider<StorageEvent>('storage');

  /**
   * Static factory designed to expose `unload` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.unloadEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> unloadEvent =
      const EventStreamProvider<Event>('unload');

  /**
   * Static factory designed to expose `animationend` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.webkitAnimationEndEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  static const EventStreamProvider<AnimationEvent> animationEndEvent =
      const EventStreamProvider<AnimationEvent>('webkitAnimationEnd');

  /**
   * Static factory designed to expose `animationiteration` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.webkitAnimationIterationEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  static const EventStreamProvider<AnimationEvent> animationIterationEvent =
      const EventStreamProvider<AnimationEvent>('webkitAnimationIteration');

  /**
   * Static factory designed to expose `animationstart` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.webkitAnimationStartEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  static const EventStreamProvider<AnimationEvent> animationStartEvent =
      const EventStreamProvider<AnimationEvent>('webkitAnimationStart');

  /**
   * Indicates that file system data cannot be cleared unless given user
   * permission.
   *
   * ## Other resources
   *
   * * [Exploring the FileSystem
   *   APIs](http://www.html5rocks.com/en/tutorials/file/filesystem/)
   *   from HTML5Rocks.
   * * [File API](http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem)
   *   from W3C.
   */
  @DomName('Window.PERSISTENT')
  @DocsEditable()
  // http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem
  @Experimental()
  static const int PERSISTENT = 1;

  /**
   * Indicates that file system data can be cleared at any time.
   *
   * ## Other resources
   *
   * * [Exploring the FileSystem
   *   APIs](http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.
   * * [File API](http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem)
   *   from W3C.
   */
  @DomName('Window.TEMPORARY')
  @DocsEditable()
  // http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem
  @Experimental()
  static const int TEMPORARY = 0;

  /**
   * 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](https://html.spec.whatwg.org/multipage/browsers.html#application-cache-api)
   *   from WHATWG.
   */
  @DomName('Window.applicationCache')
  @DocsEditable()
  final ApplicationCache applicationCache;

  @DomName('Window.caches')
  @DocsEditable()
  @Experimental() // untriaged
  final CacheStorage caches;

  @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](https://html.spec.whatwg.org/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;

  @DomName('Window.isSecureContext')
  @DocsEditable()
  @Experimental() // untriaged
  final bool isSecureContext;

  /**
   * 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](https://html.spec.whatwg.org/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](https://html.spec.whatwg.org/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](https://html.spec.whatwg.org/multipage/webappapis.html#the-navigator-object)
   *   from WHATWG.
   */
  @DomName('Window.navigator')
  @DocsEditable()
  final Navigator navigator;

  /**
   * Whether objects are drawn offscreen before being displayed.
   *
   * ## Other resources
   *
   * * [offscreenBuffering](http://docs.webplatform.org/wiki/dom/properties/offscreenBuffering)
   *   from WebPlatform.org.
   */
  @DomName('Window.offscreenBuffering')
  @DocsEditable()
  @Experimental() // non-standard
  final bool offscreenBuffering;

  @DomName('Window.opener')
  @DocsEditable()
  WindowBase get opener => _convertNativeToDart_Window(this._get_opener);
  @JSName('opener')
  @DomName('Window.opener')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_opener;

  set opener(Window value) {
    JS("void", "#.opener = #", this, value);
  }

  @DomName('Window.orientation')
  @DocsEditable()
  @Experimental() // untriaged
  final int orientation;

  /**
   * The height of this window including all user interface elements.
   *
   * ## Other resources
   *
   * * [outerHeight](http://docs.webplatform.org/wiki/css/cssom/properties/outerHeight)
   *   from WebPlatform.org.
   */
  @DomName('Window.outerHeight')
  @DocsEditable()
  final int outerHeight;

  /**
   * The width of the window including all user interface elements.
   *
   * ## Other resources
   *
   * * [outerWidth](http://docs.webplatform.org/wiki/css/cssom/properties/outerWidth)
   *   from WebPlatform.org.
   */
  @DomName('Window.outerWidth')
  @DocsEditable()
  final int outerWidth;

  @JSName('pageXOffset')
  /**
   * The distance this window has been scrolled horizontally.
   *
   * This attribute is an alias for [scrollX].
   *
   * ## Other resources
   *
   * * [The Screen interface
   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
   * * [scrollX and
   *   pageXOffset](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX)
   *   from MDN.
   */
  @DomName('Window.pageXOffset')
  @DocsEditable()
  final double _pageXOffset;

  @JSName('pageYOffset')
  /**
   * The distance this window has been scrolled vertically.
   *
   * This attribute is an alias for [scrollY].
   *
   * ## Other resources
   *
   * * [The Screen interface
   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
   * * [scrollY and
   *   pageYOffset](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY)
   *   from MDN.
   */
  @DomName('Window.pageYOffset')
  @DocsEditable()
  final double _pageYOffset;

  @DomName('Window.parent')
  @DocsEditable()
  WindowBase get parent => _convertNativeToDart_Window(this._get_parent);
  @JSName('parent')
  @DomName('Window.parent')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_parent;

  /**
   * Timing and navigation data for this window.
   *
   * ## Other resources
   *
   * * [Measuring page load speed with navigation
   *   timeing](http://www.html5rocks.com/en/tutorials/webperformance/basics/)
   *   from HTML5Rocks.
   * * [Navigation timing
   *   specification](http://www.w3.org/TR/navigation-timing/) from W3C.
   */
  @DomName('Window.performance')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE)
  final Performance performance;

  @DomName('Window.renderWorklet')
  @DocsEditable()
  @Experimental() // untriaged
  final _Worklet renderWorklet;

  /**
   * 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](https://html.spec.whatwg.org/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](https://html.spec.whatwg.org/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/)
   *   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](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
   *   from WHATWG.
   */
  @DomName('Window.toolbar')
  @DocsEditable()
  final BarProp toolbar;

  @DomName('Window.top')
  @DocsEditable()
  WindowBase get top => _convertNativeToDart_Window(this._get_top);
  @JSName('top')
  @DomName('Window.top')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_top;

  /**
   * The current window.
   *
   * ## Other resources
   *
   * * [Window.window](https://developer.mozilla.org/en-US/docs/Web/API/Window.window)
   *   from MDN.
   */
  @DomName('Window.window')
  @DocsEditable()
  WindowBase get window => _convertNativeToDart_Window(this._get_window);
  @JSName('window')
  /**
   * The current window.
   *
   * ## Other resources
   *
   * * [Window.window](https://developer.mozilla.org/en-US/docs/Web/API/Window.window)
   *   from MDN.
   */
  @DomName('Window.window')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  final dynamic _get_window;

  @DomName('Window.__getter__')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  WindowBase __getter__(index_OR_name) {
    if ((index_OR_name is int)) {
      return _convertNativeToDart_Window(__getter___1(index_OR_name));
    }
    if ((index_OR_name is String)) {
      return _convertNativeToDart_Window(__getter___2(index_OR_name));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('__getter__')
  @DomName('Window.__getter__')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  __getter___1(int index) native;
  @JSName('__getter__')
  @DomName('Window.__getter__')
  @DocsEditable()
  @Creates('Window|=Object')
  @Returns('Window|=Object')
  __getter___2(String name) native;

  /**
   * Displays a modal alert to the user.
   *
   * ## Other resources
   *
   * * [User prompts](https://html.spec.whatwg.org/multipage/webappapis.html#user-prompts)
   *   from WHATWG.
   */
  @DomName('Window.alert')
  @DocsEditable()
  void alert([String message]) native;

  @DomName('Window.cancelIdleCallback')
  @DocsEditable()
  @Experimental() // untriaged
  void cancelIdleCallback(int handle) native;

  @DomName('Window.close')
  @DocsEditable()
  void close() native;

  /**
   * Displays a modal OK/Cancel prompt to the user.
   *
   * ## Other resources
   *
   * * [User prompts](https://html.spec.whatwg.org/multipage/webappapis.html#user-prompts)
   *   from WHATWG.
   */
  @DomName('Window.confirm')
  @DocsEditable()
  bool confirm([String message]) native;

  @DomName('Window.fetch')
  @DocsEditable()
  @Experimental() // untriaged
  Future fetch(/*RequestInfo*/ input, [Map init]) {
    if (init != null) {
      var init_1 = convertDartToNative_Dictionary(init);
      return _fetch_1(input, init_1);
    }
    return _fetch_2(input);
  }

  @JSName('fetch')
  @DomName('Window.fetch')
  @DocsEditable()
  @Experimental() // untriaged
  Future _fetch_1(input, init) native;
  @JSName('fetch')
  @DomName('Window.fetch')
  @DocsEditable()
  @Experimental() // untriaged
  Future _fetch_2(input) 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 elt, String pseudoElt) native;

  @JSName('getMatchedCSSRules')
  /**
   * Returns all CSS rules that apply to the element's pseudo-element.
   */
  @DomName('Window.getMatchedCSSRules')
  @DocsEditable()
  @Experimental() // non-standard
  @Returns('_CssRuleList|Null')
  @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(int x, int y) native;

  @JSName('moveTo')
  @DomName('Window.moveTo')
  @DocsEditable()
  void _moveTo(int x, int 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(/*any*/ message, String targetOrigin,
      [List<MessagePort> transfer]) {
    if (transfer != null) {
      var message_1 = convertDartToNative_SerializedScriptValue(message);
      _postMessage_1(message_1, targetOrigin, transfer);
      return;
    }
    var message_1 = convertDartToNative_SerializedScriptValue(message);
    _postMessage_2(message_1, targetOrigin);
    return;
  }

  @JSName('postMessage')
  @DomName('Window.postMessage')
  @DocsEditable()
  void _postMessage_1(message, targetOrigin, List<MessagePort> transfer) native;
  @JSName('postMessage')
  @DomName('Window.postMessage')
  @DocsEditable()
  void _postMessage_2(message, targetOrigin) native;

  /**
   * Opens the print dialog for this window.
   *
   * ## Other resources
   *
   * * [Window.print](https://developer.mozilla.org/en-US/docs/Web/API/Window.print)
   *   from MDN.
   */
  @DomName('Window.print')
  @DocsEditable()
  void print() native;

  @DomName('Window.requestIdleCallback')
  @DocsEditable()
  @Experimental() // untriaged
  int requestIdleCallback(IdleRequestCallback callback, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _requestIdleCallback_1(callback, options_1);
    }
    return _requestIdleCallback_2(callback);
  }

  @JSName('requestIdleCallback')
  @DomName('Window.requestIdleCallback')
  @DocsEditable()
  @Experimental() // untriaged
  int _requestIdleCallback_1(IdleRequestCallback callback, options) native;
  @JSName('requestIdleCallback')
  @DomName('Window.requestIdleCallback')
  @DocsEditable()
  @Experimental() // untriaged
  int _requestIdleCallback_2(IdleRequestCallback callback) 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(int x, int 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(int x, int y) 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([options_OR_x, y, Map scrollOptions]) {
    if (options_OR_x == null && y == null && scrollOptions == null) {
      _scroll_1();
      return;
    }
    if ((options_OR_x is Map) && y == null && scrollOptions == null) {
      var options_1 = convertDartToNative_Dictionary(options_OR_x);
      _scroll_2(options_1);
      return;
    }
    if ((y is num) && (options_OR_x is num) && scrollOptions == null) {
      _scroll_3(options_OR_x, y);
      return;
    }
    if ((y is int) && (options_OR_x is int) && scrollOptions == null) {
      _scroll_4(options_OR_x, y);
      return;
    }
    if (scrollOptions != null && (y is int) && (options_OR_x is int)) {
      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
      _scroll_5(options_OR_x, y, scrollOptions_1);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('scroll')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scrollTo].
   *
   * ## Other resources
   *
   * * [Window scroll](http://docs.webplatform.org/wiki/dom/methods/scroll)
   *   from WebPlatform.org.
   */
  @DomName('Window.scroll')
  @DocsEditable()
  void _scroll_1() 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(options) native;
  @JSName('scroll')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scrollTo].
   *
   * ## Other resources
   *
   * * [Window scroll](http://docs.webplatform.org/wiki/dom/methods/scroll)
   *   from WebPlatform.org.
   */
  @DomName('Window.scroll')
  @DocsEditable()
  void _scroll_3(num x, num y) native;
  @JSName('scroll')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scrollTo].
   *
   * ## Other resources
   *
   * * [Window scroll](http://docs.webplatform.org/wiki/dom/methods/scroll)
   *   from WebPlatform.org.
   */
  @DomName('Window.scroll')
  @DocsEditable()
  void _scroll_4(int x, int y) native;
  @JSName('scroll')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scrollTo].
   *
   * ## Other resources
   *
   * * [Window scroll](http://docs.webplatform.org/wiki/dom/methods/scroll)
   *   from WebPlatform.org.
   */
  @DomName('Window.scroll')
  @DocsEditable()
  void _scroll_5(int x, int y, scrollOptions) native;

  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window scrollBy](http://docs.webplatform.org/wiki/dom/methods/scrollBy)
   *   from WebPlatform.org.
   */
  @DomName('Window.scrollBy')
  @DocsEditable()
  void scrollBy([options_OR_x, y, Map scrollOptions]) {
    if (options_OR_x == null && y == null && scrollOptions == null) {
      _scrollBy_1();
      return;
    }
    if ((options_OR_x is Map) && y == null && scrollOptions == null) {
      var options_1 = convertDartToNative_Dictionary(options_OR_x);
      _scrollBy_2(options_1);
      return;
    }
    if ((y is num) && (options_OR_x is num) && scrollOptions == null) {
      _scrollBy_3(options_OR_x, y);
      return;
    }
    if ((y is int) && (options_OR_x is int) && scrollOptions == null) {
      _scrollBy_4(options_OR_x, y);
      return;
    }
    if (scrollOptions != null && (y is int) && (options_OR_x is int)) {
      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
      _scrollBy_5(options_OR_x, y, scrollOptions_1);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('scrollBy')
  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window scrollBy](http://docs.webplatform.org/wiki/dom/methods/scrollBy)
   *   from WebPlatform.org.
   */
  @DomName('Window.scrollBy')
  @DocsEditable()
  void _scrollBy_1() 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(options) native;
  @JSName('scrollBy')
  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window scrollBy](http://docs.webplatform.org/wiki/dom/methods/scrollBy)
   *   from WebPlatform.org.
   */
  @DomName('Window.scrollBy')
  @DocsEditable()
  void _scrollBy_3(num x, num y) native;
  @JSName('scrollBy')
  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window scrollBy](http://docs.webplatform.org/wiki/dom/methods/scrollBy)
   *   from WebPlatform.org.
   */
  @DomName('Window.scrollBy')
  @DocsEditable()
  void _scrollBy_4(int x, int y) native;
  @JSName('scrollBy')
  /**
   * Scrolls the page horizontally and vertically by an offset.
   *
   * ## Other resources
   *
   * * [Window scrollBy](http://docs.webplatform.org/wiki/dom/methods/scrollBy)
   *   from WebPlatform.org.
   */
  @DomName('Window.scrollBy')
  @DocsEditable()
  void _scrollBy_5(int x, int y, scrollOptions) native;

  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scroll].
   *
   * ## Other resources
   *
   * * [Window scrollTo](http://docs.webplatform.org/wiki/dom/methods/scrollTo)
   *   from WebPlatform.org.
   */
  @DomName('Window.scrollTo')
  @DocsEditable()
  void scrollTo([options_OR_x, y, Map scrollOptions]) {
    if (options_OR_x == null && y == null && scrollOptions == null) {
      _scrollTo_1();
      return;
    }
    if ((options_OR_x is Map) && y == null && scrollOptions == null) {
      var options_1 = convertDartToNative_Dictionary(options_OR_x);
      _scrollTo_2(options_1);
      return;
    }
    if ((y is num) && (options_OR_x is num) && scrollOptions == null) {
      _scrollTo_3(options_OR_x, y);
      return;
    }
    if ((y is int) && (options_OR_x is int) && scrollOptions == null) {
      _scrollTo_4(options_OR_x, y);
      return;
    }
    if (scrollOptions != null && (y is int) && (options_OR_x is int)) {
      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
      _scrollTo_5(options_OR_x, y, scrollOptions_1);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @JSName('scrollTo')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scroll].
   *
   * ## Other resources
   *
   * * [Window scrollTo](http://docs.webplatform.org/wiki/dom/methods/scrollTo)
   *   from WebPlatform.org.
   */
  @DomName('Window.scrollTo')
  @DocsEditable()
  void _scrollTo_1() 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(options) native;
  @JSName('scrollTo')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scroll].
   *
   * ## Other resources
   *
   * * [Window scrollTo](http://docs.webplatform.org/wiki/dom/methods/scrollTo)
   *   from WebPlatform.org.
   */
  @DomName('Window.scrollTo')
  @DocsEditable()
  void _scrollTo_3(num x, num y) native;
  @JSName('scrollTo')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scroll].
   *
   * ## Other resources
   *
   * * [Window scrollTo](http://docs.webplatform.org/wiki/dom/methods/scrollTo)
   *   from WebPlatform.org.
   */
  @DomName('Window.scrollTo')
  @DocsEditable()
  void _scrollTo_4(int x, int y) native;
  @JSName('scrollTo')
  /**
   * Scrolls the page horizontally and vertically to a specific point.
   *
   * This method is identical to [scroll].
   *
   * ## Other resources
   *
   * * [Window scrollTo](http://docs.webplatform.org/wiki/dom/methods/scrollTo)
   *   from WebPlatform.org.
   */
  @DomName('Window.scrollTo')
  @DocsEditable()
  void _scrollTo_5(int x, int y, scrollOptions) native;

  /**
   * Stops the window from loading.
   *
   * ## Other resources
   *
   * * [The Window
   *   object](http://www.w3.org/html/wg/drafts/html/master/browsers.html#the-window-object)
   *   from W3C.
   */
  @DomName('Window.stop')
  @DocsEditable()
  void stop() native;

  @JSName('webkitRequestFileSystem')
  @DomName('Window.webkitRequestFileSystem')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @Experimental()
  // http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem
  void __requestFileSystem(
      int type, int size, _FileSystemCallback successCallback,
      [_ErrorCallback errorCallback]) native;

  @JSName('webkitRequestFileSystem')
  @DomName('Window.webkitRequestFileSystem')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @Experimental()
  // http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem
  Future<FileSystem> _requestFileSystem(int type, int size) {
    var completer = new Completer<FileSystem>();
    __requestFileSystem(type, size, (value) {
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  @JSName('webkitResolveLocalFileSystemURL')
  /**
   * Asynchronously retrieves a local filesystem entry.
   *
   * ## Other resources
   *
   * * [Obtaining access to file system entry
   *   points](http://www.w3.org/TR/file-system-api/#obtaining-access-to-file-system-entry-points)
   * from W3C.
   */
  @DomName('Window.webkitResolveLocalFileSystemURL')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @Experimental()
  // http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem
  void _resolveLocalFileSystemUrl(String url, _EntryCallback successCallback,
      [_ErrorCallback errorCallback]) native;

  @JSName('webkitResolveLocalFileSystemURL')
  /**
   * Asynchronously retrieves a local filesystem entry.
   *
   * ## Other resources
   *
   * * [Obtaining access to file system entry
   *   points](http://www.w3.org/TR/file-system-api/#obtaining-access-to-file-system-entry-points)
   * from W3C.
   */
  @DomName('Window.webkitResolveLocalFileSystemURL')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @Experimental()
  // http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem
  Future<Entry> resolveLocalFileSystemUrl(String url) {
    var completer = new Completer<Entry>();
    _resolveLocalFileSystemUrl(url, (value) {
      completer.complete(value);
    }, (error) {
      completer.completeError(error);
    });
    return completer.future;
  }

  // From WindowBase64

  @DomName('Window.atob')
  @DocsEditable()
  String atob(String atob) native;

  @DomName('Window.btoa')
  @DocsEditable()
  String btoa(String btoa) native;

  // From WindowTimers

  @JSName('setInterval')
  @DomName('Window.setInterval')
  @DocsEditable()
  int _setInterval_String(String handler, [int timeout, Object arguments])
      native;

  @JSName('setTimeout')
  @DomName('Window.setTimeout')
  @DocsEditable()
  int _setTimeout_String(String handler, [int timeout, Object arguments])
      native;

  @JSName('clearInterval')
  @DomName('Window.clearInterval')
  @DocsEditable()
  void _clearInterval([int handle]) native;

  @JSName('clearTimeout')
  @DomName('Window.clearTimeout')
  @DocsEditable()
  void _clearTimeout([int handle]) native;

  @JSName('setInterval')
  @DomName('Window.setInterval')
  @DocsEditable()
  int _setInterval(Object handler, [int timeout]) native;

  @JSName('setTimeout')
  @DomName('Window.setTimeout')
  @DocsEditable()
  int _setTimeout(Object handler, [int timeout]) native;

  /// Stream of `contentloaded` events handled by this [Window].
  @DomName('Window.onDOMContentLoaded')
  @DocsEditable()
  Stream<Event> get onContentLoaded => contentLoadedEvent.forTarget(this);

  /// Stream of `abort` events handled by this [Window].
  @DomName('Window.onabort')
  @DocsEditable()
  Stream<Event> get onAbort => Element.abortEvent.forTarget(this);

  /// Stream of `blur` events handled by this [Window].
  @DomName('Window.onblur')
  @DocsEditable()
  Stream<Event> get onBlur => Element.blurEvent.forTarget(this);

  @DomName('Window.oncanplay')
  @DocsEditable()
  Stream<Event> get onCanPlay => Element.canPlayEvent.forTarget(this);

  @DomName('Window.oncanplaythrough')
  @DocsEditable()
  Stream<Event> get onCanPlayThrough =>
      Element.canPlayThroughEvent.forTarget(this);

  /// Stream of `change` events handled by this [Window].
  @DomName('Window.onchange')
  @DocsEditable()
  Stream<Event> get onChange => Element.changeEvent.forTarget(this);

  /// Stream of `click` events handled by this [Window].
  @DomName('Window.onclick')
  @DocsEditable()
  Stream<MouseEvent> get onClick => Element.clickEvent.forTarget(this);

  /// Stream of `contextmenu` events handled by this [Window].
  @DomName('Window.oncontextmenu')
  @DocsEditable()
  Stream<MouseEvent> get onContextMenu =>
      Element.contextMenuEvent.forTarget(this);

  /// Stream of `doubleclick` events handled by this [Window].
  @DomName('Window.ondblclick')
  @DocsEditable()
  Stream<Event> get onDoubleClick => Element.doubleClickEvent.forTarget(this);

  /// Stream of `devicemotion` events handled by this [Window].
  @DomName('Window.ondevicemotion')
  @DocsEditable()
  // http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
  @Experimental()
  Stream<DeviceMotionEvent> get onDeviceMotion =>
      deviceMotionEvent.forTarget(this);

  /// Stream of `deviceorientation` events handled by this [Window].
  @DomName('Window.ondeviceorientation')
  @DocsEditable()
  // http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
  @Experimental()
  Stream<DeviceOrientationEvent> get onDeviceOrientation =>
      deviceOrientationEvent.forTarget(this);

  /// Stream of `drag` events handled by this [Window].
  @DomName('Window.ondrag')
  @DocsEditable()
  Stream<MouseEvent> get onDrag => Element.dragEvent.forTarget(this);

  /// Stream of `dragend` events handled by this [Window].
  @DomName('Window.ondragend')
  @DocsEditable()
  Stream<MouseEvent> get onDragEnd => Element.dragEndEvent.forTarget(this);

  /// Stream of `dragenter` events handled by this [Window].
  @DomName('Window.ondragenter')
  @DocsEditable()
  Stream<MouseEvent> get onDragEnter => Element.dragEnterEvent.forTarget(this);

  /// Stream of `dragleave` events handled by this [Window].
  @DomName('Window.ondragleave')
  @DocsEditable()
  Stream<MouseEvent> get onDragLeave => Element.dragLeaveEvent.forTarget(this);

  /// Stream of `dragover` events handled by this [Window].
  @DomName('Window.ondragover')
  @DocsEditable()
  Stream<MouseEvent> get onDragOver => Element.dragOverEvent.forTarget(this);

  /// Stream of `dragstart` events handled by this [Window].
  @DomName('Window.ondragstart')
  @DocsEditable()
  Stream<MouseEvent> get onDragStart => Element.dragStartEvent.forTarget(this);

  /// Stream of `drop` events handled by this [Window].
  @DomName('Window.ondrop')
  @DocsEditable()
  Stream<MouseEvent> get onDrop => Element.dropEvent.forTarget(this);

  @DomName('Window.ondurationchange')
  @DocsEditable()
  Stream<Event> get onDurationChange =>
      Element.durationChangeEvent.forTarget(this);

  @DomName('Window.onemptied')
  @DocsEditable()
  Stream<Event> get onEmptied => Element.emptiedEvent.forTarget(this);

  @DomName('Window.onended')
  @DocsEditable()
  Stream<Event> get onEnded => Element.endedEvent.forTarget(this);

  /// Stream of `error` events handled by this [Window].
  @DomName('Window.onerror')
  @DocsEditable()
  Stream<Event> get onError => Element.errorEvent.forTarget(this);

  /// Stream of `focus` events handled by this [Window].
  @DomName('Window.onfocus')
  @DocsEditable()
  Stream<Event> get onFocus => Element.focusEvent.forTarget(this);

  /// Stream of `hashchange` events handled by this [Window].
  @DomName('Window.onhashchange')
  @DocsEditable()
  Stream<Event> get onHashChange => hashChangeEvent.forTarget(this);

  /// Stream of `input` events handled by this [Window].
  @DomName('Window.oninput')
  @DocsEditable()
  Stream<Event> get onInput => Element.inputEvent.forTarget(this);

  /// Stream of `invalid` events handled by this [Window].
  @DomName('Window.oninvalid')
  @DocsEditable()
  Stream<Event> get onInvalid => Element.invalidEvent.forTarget(this);

  /// Stream of `keydown` events handled by this [Window].
  @DomName('Window.onkeydown')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyDown => Element.keyDownEvent.forTarget(this);

  /// Stream of `keypress` events handled by this [Window].
  @DomName('Window.onkeypress')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyPress => Element.keyPressEvent.forTarget(this);

  /// Stream of `keyup` events handled by this [Window].
  @DomName('Window.onkeyup')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyUp => Element.keyUpEvent.forTarget(this);

  /// Stream of `load` events handled by this [Window].
  @DomName('Window.onload')
  @DocsEditable()
  Stream<Event> get onLoad => Element.loadEvent.forTarget(this);

  @DomName('Window.onloadeddata')
  @DocsEditable()
  Stream<Event> get onLoadedData => Element.loadedDataEvent.forTarget(this);

  @DomName('Window.onloadedmetadata')
  @DocsEditable()
  Stream<Event> get onLoadedMetadata =>
      Element.loadedMetadataEvent.forTarget(this);

  @DomName('Window.onloadstart')
  @DocsEditable()
  Stream<Event> get onLoadStart => loadStartEvent.forTarget(this);

  /// Stream of `message` events handled by this [Window].
  @DomName('Window.onmessage')
  @DocsEditable()
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  /// Stream of `mousedown` events handled by this [Window].
  @DomName('Window.onmousedown')
  @DocsEditable()
  Stream<MouseEvent> get onMouseDown => Element.mouseDownEvent.forTarget(this);

  /// Stream of `mouseenter` events handled by this [Window].
  @DomName('Window.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseEnter =>
      Element.mouseEnterEvent.forTarget(this);

  /// Stream of `mouseleave` events handled by this [Window].
  @DomName('Window.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseLeave =>
      Element.mouseLeaveEvent.forTarget(this);

  /// Stream of `mousemove` events handled by this [Window].
  @DomName('Window.onmousemove')
  @DocsEditable()
  Stream<MouseEvent> get onMouseMove => Element.mouseMoveEvent.forTarget(this);

  /// Stream of `mouseout` events handled by this [Window].
  @DomName('Window.onmouseout')
  @DocsEditable()
  Stream<MouseEvent> get onMouseOut => Element.mouseOutEvent.forTarget(this);

  /// Stream of `mouseover` events handled by this [Window].
  @DomName('Window.onmouseover')
  @DocsEditable()
  Stream<MouseEvent> get onMouseOver => Element.mouseOverEvent.forTarget(this);

  /// Stream of `mouseup` events handled by this [Window].
  @DomName('Window.onmouseup')
  @DocsEditable()
  Stream<MouseEvent> get onMouseUp => Element.mouseUpEvent.forTarget(this);

  /// Stream of `mousewheel` events handled by this [Window].
  @DomName('Window.onmousewheel')
  @DocsEditable()
  Stream<WheelEvent> get onMouseWheel =>
      Element.mouseWheelEvent.forTarget(this);

  /// Stream of `offline` events handled by this [Window].
  @DomName('Window.onoffline')
  @DocsEditable()
  Stream<Event> get onOffline => offlineEvent.forTarget(this);

  /// Stream of `online` events handled by this [Window].
  @DomName('Window.ononline')
  @DocsEditable()
  Stream<Event> get onOnline => onlineEvent.forTarget(this);

  /// Stream of `pagehide` events handled by this [Window].
  @DomName('Window.onpagehide')
  @DocsEditable()
  Stream<Event> get onPageHide => pageHideEvent.forTarget(this);

  /// Stream of `pageshow` events handled by this [Window].
  @DomName('Window.onpageshow')
  @DocsEditable()
  Stream<Event> get onPageShow => pageShowEvent.forTarget(this);

  @DomName('Window.onpause')
  @DocsEditable()
  Stream<Event> get onPause => Element.pauseEvent.forTarget(this);

  @DomName('Window.onplay')
  @DocsEditable()
  Stream<Event> get onPlay => Element.playEvent.forTarget(this);

  @DomName('Window.onplaying')
  @DocsEditable()
  Stream<Event> get onPlaying => Element.playingEvent.forTarget(this);

  /// Stream of `popstate` events handled by this [Window].
  @DomName('Window.onpopstate')
  @DocsEditable()
  Stream<PopStateEvent> get onPopState => popStateEvent.forTarget(this);

  @DomName('Window.onprogress')
  @DocsEditable()
  Stream<Event> get onProgress => progressEvent.forTarget(this);

  @DomName('Window.onratechange')
  @DocsEditable()
  Stream<Event> get onRateChange => Element.rateChangeEvent.forTarget(this);

  /// Stream of `reset` events handled by this [Window].
  @DomName('Window.onreset')
  @DocsEditable()
  Stream<Event> get onReset => Element.resetEvent.forTarget(this);

  /// Stream of `resize` events handled by this [Window].
  @DomName('Window.onresize')
  @DocsEditable()
  Stream<Event> get onResize => Element.resizeEvent.forTarget(this);

  /// Stream of `scroll` events handled by this [Window].
  @DomName('Window.onscroll')
  @DocsEditable()
  Stream<Event> get onScroll => Element.scrollEvent.forTarget(this);

  /// Stream of `search` events handled by this [Window].
  @DomName('Window.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  Stream<Event> get onSearch => Element.searchEvent.forTarget(this);

  @DomName('Window.onseeked')
  @DocsEditable()
  Stream<Event> get onSeeked => Element.seekedEvent.forTarget(this);

  @DomName('Window.onseeking')
  @DocsEditable()
  Stream<Event> get onSeeking => Element.seekingEvent.forTarget(this);

  /// Stream of `select` events handled by this [Window].
  @DomName('Window.onselect')
  @DocsEditable()
  Stream<Event> get onSelect => Element.selectEvent.forTarget(this);

  @DomName('Window.onstalled')
  @DocsEditable()
  Stream<Event> get onStalled => Element.stalledEvent.forTarget(this);

  /// Stream of `storage` events handled by this [Window].
  @DomName('Window.onstorage')
  @DocsEditable()
  Stream<StorageEvent> get onStorage => storageEvent.forTarget(this);

  /// Stream of `submit` events handled by this [Window].
  @DomName('Window.onsubmit')
  @DocsEditable()
  Stream<Event> get onSubmit => Element.submitEvent.forTarget(this);

  @DomName('Window.onsuspend')
  @DocsEditable()
  Stream<Event> get onSuspend => Element.suspendEvent.forTarget(this);

  @DomName('Window.ontimeupdate')
  @DocsEditable()
  Stream<Event> get onTimeUpdate => Element.timeUpdateEvent.forTarget(this);

  /// Stream of `touchcancel` events handled by this [Window].
  @DomName('Window.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchCancel =>
      Element.touchCancelEvent.forTarget(this);

  /// Stream of `touchend` events handled by this [Window].
  @DomName('Window.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchEnd => Element.touchEndEvent.forTarget(this);

  /// Stream of `touchmove` events handled by this [Window].
  @DomName('Window.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchMove => Element.touchMoveEvent.forTarget(this);

  /// Stream of `touchstart` events handled by this [Window].
  @DomName('Window.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchStart =>
      Element.touchStartEvent.forTarget(this);

  /// Stream of `transitionend` events handled by this [Window].
  @DomName('Window.ontransitionend')
  @DocsEditable()
  Stream<TransitionEvent> get onTransitionEnd =>
      Element.transitionEndEvent.forTarget(this);

  /// Stream of `unload` events handled by this [Window].
  @DomName('Window.onunload')
  @DocsEditable()
  Stream<Event> get onUnload => unloadEvent.forTarget(this);

  @DomName('Window.onvolumechange')
  @DocsEditable()
  Stream<Event> get onVolumeChange => Element.volumeChangeEvent.forTarget(this);

  @DomName('Window.onwaiting')
  @DocsEditable()
  Stream<Event> get onWaiting => Element.waitingEvent.forTarget(this);

  /// Stream of `animationend` events handled by this [Window].
  @DomName('Window.onwebkitAnimationEnd')
  @DocsEditable()
  @Experimental()
  Stream<AnimationEvent> get onAnimationEnd =>
      animationEndEvent.forTarget(this);

  /// Stream of `animationiteration` events handled by this [Window].
  @DomName('Window.onwebkitAnimationIteration')
  @DocsEditable()
  @Experimental()
  Stream<AnimationEvent> get onAnimationIteration =>
      animationIterationEvent.forTarget(this);

  /// Stream of `animationstart` events handled by this [Window].
  @DomName('Window.onwebkitAnimationStart')
  @DocsEditable()
  @Experimental()
  Stream<AnimationEvent> get onAnimationStart =>
      animationStartEvent.forTarget(this);

  /**
   * Static factory designed to expose `beforeunload` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.beforeunloadEvent')
  static const EventStreamProvider<BeforeUnloadEvent> beforeUnloadEvent =
      const _BeforeUnloadEventStreamProvider('beforeunload');

  /// Stream of `beforeunload` events handled by this [Window].
  @DomName('Window.onbeforeunload')
  Stream<Event> get onBeforeUnload => beforeUnloadEvent.forTarget(this);

  /**
   * Moves this window to a specific position.
   *
   * x and y can be negative.
   *
   * ## Other resources
   *
   * * [Window.moveTo](https://developer.mozilla.org/en-US/docs/Web/API/Window.moveTo)
   *   from MDN.
   * * [Window.moveTo](http://dev.w3.org/csswg/cssom-view/#dom-window-moveto)
   *   from W3C.
   */
  void moveTo(Point p) {
    _moveTo(p.x, p.y);
  }

  @DomName('Window.pageXOffset')
  @DocsEditable()
  int get pageXOffset => JS('num', '#.pageXOffset', this).round();

  @DomName('Window.pageYOffset')
  @DocsEditable()
  int get pageYOffset => JS('num', '#.pageYOffset', this).round();

  /**
   * The distance this window has been scrolled horizontally.
   *
   * ## Other resources
   *
   * * [The Screen interface
   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
   * * [scrollX](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollX)
   *   from MDN.
   */
  @DomName('Window.scrollX')
  @DocsEditable()
  int get scrollX => JS('bool', '("scrollX" in #)', this)
      ? JS('num', '#.scrollX', this).round()
      : document.documentElement.scrollLeft;

  /**
   * The distance this window has been scrolled vertically.
   *
   * ## Other resources
   *
   * * [The Screen interface
   *   specification](http://www.w3.org/TR/cssom-view/#screen) from W3C.
   * * [scrollY](https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY)
   *   from MDN.
   */
  @DomName('Window.scrollY')
  @DocsEditable()
  int get scrollY => JS('bool', '("scrollY" in #)', this)
      ? JS('num', '#.scrollY', this).round()
      : document.documentElement.scrollTop;
}

class _BeforeUnloadEvent extends _WrappedEvent implements BeforeUnloadEvent {
  String _returnValue;

  _BeforeUnloadEvent(Event base) : super(base);

  String get returnValue => _returnValue;

  set returnValue(String value) {
    _returnValue = value;
    // FF and IE use the value as the return value, Chrome will return this from
    // the event callback function.
    if (JS('bool', '("returnValue" in #)', wrapped)) {
      JS('void', '#.returnValue = #', wrapped, value);
    }
  }
}

class _BeforeUnloadEventStreamProvider
    implements EventStreamProvider<BeforeUnloadEvent> {
  final String _eventType;

  const _BeforeUnloadEventStreamProvider(this._eventType);

  Stream<BeforeUnloadEvent> forTarget(EventTarget e, {bool useCapture: false}) {
    // Specify the generic type for EventStream only in dart2js to avoid
    // checked mode errors in dartium.
    var stream = new _EventStream<BeforeUnloadEvent>(e, _eventType, useCapture);
    var controller = new StreamController<BeforeUnloadEvent>(sync: true);

    stream.listen((event) {
      var wrapped = new _BeforeUnloadEvent(event);
      controller.add(wrapped);
    });

    return controller.stream;
  }

  String getEventType(EventTarget target) {
    return _eventType;
  }

  ElementStream<BeforeUnloadEvent> forElement(Element e,
      {bool useCapture: false}) {
    // Specify the generic type for _ElementEventStreamImpl only in dart2js to
    // avoid checked mode errors in dartium.
    return new _ElementEventStreamImpl<BeforeUnloadEvent>(
        e, _eventType, useCapture);
  }

  ElementStream<BeforeUnloadEvent> _forElementList(ElementList e,
      {bool useCapture: false}) {
    // Specify the generic type for _ElementEventStreamImpl only in dart2js to
    // avoid checked mode errors in dartium.
    return new _ElementListEventStreamImpl<BeforeUnloadEvent>(
        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 atob);

  String btoa(String btoa);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('WindowClient')
@Experimental() // untriaged
@Native("WindowClient")
class WindowClient extends Client {
  // To suppress missing implicit constructor warnings.
  factory WindowClient._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('WindowClient.focused')
  @DocsEditable()
  @Experimental() // untriaged
  final bool focused;

  @DomName('WindowClient.visibilityState')
  @DocsEditable()
  @Experimental() // untriaged
  final String visibilityState;

  @DomName('WindowClient.focus')
  @DocsEditable()
  @Experimental() // untriaged
  Future focus() native;

  @DomName('WindowClient.navigate')
  @DocsEditable()
  @Experimental() // untriaged
  Future navigate(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('WindowEventHandlers')
@Experimental() // untriaged
abstract class WindowEventHandlers extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory WindowEventHandlers._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('WindowEventHandlers.hashchangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> hashChangeEvent =
      const EventStreamProvider<Event>('hashchange');

  @DomName('WindowEventHandlers.messageEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  @DomName('WindowEventHandlers.offlineEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> offlineEvent =
      const EventStreamProvider<Event>('offline');

  @DomName('WindowEventHandlers.onlineEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> onlineEvent =
      const EventStreamProvider<Event>('online');

  @DomName('WindowEventHandlers.popstateEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<PopStateEvent> popStateEvent =
      const EventStreamProvider<PopStateEvent>('popstate');

  @DomName('WindowEventHandlers.storageEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<StorageEvent> storageEvent =
      const EventStreamProvider<StorageEvent>('storage');

  @DomName('WindowEventHandlers.unloadEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> unloadEvent =
      const EventStreamProvider<Event>('unload');

  @DomName('WindowEventHandlers.onhashchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onHashChange => hashChangeEvent.forTarget(this);

  @DomName('WindowEventHandlers.onmessage')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  @DomName('WindowEventHandlers.onoffline')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onOffline => offlineEvent.forTarget(this);

  @DomName('WindowEventHandlers.ononline')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onOnline => onlineEvent.forTarget(this);

  @DomName('WindowEventHandlers.onpopstate')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<PopStateEvent> get onPopState => popStateEvent.forTarget(this);

  @DomName('WindowEventHandlers.onstorage')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<StorageEvent> get onStorage => storageEvent.forTarget(this);

  @DomName('WindowEventHandlers.onunload')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onUnload => unloadEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('Worker')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
// http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#worker
@Experimental() // stable
@Native("Worker")
class Worker extends EventTarget implements AbstractWorker {
  // To suppress missing implicit constructor warnings.
  factory Worker._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [Worker].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Worker.errorEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [Worker].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Worker.messageEvent')
  @DocsEditable()
  static const EventStreamProvider<MessageEvent> messageEvent =
      const EventStreamProvider<MessageEvent>('message');

  @DomName('Worker.Worker')
  @DocsEditable()
  factory Worker(String scriptUrl) {
    return Worker._create_1(scriptUrl);
  }
  static Worker _create_1(scriptUrl) =>
      JS('Worker', 'new Worker(#)', scriptUrl);

  /// Checks if this type is supported on the current platform.
  static bool get supported =>
      JS('bool', '(typeof window.Worker != "undefined")');

  @DomName('Worker.postMessage')
  @DocsEditable()
  void postMessage(/*SerializedScriptValue*/ message,
      [List<MessagePort> transfer]) {
    if (transfer != null) {
      var message_1 = convertDartToNative_SerializedScriptValue(message);
      _postMessage_1(message_1, transfer);
      return;
    }
    var message_1 = convertDartToNative_SerializedScriptValue(message);
    _postMessage_2(message_1);
    return;
  }

  @JSName('postMessage')
  @DomName('Worker.postMessage')
  @DocsEditable()
  void _postMessage_1(message, List<MessagePort> transfer) native;
  @JSName('postMessage')
  @DomName('Worker.postMessage')
  @DocsEditable()
  void _postMessage_2(message) native;

  @DomName('Worker.terminate')
  @DocsEditable()
  void terminate() native;

  /// Stream of `error` events handled by this [Worker].
  @DomName('Worker.onerror')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `message` events handled by this [Worker].
  @DomName('Worker.onmessage')
  @DocsEditable()
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('WorkerConsole')
@Experimental() // untriaged
@Native("WorkerConsole")
class WorkerConsole extends ConsoleBase {
  // To suppress missing implicit constructor warnings.
  factory WorkerConsole._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('WorkerGlobalScope')
@Experimental() // untriaged
@Native("WorkerGlobalScope")
class WorkerGlobalScope extends EventTarget
    implements _WindowTimers, WindowBase64 {
  // To suppress missing implicit constructor warnings.
  factory WorkerGlobalScope._() {
    throw new UnsupportedError("Not supported");
  }

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [WorkerGlobalScope].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('WorkerGlobalScope.errorEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> errorEvent =
      const EventStreamProvider<Event>('error');

  @DomName('WorkerGlobalScope.caches')
  @DocsEditable()
  @Experimental() // untriaged
  final CacheStorage caches;

  @DomName('WorkerGlobalScope.console')
  @DocsEditable()
  @Experimental() // untriaged
  final WorkerConsole console;

  @DomName('WorkerGlobalScope.crypto')
  @DocsEditable()
  @Experimental() // untriaged
  final Crypto crypto;

  @DomName('WorkerGlobalScope.indexedDB')
  @DocsEditable()
  @Experimental() // untriaged
  final IdbFactory indexedDB;

  @DomName('WorkerGlobalScope.location')
  @DocsEditable()
  @Experimental() // untriaged
  final _WorkerLocation location;

  @DomName('WorkerGlobalScope.navigator')
  @DocsEditable()
  @Experimental() // untriaged
  final _WorkerNavigator navigator;

  @DomName('WorkerGlobalScope.performance')
  @DocsEditable()
  @Experimental() // untriaged
  final WorkerPerformance performance;

  @DomName('WorkerGlobalScope.self')
  @DocsEditable()
  @Experimental() // untriaged
  final WorkerGlobalScope self;

  @DomName('WorkerGlobalScope.close')
  @DocsEditable()
  @Experimental() // untriaged
  void close() native;

  @DomName('WorkerGlobalScope.fetch')
  @DocsEditable()
  @Experimental() // untriaged
  Future fetch(/*RequestInfo*/ input, [Map init]) {
    if (init != null) {
      var init_1 = convertDartToNative_Dictionary(init);
      return _fetch_1(input, init_1);
    }
    return _fetch_2(input);
  }

  @JSName('fetch')
  @DomName('WorkerGlobalScope.fetch')
  @DocsEditable()
  @Experimental() // untriaged
  Future _fetch_1(input, init) native;
  @JSName('fetch')
  @DomName('WorkerGlobalScope.fetch')
  @DocsEditable()
  @Experimental() // untriaged
  Future _fetch_2(input) native;

  @DomName('WorkerGlobalScope.importScripts')
  @DocsEditable()
  @Experimental() // untriaged
  void importScripts(String urls) native;

  // From WindowBase64

  @DomName('WorkerGlobalScope.atob')
  @DocsEditable()
  @Experimental() // untriaged
  String atob(String atob) native;

  @DomName('WorkerGlobalScope.btoa')
  @DocsEditable()
  @Experimental() // untriaged
  String btoa(String btoa) native;

  // From WindowTimers

  @JSName('setInterval')
  @DomName('WorkerGlobalScope.setInterval')
  @DocsEditable()
  @Experimental() // untriaged
  int _setInterval_String(String handler, [int timeout, Object arguments])
      native;

  @JSName('setTimeout')
  @DomName('WorkerGlobalScope.setTimeout')
  @DocsEditable()
  @Experimental() // untriaged
  int _setTimeout_String(String handler, [int timeout, Object arguments])
      native;

  @JSName('clearInterval')
  @DomName('WorkerGlobalScope.clearInterval')
  @DocsEditable()
  @Experimental() // untriaged
  void _clearInterval([int handle]) native;

  @JSName('clearTimeout')
  @DomName('WorkerGlobalScope.clearTimeout')
  @DocsEditable()
  @Experimental() // untriaged
  void _clearTimeout([int handle]) native;

  @JSName('setInterval')
  @DomName('WorkerGlobalScope.setInterval')
  @DocsEditable()
  @Experimental() // untriaged
  int _setInterval(Object handler, [int timeout]) native;

  @JSName('setTimeout')
  @DomName('WorkerGlobalScope.setTimeout')
  @DocsEditable()
  @Experimental() // untriaged
  int _setTimeout(Object handler, [int timeout]) native;

  /// Stream of `error` events handled by this [WorkerGlobalScope].
  @DomName('WorkerGlobalScope.onerror')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onError => errorEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('WorkerPerformance')
@Experimental() // untriaged
@Native("WorkerPerformance")
class WorkerPerformance extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory WorkerPerformance._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('WorkerPerformance.memory')
  @DocsEditable()
  @Experimental() // untriaged
  final MemoryInfo memory;

  @DomName('WorkerPerformance.clearMarks')
  @DocsEditable()
  @Experimental() // untriaged
  void clearMarks(String markName) native;

  @DomName('WorkerPerformance.clearMeasures')
  @DocsEditable()
  @Experimental() // untriaged
  void clearMeasures(String measureName) native;

  @DomName('WorkerPerformance.clearResourceTimings')
  @DocsEditable()
  @Experimental() // untriaged
  void clearResourceTimings() native;

  @DomName('WorkerPerformance.getEntries')
  @DocsEditable()
  @Experimental() // untriaged
  List<PerformanceEntry> getEntries() native;

  @DomName('WorkerPerformance.getEntriesByName')
  @DocsEditable()
  @Experimental() // untriaged
  List<PerformanceEntry> getEntriesByName(String name, String entryType) native;

  @DomName('WorkerPerformance.getEntriesByType')
  @DocsEditable()
  @Experimental() // untriaged
  List<PerformanceEntry> getEntriesByType(String entryType) native;

  @DomName('WorkerPerformance.mark')
  @DocsEditable()
  @Experimental() // untriaged
  void mark(String markName) native;

  @DomName('WorkerPerformance.measure')
  @DocsEditable()
  @Experimental() // untriaged
  void measure(String measureName, String startMark, String endMark) native;

  @DomName('WorkerPerformance.now')
  @DocsEditable()
  @Experimental() // untriaged
  double now() native;

  @DomName('WorkerPerformance.setResourceTimingBufferSize')
  @DocsEditable()
  @Experimental() // untriaged
  void setResourceTimingBufferSize(int maxSize) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('XPathEvaluator')
// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathEvaluator
@deprecated // experimental
@Native("XPathEvaluator")
class XPathEvaluator extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory XPathEvaluator._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('XPathEvaluator.XPathEvaluator')
  @DocsEditable()
  factory XPathEvaluator() {
    return XPathEvaluator._create_1();
  }
  static XPathEvaluator _create_1() =>
      JS('XPathEvaluator', 'new XPathEvaluator()');

  @DomName('XPathEvaluator.createExpression')
  @DocsEditable()
  XPathExpression createExpression(String expression, XPathNSResolver resolver)
      native;

  @DomName('XPathEvaluator.createNSResolver')
  @DocsEditable()
  XPathNSResolver createNSResolver(Node nodeResolver) native;

  @DomName('XPathEvaluator.evaluate')
  @DocsEditable()
  XPathResult evaluate(
      String expression, Node contextNode, XPathNSResolver resolver,
      [int type, Object inResult]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('XPathExpression')
// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathExpression
@deprecated // experimental
@Native("XPathExpression")
class XPathExpression extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory XPathExpression._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('XPathExpression.evaluate')
  @DocsEditable()
  XPathResult evaluate(Node contextNode, [int type, Object inResult]) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('XPathNSResolver')
// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathNSResolver
@deprecated // experimental
@Native("XPathNSResolver")
class XPathNSResolver extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory XPathNSResolver._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('lookupNamespaceURI')
  @DomName('XPathNSResolver.lookupNamespaceURI')
  @DocsEditable()
  String lookupNamespaceUri(String prefix) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('XPathResult')
// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathResult
@deprecated // experimental
@Native("XPathResult")
class XPathResult extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory XPathResult._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('XPathResult.ANY_TYPE')
  @DocsEditable()
  static const int ANY_TYPE = 0;

  @DomName('XPathResult.ANY_UNORDERED_NODE_TYPE')
  @DocsEditable()
  static const int ANY_UNORDERED_NODE_TYPE = 8;

  @DomName('XPathResult.BOOLEAN_TYPE')
  @DocsEditable()
  static const int BOOLEAN_TYPE = 3;

  @DomName('XPathResult.FIRST_ORDERED_NODE_TYPE')
  @DocsEditable()
  static const int FIRST_ORDERED_NODE_TYPE = 9;

  @DomName('XPathResult.NUMBER_TYPE')
  @DocsEditable()
  static const int NUMBER_TYPE = 1;

  @DomName('XPathResult.ORDERED_NODE_ITERATOR_TYPE')
  @DocsEditable()
  static const int ORDERED_NODE_ITERATOR_TYPE = 5;

  @DomName('XPathResult.ORDERED_NODE_SNAPSHOT_TYPE')
  @DocsEditable()
  static const int ORDERED_NODE_SNAPSHOT_TYPE = 7;

  @DomName('XPathResult.STRING_TYPE')
  @DocsEditable()
  static const int STRING_TYPE = 2;

  @DomName('XPathResult.UNORDERED_NODE_ITERATOR_TYPE')
  @DocsEditable()
  static const int UNORDERED_NODE_ITERATOR_TYPE = 4;

  @DomName('XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE')
  @DocsEditable()
  static const int UNORDERED_NODE_SNAPSHOT_TYPE = 6;

  @DomName('XPathResult.booleanValue')
  @DocsEditable()
  final bool booleanValue;

  @DomName('XPathResult.invalidIteratorState')
  @DocsEditable()
  final bool invalidIteratorState;

  @DomName('XPathResult.numberValue')
  @DocsEditable()
  final double numberValue;

  @DomName('XPathResult.resultType')
  @DocsEditable()
  final int resultType;

  @DomName('XPathResult.singleNodeValue')
  @DocsEditable()
  final Node singleNodeValue;

  @DomName('XPathResult.snapshotLength')
  @DocsEditable()
  final int snapshotLength;

  @DomName('XPathResult.stringValue')
  @DocsEditable()
  final String stringValue;

  @DomName('XPathResult.iterateNext')
  @DocsEditable()
  Node iterateNext() native;

  @DomName('XPathResult.snapshotItem')
  @DocsEditable()
  Node snapshotItem(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('XMLDocument')
@Experimental() // untriaged
@Native("XMLDocument")
class XmlDocument extends Document {
  // To suppress missing implicit constructor warnings.
  factory XmlDocument._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('XMLSerializer')
// http://domparsing.spec.whatwg.org/#the-xmlserializer-interface
@deprecated // stable
@Native("XMLSerializer")
class XmlSerializer extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory XmlSerializer._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('XMLSerializer.XMLSerializer')
  @DocsEditable()
  factory XmlSerializer() {
    return XmlSerializer._create_1();
  }
  static XmlSerializer _create_1() =>
      JS('XmlSerializer', 'new XMLSerializer()');

  @DomName('XMLSerializer.serializeToString')
  @DocsEditable()
  String serializeToString(Node root) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('XSLTProcessor')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@deprecated // nonstandard
@Native("XSLTProcessor")
class XsltProcessor extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory XsltProcessor._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('XSLTProcessor.XSLTProcessor')
  @DocsEditable()
  factory XsltProcessor() {
    return XsltProcessor._create_1();
  }
  static XsltProcessor _create_1() =>
      JS('XsltProcessor', 'new XSLTProcessor()');

  /// Checks if this type is supported on the current platform.
  static bool get supported => JS('bool', '!!(window.XSLTProcessor)');

  @DomName('XSLTProcessor.clearParameters')
  @DocsEditable()
  void clearParameters() native;

  @DomName('XSLTProcessor.getParameter')
  @DocsEditable()
  String getParameter(String namespaceURI, String localName) native;

  @DomName('XSLTProcessor.importStylesheet')
  @DocsEditable()
  void importStylesheet(Node style) 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 output) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('Attr')
@Native("Attr")
class _Attr extends Node {
  // To suppress missing implicit constructor warnings.
  factory _Attr._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('localName')
  @DomName('Attr.localName')
  @DocsEditable()
  @Experimental() // untriaged
  final String _localName;

  @DomName('Attr.name')
  @DocsEditable()
  final String name;

  @JSName('namespaceURI')
  @DomName('Attr.namespaceURI')
  @DocsEditable()
  @Experimental() // untriaged
  final String _namespaceUri;

  // Use implementation from Node.
  // final String nodeValue;

  @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('Bluetooth')
@Experimental() // untriaged
@Native("Bluetooth")
abstract class _Bluetooth extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _Bluetooth._() {
    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('BluetoothAdvertisingData')
@Experimental() // untriaged
@Native("BluetoothAdvertisingData")
abstract class _BluetoothAdvertisingData extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _BluetoothAdvertisingData._() {
    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('BluetoothCharacteristicProperties')
@Experimental() // untriaged
@Native("BluetoothCharacteristicProperties")
abstract class _BluetoothCharacteristicProperties extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _BluetoothCharacteristicProperties._() {
    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('BluetoothDevice')
@Experimental() // untriaged
@Native("BluetoothDevice")
abstract class _BluetoothDevice extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory _BluetoothDevice._() {
    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('BluetoothRemoteGATTCharacteristic')
@Experimental() // untriaged
@Native("BluetoothRemoteGATTCharacteristic")
abstract class _BluetoothRemoteGATTCharacteristic extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory _BluetoothRemoteGATTCharacteristic._() {
    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('BluetoothRemoteGATTServer')
@Experimental() // untriaged
@Native("BluetoothRemoteGATTServer")
abstract class _BluetoothRemoteGATTServer extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _BluetoothRemoteGATTServer._() {
    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('BluetoothRemoteGATTService')
@Experimental() // untriaged
@Native("BluetoothRemoteGATTService")
abstract class _BluetoothRemoteGATTService extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _BluetoothRemoteGATTService._() {
    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('BluetoothUUID')
@Experimental() // untriaged
@Native("BluetoothUUID")
abstract class _BluetoothUUID extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _BluetoothUUID._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('Cache')
@Experimental() // untriaged
@Native("Cache")
abstract class _Cache extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _Cache._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('CanvasPathMethods')
@Experimental() // untriaged
abstract class _CanvasPathMethods extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _CanvasPathMethods._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('ClientRect')
@Native("ClientRect")
class _ClientRect extends Interceptor implements Rectangle {
  // NOTE! All code below should be common with RectangleBase.
  String toString() {
    return 'Rectangle ($left, $top) $width x $height';
  }

  bool operator ==(other) {
    if (other is! Rectangle) return false;
    return left == other.left &&
        top == other.top &&
        width == other.width &&
        height == other.height;
  }

  int get hashCode => _JenkinsSmiHash.hash4(
      left.hashCode, top.hashCode, width.hashCode, height.hashCode);

  /**
   * Computes the intersection of `this` and [other].
   *
   * The intersection of two axis-aligned rectangles, if any, is always another
   * axis-aligned rectangle.
   *
   * Returns the intersection of this and `other`, or null if they don't
   * intersect.
   */
  Rectangle intersection(Rectangle other) {
    var x0 = max(left, other.left);
    var x1 = min(left + width, other.left + other.width);

    if (x0 <= x1) {
      var y0 = max(top, other.top);
      var y1 = min(top + height, other.top + other.height);

      if (y0 <= y1) {
        return new Rectangle(x0, y0, x1 - x0, y1 - y0);
      }
    }
    return null;
  }

  /**
   * Returns true if `this` intersects [other].
   */
  bool intersects(Rectangle<num> other) {
    return (left <= other.left + other.width &&
        other.left <= left + width &&
        top <= other.top + other.height &&
        other.top <= top + height);
  }

  /**
   * Returns a new rectangle which completely contains `this` and [other].
   */
  Rectangle boundingBox(Rectangle other) {
    var right = max(this.left + this.width, other.left + other.width);
    var bottom = max(this.top + this.height, other.top + other.height);

    var left = min(this.left, other.left);
    var top = min(this.top, other.top);

    return new Rectangle(left, top, right - left, bottom - top);
  }

  /**
   * Tests whether `this` entirely contains [another].
   */
  bool containsRectangle(Rectangle<num> another) {
    return left <= another.left &&
        left + width >= another.left + another.width &&
        top <= another.top &&
        top + height >= another.top + another.height;
  }

  /**
   * Tests whether [another] is inside or along the edges of `this`.
   */
  bool containsPoint(Point<num> another) {
    return another.x >= left &&
        another.x <= left + width &&
        another.y >= top &&
        another.y <= top + height;
  }

  Point get topLeft => new Point/*<num>*/(this.left, this.top);
  Point get topRight => new Point/*<num>*/(this.left + this.width, this.top);
  Point get bottomRight =>
      new Point/*<num>*/(this.left + this.width, this.top + this.height);
  Point get bottomLeft => new Point/*<num>*/(this.left, this.top + this.height);

  // To suppress missing implicit constructor warnings.
  factory _ClientRect._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('ClientRect.bottom')
  @DocsEditable()
  final double bottom;

  @DomName('ClientRect.height')
  @DocsEditable()
  final double height;

  @DomName('ClientRect.left')
  @DocsEditable()
  final double left;

  @DomName('ClientRect.right')
  @DocsEditable()
  final double right;

  @DomName('ClientRect.top')
  @DocsEditable()
  final double top;

  @DomName('ClientRect.width')
  @DocsEditable()
  final double width;
}

/**
 * This is the [Jenkins hash function][1] but using masking to keep
 * values in SMI range.
 *
 * [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function
 *
 * Use:
 * Hash each value with the hash of the previous value, then get the final
 * hash by calling finish.
 *
 *     var hash = 0;
 *     for (var value in values) {
 *       hash = JenkinsSmiHash.combine(hash, value.hashCode);
 *     }
 *     hash = JenkinsSmiHash.finish(hash);
 */
class _JenkinsSmiHash {
  // TODO(11617): This class should be optimized and standardized elsewhere.

  static int combine(int hash, int value) {
    hash = 0x1fffffff & (hash + value);
    hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
    return hash ^ (hash >> 6);
  }

  static int finish(int hash) {
    hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
    hash = hash ^ (hash >> 11);
    return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
  }

  static int hash2(a, b) => finish(combine(combine(0, a), b));

  static int hash4(a, b, c, d) =>
      finish(combine(combine(combine(combine(0, a), b), c), d));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('ClientRectList')
@Native("ClientRectList,DOMRectList")
class _ClientRectList extends Interceptor
    with ListMixin<Rectangle>, ImmutableListMixin<Rectangle>
    implements List<Rectangle>, JavaScriptIndexingBehavior<Rectangle> {
  // To suppress missing implicit constructor warnings.
  factory _ClientRectList._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('ClientRectList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  Rectangle operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("Rectangle", "#[#]", this, index);
  }

  void operator []=(int index, Rectangle value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Rectangle> mixins.
  // Rectangle is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Rectangle get first {
    if (this.length > 0) {
      return JS('Rectangle', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Rectangle get last {
    int len = this.length;
    if (len > 0) {
      return JS('Rectangle', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Rectangle get single {
    int len = this.length;
    if (len == 1) {
      return JS('Rectangle', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Rectangle elementAt(int index) => this[index];
  // -- end List<Rectangle> mixins.

  @DomName('ClientRectList.__getter__')
  @DocsEditable()
  @Experimental() // untriaged
  Rectangle __getter__(int index) native;

  @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('CSSRuleList')
@Native("CSSRuleList")
class _CssRuleList extends Interceptor
    with ListMixin<CssRule>, ImmutableListMixin<CssRule>
    implements JavaScriptIndexingBehavior<CssRule>, List<CssRule> {
  // To suppress missing implicit constructor warnings.
  factory _CssRuleList._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('CSSRuleList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  CssRule operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("CssRule", "#[#]", this, index);
  }

  void operator []=(int index, CssRule value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<CssRule> mixins.
  // CssRule is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  CssRule get first {
    if (this.length > 0) {
      return JS('CssRule', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  CssRule get last {
    int len = this.length;
    if (len > 0) {
      return JS('CssRule', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  CssRule get single {
    int len = this.length;
    if (len == 1) {
      return JS('CssRule', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  CssRule elementAt(int index) => this[index];
  // -- end List<CssRule> mixins.

  @DomName('CSSRuleList.item')
  @DocsEditable()
  CssRule item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('DOMFileSystemSync')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://www.w3.org/TR/file-system-api/#the-filesystemsync-interface
@Native("DOMFileSystemSync")
abstract class _DOMFileSystemSync extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _DOMFileSystemSync._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('DirectoryEntrySync')
// http://www.w3.org/TR/file-system-api/#the-directoryentrysync-interface
@Experimental()
@Native("DirectoryEntrySync")
abstract class _DirectoryEntrySync extends _EntrySync {
  // To suppress missing implicit constructor warnings.
  factory _DirectoryEntrySync._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('DirectoryReaderSync')
// http://www.w3.org/TR/file-system-api/#idl-def-DirectoryReaderSync
@Experimental()
@Native("DirectoryReaderSync")
abstract class _DirectoryReaderSync extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _DirectoryReaderSync._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('DocumentType')
// http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-412266927
@deprecated // stable
@Native("DocumentType")
abstract class _DocumentType extends Node implements ChildNode {
  // To suppress missing implicit constructor warnings.
  factory _DocumentType._() {
    throw new UnsupportedError("Not supported");
  }

  // From ChildNode

}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('DOMRect')
@Experimental() // untriaged
@Native("DOMRect")
class _DomRect extends DomRectReadOnly {
  // To suppress missing implicit constructor warnings.
  factory _DomRect._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('DOMRect.DOMRect')
  @DocsEditable()
  factory _DomRect([num x, num y, num width, num height]) {
    if (height != null) {
      return _DomRect._create_1(x, y, width, height);
    }
    if (width != null) {
      return _DomRect._create_2(x, y, width);
    }
    if (y != null) {
      return _DomRect._create_3(x, y);
    }
    if (x != null) {
      return _DomRect._create_4(x);
    }
    return _DomRect._create_5();
  }
  static _DomRect _create_1(x, y, width, height) =>
      JS('_DomRect', 'new DOMRect(#,#,#,#)', x, y, width, height);
  static _DomRect _create_2(x, y, width) =>
      JS('_DomRect', 'new DOMRect(#,#,#)', x, y, width);
  static _DomRect _create_3(x, y) => JS('_DomRect', 'new DOMRect(#,#)', x, y);
  static _DomRect _create_4(x) => JS('_DomRect', 'new DOMRect(#)', x);
  static _DomRect _create_5() => JS('_DomRect', 'new DOMRect()');

  // Shadowing definition.
  num get height => JS("num", "#.height", this);

  set height(num value) {
    JS("void", "#.height = #", this, value);
  }

  // Shadowing definition.
  num get width => JS("num", "#.width", this);

  set width(num value) {
    JS("void", "#.width = #", this, value);
  }

  // Shadowing definition.
  num get x => JS("num", "#.x", this);

  set x(num value) {
    JS("void", "#.x = #", this, value);
  }

  // Shadowing definition.
  num get y => JS("num", "#.y", this);

  set y(num value) {
    JS("void", "#.y = #", this, value);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('EntrySync')
// http://www.w3.org/TR/file-system-api/#idl-def-EntrySync
@Experimental()
@Native("EntrySync")
abstract class _EntrySync extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _EntrySync._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('FileEntrySync')
// http://www.w3.org/TR/file-system-api/#the-fileentrysync-interface
@Experimental()
@Native("FileEntrySync")
abstract class _FileEntrySync extends _EntrySync {
  // To suppress missing implicit constructor warnings.
  factory _FileEntrySync._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('FileReaderSync')
// http://www.w3.org/TR/FileAPI/#FileReaderSync
@Experimental()
@Native("FileReaderSync")
abstract class _FileReaderSync extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _FileReaderSync._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('FileReaderSync.FileReaderSync')
  @DocsEditable()
  factory _FileReaderSync() {
    return _FileReaderSync._create_1();
  }
  static _FileReaderSync _create_1() =>
      JS('_FileReaderSync', 'new FileReaderSync()');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('FileWriterSync')
// http://www.w3.org/TR/file-writer-api/#idl-def-FileWriterSync
@Experimental()
@Native("FileWriterSync")
abstract class _FileWriterSync extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _FileWriterSync._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('GamepadList')
// https://dvcs.w3.org/hg/gamepad/raw-file/default/gamepad.html
@Experimental()
@Native("GamepadList")
class _GamepadList extends Interceptor
    with ListMixin<Gamepad>, ImmutableListMixin<Gamepad>
    implements List<Gamepad>, JavaScriptIndexingBehavior<Gamepad> {
  // To suppress missing implicit constructor warnings.
  factory _GamepadList._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('GamepadList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  Gamepad operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("Gamepad|Null", "#[#]", this, index);
  }

  void operator []=(int index, Gamepad value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Gamepad> mixins.
  // Gamepad is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Gamepad get first {
    if (this.length > 0) {
      return JS('Gamepad|Null', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Gamepad get last {
    int len = this.length;
    if (len > 0) {
      return JS('Gamepad|Null', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Gamepad get single {
    int len = this.length;
    if (len == 1) {
      return JS('Gamepad|Null', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Gamepad elementAt(int index) => this[index];
  // -- end List<Gamepad> mixins.

  @DomName('GamepadList.item')
  @DocsEditable()
  Gamepad item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLAllCollection')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#dom-document-all
@deprecated // deprecated
@Native("HTMLAllCollection")
abstract class _HTMLAllCollection extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _HTMLAllCollection._() {
    throw new UnsupportedError("Not supported");
  }

  @JSName('item')
  @DomName('HTMLAllCollection.item')
  @DocsEditable()
  Element _item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLDirectoryElement')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#dir
@deprecated // deprecated
@Native("HTMLDirectoryElement")
abstract class _HTMLDirectoryElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory _HTMLDirectoryElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLDirectoryElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLFontElement')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#htmlfontelement
@deprecated // deprecated
@Native("HTMLFontElement")
abstract class _HTMLFontElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory _HTMLFontElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLFontElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLFrameElement')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#htmlframeelement
@deprecated // deprecated
@Native("HTMLFrameElement")
abstract class _HTMLFrameElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory _HTMLFrameElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLFrameElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLFrameSetElement')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#frameset
@deprecated // deprecated
@Native("HTMLFrameSetElement")
abstract class _HTMLFrameSetElement extends HtmlElement
    implements WindowEventHandlers {
  // To suppress missing implicit constructor warnings.
  factory _HTMLFrameSetElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLFrameSetElement.created() : super.created();
}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('HTMLMarqueeElement')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#the-marquee-element
@deprecated // deprecated
@Native("HTMLMarqueeElement")
abstract class _HTMLMarqueeElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory _HTMLMarqueeElement._() {
    throw new UnsupportedError("Not supported");
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLMarqueeElement.created() : super.created();
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('NFC')
@Experimental() // untriaged
@Native("NFC")
abstract class _NFC extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _NFC._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('NamedNodeMap')
// http://dom.spec.whatwg.org/#namednodemap
@deprecated // deprecated
@Native("NamedNodeMap,MozNamedAttrMap")
class _NamedNodeMap extends Interceptor
    with ListMixin<Node>, ImmutableListMixin<Node>
    implements JavaScriptIndexingBehavior<Node>, List<Node> {
  // To suppress missing implicit constructor warnings.
  factory _NamedNodeMap._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('NamedNodeMap.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  Node operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("Node", "#[#]", this, index);
  }

  void operator []=(int index, Node value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Node> mixins.
  // Node is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Node get first {
    if (this.length > 0) {
      return JS('Node', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  Node get last {
    int len = this.length;
    if (len > 0) {
      return JS('Node', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  Node get single {
    int len = this.length;
    if (len == 1) {
      return JS('Node', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Node elementAt(int index) => this[index];
  // -- end List<Node> mixins.

  @DomName('NamedNodeMap.getNamedItem')
  @DocsEditable()
  _Attr getNamedItem(String name) native;

  @DomName('NamedNodeMap.getNamedItemNS')
  @DocsEditable()
  _Attr getNamedItemNS(String namespaceURI, String localName) native;

  @DomName('NamedNodeMap.item')
  @DocsEditable()
  _Attr item(int index) native;

  @DomName('NamedNodeMap.removeNamedItem')
  @DocsEditable()
  _Attr removeNamedItem(String name) native;

  @DomName('NamedNodeMap.removeNamedItemNS')
  @DocsEditable()
  _Attr removeNamedItemNS(String namespaceURI, String localName) native;

  @DomName('NamedNodeMap.setNamedItem')
  @DocsEditable()
  _Attr setNamedItem(_Attr attr) native;

  @DomName('NamedNodeMap.setNamedItemNS')
  @DocsEditable()
  _Attr setNamedItemNS(_Attr attr) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('PagePopupController')
@deprecated // nonstandard
@Native("PagePopupController")
abstract class _PagePopupController extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _PagePopupController._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 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('Request')
@Experimental() // untriaged
@Native("Request")
class _Request extends Body {
  // To suppress missing implicit constructor warnings.
  factory _Request._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Request.Request')
  @DocsEditable()
  factory _Request(Object input, [Map requestInitDict]) {
    if (requestInitDict != null) {
      var requestInitDict_1 = convertDartToNative_Dictionary(requestInitDict);
      return _Request._create_1(input, requestInitDict_1);
    }
    return _Request._create_2(input);
  }
  static _Request _create_1(input, requestInitDict) =>
      JS('_Request', 'new Request(#,#)', input, requestInitDict);
  static _Request _create_2(input) => JS('_Request', 'new Request(#)', input);

  @DomName('Request.credentials')
  @DocsEditable()
  @Experimental() // untriaged
  final String credentials;

  @DomName('Request.headers')
  @DocsEditable()
  @Experimental() // untriaged
  final Headers headers;

  @DomName('Request.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  final String integrity;

  @DomName('Request.mode')
  @DocsEditable()
  @Experimental() // untriaged
  final String mode;

  @DomName('Request.redirect')
  @DocsEditable()
  @Experimental() // untriaged
  final String redirect;

  @DomName('Request.referrer')
  @DocsEditable()
  @Experimental() // untriaged
  final String referrer;

  @DomName('Request.url')
  @DocsEditable()
  @Experimental() // untriaged
  final String url;

  @DomName('Request.clone')
  @DocsEditable()
  @Experimental() // untriaged
  _Request clone() native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('ResourceProgressEvent')
// https://chromiumcodereview.appspot.com/14773025/
@deprecated // experimental
@Native("ResourceProgressEvent")
abstract class _ResourceProgressEvent extends ProgressEvent {
  // To suppress missing implicit constructor warnings.
  factory _ResourceProgressEvent._() {
    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('Response')
@Experimental() // untriaged
@Native("Response")
abstract class _Response extends Body {
  // To suppress missing implicit constructor warnings.
  factory _Response._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('Response.Response')
  @DocsEditable()
  factory _Response([Object body, Map responseInitDict]) {
    if (responseInitDict != null) {
      var responseInitDict_1 = convertDartToNative_Dictionary(responseInitDict);
      return _Response._create_1(body, responseInitDict_1);
    }
    if (body != null) {
      return _Response._create_2(body);
    }
    return _Response._create_3();
  }
  static _Response _create_1(body, responseInitDict) =>
      JS('_Response', 'new Response(#,#)', body, responseInitDict);
  static _Response _create_2(body) => JS('_Response', 'new Response(#)', body);
  static _Response _create_3() => JS('_Response', 'new 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.

@DocsEditable()
@DomName('ServiceWorker')
@Experimental() // untriaged
@Native("ServiceWorker")
abstract class _ServiceWorker extends EventTarget implements AbstractWorker {
  // To suppress missing implicit constructor warnings.
  factory _ServiceWorker._() {
    throw new UnsupportedError("Not supported");
  }
}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('SpeechRecognitionResultList')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechrecognitionresultlist
@Experimental()
@Native("SpeechRecognitionResultList")
class _SpeechRecognitionResultList extends Interceptor
    with
        ListMixin<SpeechRecognitionResult>,
        ImmutableListMixin<SpeechRecognitionResult>
    implements
        JavaScriptIndexingBehavior<SpeechRecognitionResult>,
        List<SpeechRecognitionResult> {
  // To suppress missing implicit constructor warnings.
  factory _SpeechRecognitionResultList._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('SpeechRecognitionResultList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  SpeechRecognitionResult operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("SpeechRecognitionResult", "#[#]", this, index);
  }

  void operator []=(int index, SpeechRecognitionResult value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<SpeechRecognitionResult> mixins.
  // SpeechRecognitionResult is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  SpeechRecognitionResult get first {
    if (this.length > 0) {
      return JS('SpeechRecognitionResult', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  SpeechRecognitionResult get last {
    int len = this.length;
    if (len > 0) {
      return JS('SpeechRecognitionResult', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  SpeechRecognitionResult get single {
    int len = this.length;
    if (len == 1) {
      return JS('SpeechRecognitionResult', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  SpeechRecognitionResult elementAt(int index) => this[index];
  // -- end List<SpeechRecognitionResult> mixins.

  @DomName('SpeechRecognitionResultList.item')
  @DocsEditable()
  SpeechRecognitionResult item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('StyleSheetList')
@Native("StyleSheetList")
class _StyleSheetList extends Interceptor
    with ListMixin<StyleSheet>, ImmutableListMixin<StyleSheet>
    implements List<StyleSheet>, JavaScriptIndexingBehavior<StyleSheet> {
  // To suppress missing implicit constructor warnings.
  factory _StyleSheetList._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('StyleSheetList.length')
  @DocsEditable()
  int get length => JS("int", "#.length", this);

  StyleSheet operator [](int index) {
    if (JS("bool", "# >>> 0 !== # || # >= #", index, index, index, length))
      throw new RangeError.index(index, this);
    return JS("StyleSheet", "#[#]", this, index);
  }

  void operator []=(int index, StyleSheet value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<StyleSheet> mixins.
  // StyleSheet is the element type.

  set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  StyleSheet get first {
    if (this.length > 0) {
      return JS('StyleSheet', '#[0]', this);
    }
    throw new StateError("No elements");
  }

  StyleSheet get last {
    int len = this.length;
    if (len > 0) {
      return JS('StyleSheet', '#[#]', this, len - 1);
    }
    throw new StateError("No elements");
  }

  StyleSheet get single {
    int len = this.length;
    if (len == 1) {
      return JS('StyleSheet', '#[0]', this);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  StyleSheet elementAt(int index) => this[index];
  // -- end List<StyleSheet> mixins.

  @DomName('StyleSheetList.__getter__')
  @DocsEditable()
  CssStyleSheet __getter__(String name) native;

  @DomName('StyleSheetList.item')
  @DocsEditable()
  StyleSheet item(int index) native;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('SubtleCrypto')
@Experimental() // untriaged
@Native("SubtleCrypto")
abstract class _SubtleCrypto extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _SubtleCrypto._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('USB')
@Experimental() // untriaged
@Native("USB")
abstract class _USB extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory _USB._() {
    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('USBAlternateInterface')
@Experimental() // untriaged
@Native("USBAlternateInterface")
abstract class _USBAlternateInterface extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBAlternateInterface._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('USBAlternateInterface.USBAlternateInterface')
  @DocsEditable()
  factory _USBAlternateInterface(
      _USBInterface deviceInterface, int alternateSetting) {
    return _USBAlternateInterface._create_1(deviceInterface, alternateSetting);
  }
  static _USBAlternateInterface _create_1(deviceInterface, alternateSetting) =>
      JS('_USBAlternateInterface', 'new USBAlternateInterface(#,#)',
          deviceInterface, alternateSetting);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('USBConfiguration')
@Experimental() // untriaged
@Native("USBConfiguration")
abstract class _USBConfiguration extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBConfiguration._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('USBConfiguration.USBConfiguration')
  @DocsEditable()
  factory _USBConfiguration(_USBDevice device, int configurationValue) {
    return _USBConfiguration._create_1(device, configurationValue);
  }
  static _USBConfiguration _create_1(device, configurationValue) => JS(
      '_USBConfiguration',
      'new USBConfiguration(#,#)',
      device,
      configurationValue);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('USBConnectionEvent')
@Experimental() // untriaged
@Native("USBConnectionEvent")
abstract class _USBConnectionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory _USBConnectionEvent._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('USBConnectionEvent.USBConnectionEvent')
  @DocsEditable()
  factory _USBConnectionEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _USBConnectionEvent._create_1(type, eventInitDict_1);
    }
    return _USBConnectionEvent._create_2(type);
  }
  static _USBConnectionEvent _create_1(type, eventInitDict) => JS(
      '_USBConnectionEvent',
      'new USBConnectionEvent(#,#)',
      type,
      eventInitDict);
  static _USBConnectionEvent _create_2(type) =>
      JS('_USBConnectionEvent', 'new USBConnectionEvent(#)', 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('USBDevice')
@Experimental() // untriaged
@Native("USBDevice")
abstract class _USBDevice extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBDevice._() {
    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('USBEndpoint')
@Experimental() // untriaged
@Native("USBEndpoint")
abstract class _USBEndpoint extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBEndpoint._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('USBEndpoint.USBEndpoint')
  @DocsEditable()
  factory _USBEndpoint(
      _USBAlternateInterface alternate, int endpointNumber, String direction) {
    return _USBEndpoint._create_1(alternate, endpointNumber, direction);
  }
  static _USBEndpoint _create_1(alternate, endpointNumber, direction) => JS(
      '_USBEndpoint',
      'new USBEndpoint(#,#,#)',
      alternate,
      endpointNumber,
      direction);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('USBInTransferResult')
@Experimental() // untriaged
@Native("USBInTransferResult")
abstract class _USBInTransferResult extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBInTransferResult._() {
    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('USBInterface')
@Experimental() // untriaged
@Native("USBInterface")
abstract class _USBInterface extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBInterface._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('USBInterface.USBInterface')
  @DocsEditable()
  factory _USBInterface(_USBConfiguration configuration, int interfaceNumber) {
    return _USBInterface._create_1(configuration, interfaceNumber);
  }
  static _USBInterface _create_1(configuration, interfaceNumber) => JS(
      '_USBInterface', 'new USBInterface(#,#)', configuration, interfaceNumber);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('USBIsochronousInTransferPacket')
@Experimental() // untriaged
@Native("USBIsochronousInTransferPacket")
abstract class _USBIsochronousInTransferPacket extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBIsochronousInTransferPacket._() {
    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('USBIsochronousInTransferResult')
@Experimental() // untriaged
@Native("USBIsochronousInTransferResult")
abstract class _USBIsochronousInTransferResult extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBIsochronousInTransferResult._() {
    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('USBIsochronousOutTransferPacket')
@Experimental() // untriaged
@Native("USBIsochronousOutTransferPacket")
abstract class _USBIsochronousOutTransferPacket extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBIsochronousOutTransferPacket._() {
    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('USBIsochronousOutTransferResult')
@Experimental() // untriaged
@Native("USBIsochronousOutTransferResult")
abstract class _USBIsochronousOutTransferResult extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBIsochronousOutTransferResult._() {
    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('USBOutTransferResult')
@Experimental() // untriaged
@Native("USBOutTransferResult")
abstract class _USBOutTransferResult extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _USBOutTransferResult._() {
    throw new UnsupportedError("Not supported");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('WebKitCSSMatrix')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
@Native("WebKitCSSMatrix")
abstract class _WebKitCSSMatrix extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _WebKitCSSMatrix._() {
    throw new UnsupportedError("Not supported");
  }

  @DomName('WebKitCSSMatrix.WebKitCSSMatrix')
  @DocsEditable()
  factory _WebKitCSSMatrix([String cssValue]) {
    if (cssValue != null) {
      return _WebKitCSSMatrix._create_1(cssValue);
    }
    return _WebKitCSSMatrix._create_2();
  }
  static _WebKitCSSMatrix _create_1(cssValue) =>
      JS('_WebKitCSSMatrix', 'new WebKitCSSMatrix(#)', cssValue);
  static _WebKitCSSMatrix _create_2() =>
      JS('_WebKitCSSMatrix', 'new WebKitCSSMatrix()');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('WindowTimers')
@Experimental() // untriaged
abstract class _WindowTimers extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _WindowTimers._() {
    throw new UnsupportedError("Not supported");
  }

  int _setInterval_String(String handler, [int timeout, Object arguments]);

  int _setTimeout_String(String handler, [int timeout, Object arguments]);

  void _clearInterval([int handle]);

  void _clearTimeout([int handle]);

  int _setInterval(Object handler, [int timeout]);

  int _setTimeout(Object handler, [int timeout]);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('WorkerLocation')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#workerlocation
@Experimental()
@Native("WorkerLocation")
abstract class _WorkerLocation extends Interceptor implements UrlUtilsReadOnly {
  // To suppress missing implicit constructor warnings.
  factory _WorkerLocation._() {
    throw new UnsupportedError("Not supported");
  }

  // From URLUtilsReadOnly

}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('WorkerNavigator')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#workernavigator
@Experimental()
@Native("WorkerNavigator")
abstract class _WorkerNavigator extends Interceptor
    implements NavigatorCpu, NavigatorOnLine, NavigatorID {
  // To suppress missing implicit constructor warnings.
  factory _WorkerNavigator._() {
    throw new UnsupportedError("Not supported");
  }

  // From NavigatorCPU

  // From NavigatorID

  // From NavigatorOnLine

}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

@DocsEditable()
@DomName('Worklet')
@Experimental() // untriaged
@Native("Worklet")
abstract class _Worklet extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _Worklet._() {
    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('WorkletGlobalScope')
@Experimental() // untriaged
@Native("WorkletGlobalScope")
abstract class _WorkletGlobalScope extends Interceptor {
  // To suppress missing implicit constructor warnings.
  factory _WorkletGlobalScope._() {
    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(Object 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 = <String>[];
    for (int i = 0, len = attributes.length; i < len; i++) {
      _Attr attr = attributes[i];
      if (_matches(attr)) {
        keys.add(attr.name);
      }
    }
    return keys;
  }

  Iterable<String> get values {
    // TODO: generate a lazy collection instead.
    var attributes = _element._attributes;
    var values = <String>[];
    for (int i = 0, len = attributes.length; i < len; i++) {
      _Attr attr = attributes[i];
      if (_matches(attr)) {
        values.add(attr.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(_Attr node);
}

/**
 * Wrapper to expose [Element.attributes] as a typed map.
 */
class _ElementAttributeMap extends _AttributeMap {
  _ElementAttributeMap(Element element) : super(element);

  bool containsKey(Object key) {
    return _element._hasAttribute(key);
  }

  String operator [](Object key) {
    return _element.getAttribute(key);
  }

  void operator []=(String key, String value) {
    _element.setAttribute(key, value);
  }

  String remove(Object 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(_Attr 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(Object key) {
    return _element._hasAttributeNS(_namespace, key);
  }

  String operator [](Object key) {
    return _element.getAttributeNS(_namespace, key);
  }

  void operator []=(String key, String value) {
    _element.setAttributeNS(_namespace, key, value);
  }

  String remove(Object 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(_Attr 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(Object value) => values.any((v) => v == value);

  bool containsKey(Object key) => _attributes.containsKey(_attr(key));

  String operator [](Object 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(Object 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 = <String>[];
    _attributes.forEach((String key, String value) {
      if (_matches(key)) {
        keys.add(_strip(key));
      }
    });
    return keys;
  }

  Iterable<String> get values {
    final values = <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](https://html.spec.whatwg.org/multipage/scripting.html#image-sources-for-2d-rendering-contexts)
 *   from WHATWG.
 * * [Drawing images](https://html.spec.whatwg.org/multipage/scripting.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](https://html.spec.whatwg.org/multipage/browsers.html#history)
   *   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](https://html.spec.whatwg.org/multipage/comms.html#web-messaging)
   *   from WHATWG.
   */
  void postMessage(var message, String targetOrigin,
      [List<MessagePort> messagePorts]);
}

abstract class LocationBase {
  void set href(String val);
}

abstract class HistoryBase {
  void back();
  void forward();
  void go(int distance);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/** A Set that stores the CSS class names for an element. */
abstract class CssClassSet implements Set<String> {
  /**
   * Adds the class [value] to the element if it is not on it, removes it if it
   * is.
   *
   * If [shouldAdd] is true, then we always add that [value] to the element. If
   * [shouldAdd] is false then we always remove [value] from the element.
   *
   * If this corresponds to one element, returns `true` if [value] is present
   * after the operation, and returns `false` if [value] is absent after the
   * operation.
   *
   * If this corresponds to many elements, `null` is always returned.
   *
   * [value] must be a valid 'token' representing a single class, i.e. a
   * non-empty string containing no whitespace.  To toggle multiple classes, use
   * [toggleAll].
   */
  bool toggle(String value, [bool shouldAdd]);

  /**
   * Returns [:true:] if classes cannot be added or removed from this
   * [:CssClassSet:].
   */
  bool get frozen;

  /**
   * Determine if this element contains the class [value].
   *
   * This is the Dart equivalent of jQuery's
   * [hasClass](http://api.jquery.com/hasClass/).
   *
   * [value] must be a valid 'token' representing a single class, i.e. a
   * non-empty string containing no whitespace.
   */
  bool contains(Object value);

  /**
   * Add the class [value] to element.
   *
   * [add] and [addAll] are the Dart equivalent of jQuery's
   * [addClass](http://api.jquery.com/addClass/).
   *
   * If this CssClassSet corresponds to one element. Returns true if [value] was
   * added to the set, otherwise false.
   *
   * If this corresponds to many elements, `null` is always returned.
   *
   * [value] must be a valid 'token' representing a single class, i.e. a
   * non-empty string containing no whitespace.  To add multiple classes use
   * [addAll].
   */
  bool add(String value);

  /**
   * Remove the class [value] from element, and return true on successful
   * removal.
   *
   * [remove] and [removeAll] are the Dart equivalent of jQuery's
   * [removeClass](http://api.jquery.com/removeClass/).
   *
   * [value] must be a valid 'token' representing a single class, i.e. a
   * non-empty string containing no whitespace.  To remove multiple classes, use
   * [removeAll].
   */
  bool remove(Object value);

  /**
   * Add all classes specified in [iterable] to element.
   *
   * [add] and [addAll] are the Dart equivalent of jQuery's
   * [addClass](http://api.jquery.com/addClass/).
   *
   * Each element of [iterable] must be a valid 'token' representing a single
   * class, i.e. a non-empty string containing no whitespace.
   */
  void addAll(Iterable<String> iterable);

  /**
   * Remove all classes specified in [iterable] from element.
   *
   * [remove] and [removeAll] are the Dart equivalent of jQuery's
   * [removeClass](http://api.jquery.com/removeClass/).
   *
   * Each element of [iterable] must be a valid 'token' representing a single
   * class, i.e. a non-empty string containing no whitespace.
   */
  void removeAll(Iterable<Object> iterable);

  /**
   * Toggles all classes specified in [iterable] on element.
   *
   * Iterate through [iterable]'s items, and add it if it is not on it, or
   * remove it if it is. This is the Dart equivalent of jQuery's
   * [toggleClass](http://api.jquery.com/toggleClass/).
   * If [shouldAdd] is true, then we always add all the classes in [iterable]
   * element. If [shouldAdd] is false then we always remove all the classes in
   * [iterable] from the element.
   *
   * Each element of [iterable] must be a valid 'token' representing a single
   * class, i.e. a non-empty string containing no whitespace.
   */
  void toggleAll(Iterable<String> iterable, [bool shouldAdd]);
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * A rectangle representing all the content of the element in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _ContentCssRect extends CssRect {
  _ContentCssRect(Element element) : super(element);

  num get height =>
      _element.offsetHeight + _addOrSubtractToBoxModel(_HEIGHT, _CONTENT);

  num get width =>
      _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _CONTENT);

  /**
   * Set the height to `newHeight`.
   *
   * newHeight can be either a [num] representing the height in pixels or a
   * [Dimension] object. Values of newHeight that are less than zero are
   * converted to effectively setting the height to 0. This is equivalent to the
   * `height` function in jQuery and the calculated `height` CSS value,
   * converted to a num in pixels.
   */
  set height(dynamic newHeight) {
    if (newHeight is Dimension) {
      if (newHeight.value < 0) newHeight = new Dimension.px(0);
      _element.style.height = newHeight.toString();
    } else if (newHeight is num) {
      if (newHeight < 0) newHeight = 0;
      _element.style.height = '${newHeight}px';
    } else {
      throw new ArgumentError("newHeight is not a Dimension or num");
    }
  }

  /**
   * Set the current computed width in pixels of this element.
   *
   * newWidth can be either a [num] representing the width in pixels or a
   * [Dimension] object. This is equivalent to the `width` function in jQuery
   * and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels.
   */
  set width(dynamic newWidth) {
    if (newWidth is Dimension) {
      if (newWidth.value < 0) newWidth = new Dimension.px(0);
      _element.style.width = newWidth.toString();
    } else if (newWidth is num) {
      if (newWidth < 0) newWidth = 0;
      _element.style.width = '${newWidth}px';
    } else {
      throw new ArgumentError("newWidth is not a Dimension or num");
    }
  }

  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(List<Element> elementList) : super(elementList.first) {
    _elementList = elementList;
  }

  /**
   * Set the height to `newHeight`.
   *
   * Values of newHeight that are less than zero are converted to effectively
   * setting the height to 0. This is equivalent to the `height`
   * function in jQuery and the calculated `height` CSS value, converted to a
   * num in pixels.
   */
  set height(newHeight) {
    _elementList.forEach((e) => e.contentEdge.height = newHeight);
  }

  /**
   * Set the current computed width in pixels of this element.
   *
   * This is equivalent to the `width` function in jQuery and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels.
   */
  set width(newWidth) {
    _elementList.forEach((e) => e.contentEdge.width = newWidth);
  }
}

/**
 * A rectangle representing the dimensions of the space occupied by the
 * element's content + padding in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _PaddingCssRect extends CssRect {
  _PaddingCssRect(element) : super(element);
  num get height =>
      _element.offsetHeight + _addOrSubtractToBoxModel(_HEIGHT, _PADDING);
  num get width =>
      _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _PADDING);

  num get left =>
      _element.getBoundingClientRect().left -
      _addOrSubtractToBoxModel(['left'], _PADDING);
  num get top =>
      _element.getBoundingClientRect().top -
      _addOrSubtractToBoxModel(['top'], _PADDING);
}

/**
 * A rectangle representing the dimensions of the space occupied by the
 * element's content + padding + border in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _BorderCssRect extends CssRect {
  _BorderCssRect(element) : super(element);
  num get height => _element.offsetHeight;
  num get width => _element.offsetWidth;

  num get left => _element.getBoundingClientRect().left;
  num get top => _element.getBoundingClientRect().top;
}

/**
 * A rectangle representing the dimensions of the space occupied by the
 * element's content + padding + border + margin in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _MarginCssRect extends CssRect {
  _MarginCssRect(element) : super(element);
  num get height =>
      _element.offsetHeight + _addOrSubtractToBoxModel(_HEIGHT, _MARGIN);
  num get width =>
      _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _MARGIN);

  num get left =>
      _element.getBoundingClientRect().left -
      _addOrSubtractToBoxModel(['left'], _MARGIN);
  num get top =>
      _element.getBoundingClientRect().top -
      _addOrSubtractToBoxModel(['top'], _MARGIN);
}

/**
 * A class for representing CSS dimensions.
 *
 * In contrast to the more general purpose [Rectangle] class, this class's
 * values are mutable, so one can change the height of an element
 * programmatically.
 *
 * _Important_ _note_: use of these methods will perform CSS calculations that
 * can trigger a browser reflow. Therefore, use of these properties _during_ an
 * animation frame is discouraged. See also:
 * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
 */
abstract class CssRect implements Rectangle<num> {
  Element _element;

  CssRect(this._element);

  num get left;

  num get top;

  /**
   * The height of this rectangle.
   *
   * This is equivalent to the `height` function in jQuery and the calculated
   * `height` CSS value, converted to a dimensionless num in pixels. Unlike
   * [getBoundingClientRect], `height` will return the same numerical width if
   * the element is hidden or not.
   */
  num get height;

  /**
   * The width of this rectangle.
   *
   * This is equivalent to the `width` function in jQuery and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels. Unlike
   * [getBoundingClientRect], `width` will return the same numerical width if
   * the element is hidden or not.
   */
  num get width;

  /**
   * Set the height to `newHeight`.
   *
   * newHeight can be either a [num] representing the height in pixels or a
   * [Dimension] object. Values of newHeight that are less than zero are
   * converted to effectively setting the height to 0. This is equivalent to the
   * `height` function in jQuery and the calculated `height` CSS value,
   * converted to a num in pixels.
   *
   * Note that only the content height can actually be set via this method.
   */
  set height(dynamic newHeight) {
    throw new UnsupportedError("Can only set height for content rect.");
  }

  /**
   * Set the current computed width in pixels of this element.
   *
   * newWidth can be either a [num] representing the width in pixels or a
   * [Dimension] object. This is equivalent to the `width` function in jQuery
   * and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels.
   *
   * Note that only the content width can be set via this method.
   */
  set width(dynamic 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;
  }

  // TODO(jacobr): these methods are duplicated from _RectangleBase in dart:math
  // Ideally we would provide a RectangleMixin class that provides this implementation.
  // In an ideal world we would exp
  /** The x-coordinate of the right edge. */
  num get right => left + width;
  /** The y-coordinate of the bottom edge. */
  num get bottom => top + height;

  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 &&
        right == other.right &&
        bottom == other.bottom;
  }

  int get hashCode => _JenkinsSmiHash.hash4(
      left.hashCode, top.hashCode, right.hashCode, bottom.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<num> intersection(Rectangle<num> 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<num>(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<num> boundingBox(Rectangle<num> 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<num>(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<num> get topLeft => new Point<num>(this.left, this.top);
  Point<num> get topRight => new Point<num>(this.left + this.width, this.top);
  Point<num> get bottomRight =>
      new Point<num>(this.left + this.width, this.top + this.height);
  Point<num> get bottomLeft =>
      new Point<num>(this.left, this.top + this.height);
}

final _HEIGHT = ['top', 'bottom'];
final _WIDTH = ['right', 'left'];
final _CONTENT = 'content';
final _PADDING = 'padding';
final _MARGIN = 'margin';
// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * A set (union) of the CSS classes that are present in a set of elements.
 * Implemented separately from _ElementCssClassSet for performance.
 */
class _MultiElementCssClassSet extends CssClassSetImpl {
  final Iterable<Element> _elementIterable;

  // TODO(sra): Perhaps we should store the DomTokenList instead.
  final List<CssClassSetImpl> _sets;

  factory _MultiElementCssClassSet(Iterable<Element> elements) {
    return new _MultiElementCssClassSet._(
        elements, elements.map((Element e) => e.classes).toList());
  }

  _MultiElementCssClassSet._(this._elementIterable, this._sets);

  Set<String> readClasses() {
    var s = new LinkedHashSet<String>();
    _sets.forEach((CssClassSetImpl e) => s.addAll(e.readClasses()));
    return s;
  }

  void writeClasses(Set<String> s) {
    var classes = s.join(' ');
    for (Element e in _elementIterable) {
      e.className = classes;
    }
  }

  /**
   * Helper method used to modify the set of css classes on this element.
   *
   *   f - callback with:
   *   s - a Set of all the css class name currently on this element.
   *
   *   After f returns, the modified set is written to the
   *       className property of this element.
   */
  modify(f(Set<String> s)) {
    _sets.forEach((CssClassSetImpl e) => e.modify(f));
  }

  /**
   * Adds the class [value] to the element if it is not on it, removes it if it
   * is.
   *
   * TODO(sra): It seems wrong to collect a 'changed' flag like this when the
   * underlying toggle returns an 'is set' flag.
   */
  bool toggle(String value, [bool shouldAdd]) => _sets.fold(
      false,
      (bool changed, CssClassSetImpl e) =>
          e.toggle(value, shouldAdd) || changed);

  /**
   * Remove the class [value] from element, and return true on successful
   * removal.
   *
   * This is the Dart equivalent of jQuery's
   * [removeClass](http://api.jquery.com/removeClass/).
   */
  bool remove(Object value) => _sets.fold(
      false, (bool changed, CssClassSetImpl e) => e.remove(value) || changed);
}

class _ElementCssClassSet extends CssClassSetImpl {
  final Element _element;

  _ElementCssClassSet(this._element);

  Set<String> readClasses() {
    var s = new LinkedHashSet<String>();
    var classname = _element.className;

    for (String name in classname.split(' ')) {
      String trimmed = name.trim();
      if (!trimmed.isEmpty) {
        s.add(trimmed);
      }
    }
    return s;
  }

  void writeClasses(Set<String> s) {
    _element.className = s.join(' ');
  }

  int get length => _classListLength(_classListOf(_element));
  bool get isEmpty => length == 0;
  bool get isNotEmpty => length != 0;

  void clear() {
    _element.className = '';
  }

  bool contains(Object value) {
    return _contains(_element, value);
  }

  bool add(String value) {
    return _add(_element, value);
  }

  bool remove(Object value) {
    return value is String && _remove(_element, value);
  }

  bool toggle(String value, [bool shouldAdd]) {
    return _toggle(_element, value, shouldAdd);
  }

  void addAll(Iterable<String> iterable) {
    _addAll(_element, iterable);
  }

  void removeAll(Iterable<Object> iterable) {
    _removeAll(_element, iterable);
  }

  void retainAll(Iterable<Object> iterable) {
    _removeWhere(_element, iterable.toSet().contains, false);
  }

  void removeWhere(bool test(String name)) {
    _removeWhere(_element, test, true);
  }

  void retainWhere(bool test(String name)) {
    _removeWhere(_element, test, false);
  }

  static bool _contains(Element _element, Object value) {
    return value is String && _classListContains(_classListOf(_element), value);
  }

  @ForceInline()
  static bool _add(Element _element, String value) {
    DomTokenList list = _classListOf(_element);
    // Compute returned result independently of action upon the set.
    bool added = !_classListContainsBeforeAddOrRemove(list, value);
    _classListAdd(list, value);
    return added;
  }

  @ForceInline()
  static bool _remove(Element _element, String value) {
    DomTokenList list = _classListOf(_element);
    bool removed = _classListContainsBeforeAddOrRemove(list, value);
    _classListRemove(list, value);
    return removed;
  }

  static bool _toggle(Element _element, String value, bool shouldAdd) {
    // There is no value that can be passed as the second argument of
    // DomTokenList.toggle that behaves the same as passing one argument.
    // `null` is seen as false, meaning 'remove'.
    return shouldAdd == null
        ? _toggleDefault(_element, value)
        : _toggleOnOff(_element, value, shouldAdd);
  }

  static bool _toggleDefault(Element _element, String value) {
    DomTokenList list = _classListOf(_element);
    return _classListToggle1(list, value);
  }

  static bool _toggleOnOff(Element _element, String value, bool shouldAdd) {
    DomTokenList list = _classListOf(_element);
    // IE's toggle does not take a second parameter. We would prefer:
    //
    //    return _classListToggle2(list, value, shouldAdd);
    //
    if (shouldAdd) {
      _classListAdd(list, value);
      return true;
    } else {
      _classListRemove(list, value);
      return false;
    }
  }

  static void _addAll(Element _element, Iterable<String> iterable) {
    DomTokenList list = _classListOf(_element);
    for (String value in iterable) {
      _classListAdd(list, value);
    }
  }

  static void _removeAll(Element _element, Iterable<String> iterable) {
    DomTokenList list = _classListOf(_element);
    for (var value in iterable) {
      _classListRemove(list, value);
    }
  }

  static void _removeWhere(
      Element _element, bool test(String name), bool doRemove) {
    DomTokenList list = _classListOf(_element);
    int i = 0;
    while (i < _classListLength(list)) {
      String item = list.item(i);
      if (doRemove == test(item)) {
        _classListRemove(list, item);
      } else {
        ++i;
      }
    }
  }

  // A collection of static methods for DomTokenList. These methods are a
  // work-around for the lack of annotations to express the full behaviour of
  // the DomTokenList methods.

  static DomTokenList _classListOf(Element e) => JS(
      'returns:DomTokenList;creates:DomTokenList;effects:none;depends:all;',
      '#.classList',
      e);

  static int _classListLength(DomTokenList list) =>
      JS('returns:JSUInt31;effects:none;depends:all;', '#.length', list);

  static bool _classListContains(DomTokenList list, String value) =>
      JS('returns:bool;effects:none;depends:all', '#.contains(#)', list, value);

  static bool _classListContainsBeforeAddOrRemove(
          DomTokenList list, String value) =>
      // 'throws:never' is a lie, since 'contains' will throw on an illegal
      // token.  However, we always call this function immediately prior to
      // add/remove/toggle with the same token.  Often the result of 'contains'
      // is unused and the lie makes it possible for the 'contains' instruction
      // to be removed.
      JS('returns:bool;effects:none;depends:all;throws:null(1)',
          '#.contains(#)', list, value);

  static void _classListAdd(DomTokenList list, String value) {
    // list.add(value);
    JS('', '#.add(#)', list, value);
  }

  static void _classListRemove(DomTokenList list, String value) {
    // list.remove(value);
    JS('', '#.remove(#)', list, value);
  }

  static bool _classListToggle1(DomTokenList list, String value) {
    return JS('bool', '#.toggle(#)', list, value);
  }

  static bool _classListToggle2(
      DomTokenList list, String value, bool shouldAdd) {
    return JS('bool', '#.toggle(#, #)', list, value, shouldAdd);
  }
}

/**
 * Class representing a
 * [length measurement](https://developer.mozilla.org/en-US/docs/Web/CSS/length)
 * in CSS.
 */
@Experimental()
class Dimension {
  num _value;
  String _unit;

  /** Set this CSS Dimension to a percentage `value`. */
  Dimension.percent(this._value) : _unit = '%';

  /** Set this CSS Dimension to a pixel `value`. */
  Dimension.px(this._value) : _unit = 'px';

  /** Set this CSS Dimension to a pica `value`. */
  Dimension.pc(this._value) : _unit = 'pc';

  /** Set this CSS Dimension to a point `value`. */
  Dimension.pt(this._value) : _unit = 'pt';

  /** Set this CSS Dimension to an inch `value`. */
  Dimension.inch(this._value) : _unit = 'in';

  /** Set this CSS Dimension to a centimeter `value`. */
  Dimension.cm(this._value) : _unit = 'cm';

  /** Set this CSS Dimension to a millimeter `value`. */
  Dimension.mm(this._value) : _unit = 'mm';

  /**
   * Set this CSS Dimension to the specified number of ems.
   *
   * 1em is equal to the current font size. (So 2ems is equal to double the font
   * size). This is useful for producing website layouts that scale nicely with
   * the user's desired font size.
   */
  Dimension.em(this._value) : _unit = 'em';

  /**
   * Set this CSS Dimension to the specified number of x-heights.
   *
   * One ex is equal to the 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<T>(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<T>(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<T>(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<T> subscription),
          void onCancel(StreamSubscription<T> 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);
  }
}

bool _matchesWithAncestors(Event event, String selector) {
  var target = event.target;
  return target is Element ? target.matchesWithAncestors(selector) : false;
}

/**
 * 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) => _matchesWithAncestors(event, 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) => _matchesWithAncestors(event, 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<T>.broadcast();
    for (var target in _targetList) {
      pool.add(new _EventStream<T>(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<T>.broadcast();
    for (var target in _targetList) {
      pool.add(new _EventStream<T>(target, _eventType, true));
    }
    return pool.stream.listen(onData);
  }

  Stream<T> asBroadcastStream(
          {void onListen(StreamSubscription<T> subscription),
          void onCancel(StreamSubscription<T> subscription)}) =>
      this;
  bool get isBroadcast => true;
}

// We would like this to just be EventListener<T> but that typdef cannot
// use generics until dartbug/26276 is fixed.
typedef _EventListener<T extends Event>(T event);

class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> {
  int _pauseCount = 0;
  EventTarget _target;
  final String _eventType;
  EventListener _onData;
  final bool _useCapture;

  // TODO(leafp): It would be better to write this as
  // _onData = onData == null ? null :
  //   onData is _wrapZoneCallback<Event, dynamic>
  //     ? _wrapZone/*<Event, dynamic>*/(onData)
  //     : _wrapZone/*<Event, dynamic>*/((e) => onData(e as T))
  // In order to support existing tests which pass the wrong type of events but
  // use a more general listener, without causing as much slowdown for things
  // which are typed correctly.  But this currently runs afoul of restrictions
  // on is checks for compatibility with the VM.
  _EventStreamSubscription(
      this._target, this._eventType, void onData(T event), this._useCapture)
      : _onData = onData == null
            ? null
            : _wrapZone<Event, dynamic>((e) => (onData as dynamic)(e)) {
    _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/*<Event, dynamic>*/(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<E> asFuture<E>([E futureValue]) {
    // We just need a future that will never succeed or fail.
    var completer = new Completer<E>();
    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<T> subscription),
          void onCancel(StreamSubscription<T> 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<T>(e, _eventTypeGetter(e), useCapture);
  }

  ElementStream<T> forElement(Element e, {bool useCapture: false}) {
    return new _ElementEventStreamImpl<T>(e, _eventTypeGetter(e), useCapture);
  }

  ElementStream<T> _forElementList(ElementList e, {bool useCapture: false}) {
    return new _ElementListEventStreamImpl<T>(
        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::autofocus',
    'INPUT::checked',
    'INPUT::disabled',
    'INPUT::inputmode',
    'INPUT::ismap',
    'INPUT::list',
    'INPUT::max',
    'INPUT::maxlength',
    'INPUT::min',
    'INPUT::multiple',
    'INPUT::name',
    'INPUT::placeholder',
    'INPUT::readonly',
    'INPUT::required',
    'INPUT::size',
    'INPUT::step',
    'INPUT::tabindex',
    'INPUT::type',
    'INPUT::usemap',
    'INPUT::value',
    'INS::datetime',
    'KEYGEN::disabled',
    'KEYGEN::keytype',
    'KEYGEN::name',
    'LABEL::accesskey',
    'LABEL::for',
    'LEGEND::accesskey',
    'LEGEND::align',
    'LI::type',
    'LI::value',
    'LINK::sizes',
    'MAP::name',
    'MENU::compact',
    'MENU::label',
    'MENU::type',
    'METER::high',
    'METER::low',
    'METER::max',
    'METER::min',
    'METER::value',
    'OBJECT::typemustmatch',
    'OL::compact',
    'OL::reversed',
    'OL::start',
    'OL::type',
    'OPTGROUP::disabled',
    'OPTGROUP::label',
    'OPTION::disabled',
    'OPTION::label',
    'OPTION::selected',
    'OPTION::value',
    'OUTPUT::for',
    'OUTPUT::name',
    'P::align',
    'PRE::width',
    'PROGRESS::max',
    'PROGRESS::min',
    'PROGRESS::value',
    'SELECT::autocomplete',
    'SELECT::disabled',
    'SELECT::multiple',
    'SELECT::name',
    'SELECT::required',
    'SELECT::size',
    'SELECT::tabindex',
    'SOURCE::type',
    'TABLE::align',
    'TABLE::bgcolor',
    'TABLE::border',
    'TABLE::cellpadding',
    'TABLE::cellspacing',
    'TABLE::frame',
    'TABLE::rules',
    'TABLE::summary',
    'TABLE::width',
    'TBODY::align',
    'TBODY::char',
    'TBODY::charoff',
    'TBODY::valign',
    'TD::abbr',
    'TD::align',
    'TD::axis',
    'TD::bgcolor',
    'TD::char',
    'TD::charoff',
    'TD::colspan',
    'TD::headers',
    'TD::height',
    'TD::nowrap',
    'TD::rowspan',
    'TD::scope',
    'TD::valign',
    'TD::width',
    'TEXTAREA::accesskey',
    'TEXTAREA::autocomplete',
    'TEXTAREA::cols',
    'TEXTAREA::disabled',
    'TEXTAREA::inputmode',
    'TEXTAREA::name',
    'TEXTAREA::placeholder',
    'TEXTAREA::readonly',
    'TEXTAREA::required',
    'TEXTAREA::rows',
    'TEXTAREA::tabindex',
    'TEXTAREA::wrap',
    'TFOOT::align',
    'TFOOT::char',
    'TFOOT::charoff',
    'TFOOT::valign',
    'TH::abbr',
    'TH::align',
    'TH::axis',
    'TH::bgcolor',
    'TH::char',
    'TH::charoff',
    'TH::colspan',
    'TH::headers',
    'TH::height',
    'TH::nowrap',
    'TH::rowspan',
    'TH::scope',
    'TH::valign',
    'TH::width',
    'THEAD::align',
    'THEAD::char',
    'THEAD::charoff',
    'THEAD::valign',
    'TR::align',
    'TR::bgcolor',
    'TR::char',
    'TR::charoff',
    'TR::valign',
    'TRACK::default',
    'TRACK::kind',
    'TRACK::label',
    'TRACK::srclang',
    'UL::compact',
    'UL::type',
    'VIDEO::controls',
    'VIDEO::height',
    'VIDEO::loop',
    'VIDEO::mediagroup',
    'VIDEO::muted',
    'VIDEO::preload',
    'VIDEO::width',
  ];

  static const _uriAttributes = const <String>[
    'A::href',
    'AREA::href',
    'BLOCKQUOTE::cite',
    'BODY::background',
    'COMMAND::icon',
    'DEL::cite',
    'FORM::action',
    'IMG::src',
    'INPUT::src',
    'INS::cite',
    'Q::cite',
    'VIDEO::poster',
  ];

  final UriPolicy uriPolicy;

  static final Map<String, Function> _attributeValidators = {};

  /**
   * All known URI attributes will be validated against the UriPolicy, if
   * [uriPolicy] is null then a default UriPolicy will be used.
   */
  _Html5NodeValidator({UriPolicy uriPolicy})
      : uriPolicy = uriPolicy != null ? uriPolicy : new UriPolicy() {
    if (_attributeValidators.isEmpty) {
      for (var attr in _standardAttributes) {
        _attributeValidators[attr] = _standardAttributeValidator;
      }

      for (var attr in _uriAttributes) {
        _attributeValidators[attr] = _uriAttributeValidator;
      }
    }
  }

  bool allowsElement(Element element) {
    return _allowedElements.contains(Element._safeTagName(element));
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    var tagName = Element._safeTagName(element);
    var validator = _attributeValidators['$tagName::$attributeName'];
    if (validator == null) {
      validator = _attributeValidators['*::$attributeName'];
    }
    if (validator == null) {
      return false;
    }
    return validator(element, attributeName, value, this);
  }

  static bool _standardAttributeValidator(Element element, String attributeName,
      String value, _Html5NodeValidator context) {
    return true;
  }

  static bool _uriAttributeValidator(Element element, String attributeName,
      String value, _Html5NodeValidator context) {
    return context.uriPolicy.allowsUri(value);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

abstract class ImmutableListMixin<E> implements List<E> {
  // From Iterable<$E>:
  Iterator<E> get iterator {
    // Note: NodeLists are not fixed size. And most probably length shouldn't
    // be cached in both iterator _and_ forEach method. For now caching it
    // for consistency.
    return new FixedSizeListIterator<E>(this);
  }

  // From Collection<E>:
  void add(E value) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  void addAll(Iterable<E> iterable) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  // From List<E>:
  void sort([int compare(E a, E b)]) {
    throw new UnsupportedError("Cannot sort immutable List.");
  }

  void shuffle([Random random]) {
    throw new UnsupportedError("Cannot shuffle immutable List.");
  }

  void insert(int index, E element) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  void insertAll(int index, Iterable<E> iterable) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  void setAll(int index, Iterable<E> iterable) {
    throw new UnsupportedError("Cannot modify an immutable List.");
  }

  E removeAt(int pos) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  E removeLast() {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  bool remove(Object object) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  void removeWhere(bool test(E element)) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  void retainWhere(bool test(E element)) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
    throw new UnsupportedError("Cannot setRange on immutable List.");
  }

  void removeRange(int start, int end) {
    throw new UnsupportedError("Cannot removeRange on immutable List.");
  }

  void replaceRange(int start, int end, Iterable<E> iterable) {
    throw new UnsupportedError("Cannot modify an immutable List.");
  }

  void fillRange(int start, int end, [E fillValue]) {
    throw new UnsupportedError("Cannot modify an immutable List.");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Defines the keycode values for keys that are returned by
 * KeyboardEvent.keyCode.
 *
 * Important note: There is substantial divergence in how different browsers
 * handle keycodes and their variants in different locales/keyboard layouts. We
 * provide these constants to help make code processing keys more readable.
 */
abstract class KeyCode {
  // These constant names were borrowed from Closure's Keycode enumeration
  // class.
  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keycodes.js.source.html
  static const int WIN_KEY_FF_LINUX = 0;
  static const int MAC_ENTER = 3;
  static const int BACKSPACE = 8;
  static const int TAB = 9;
  /** NUM_CENTER is also NUMLOCK for FF and Safari on Mac. */
  static const int NUM_CENTER = 12;
  static const int ENTER = 13;
  static const int SHIFT = 16;
  static const int CTRL = 17;
  static const int ALT = 18;
  static const int PAUSE = 19;
  static const int CAPS_LOCK = 20;
  static const int ESC = 27;
  static const int SPACE = 32;
  static const int PAGE_UP = 33;
  static const int PAGE_DOWN = 34;
  static const int END = 35;
  static const int HOME = 36;
  static const int LEFT = 37;
  static const int UP = 38;
  static const int RIGHT = 39;
  static const int DOWN = 40;
  static const int NUM_NORTH_EAST = 33;
  static const int NUM_SOUTH_EAST = 34;
  static const int NUM_SOUTH_WEST = 35;
  static const int NUM_NORTH_WEST = 36;
  static const int NUM_WEST = 37;
  static const int NUM_NORTH = 38;
  static const int NUM_EAST = 39;
  static const int NUM_SOUTH = 40;
  static const int PRINT_SCREEN = 44;
  static const int INSERT = 45;
  static const int NUM_INSERT = 45;
  static const int DELETE = 46;
  static const int NUM_DELETE = 46;
  static const int ZERO = 48;
  static const int ONE = 49;
  static const int TWO = 50;
  static const int THREE = 51;
  static const int FOUR = 52;
  static const int FIVE = 53;
  static const int SIX = 54;
  static const int SEVEN = 55;
  static const int EIGHT = 56;
  static const int NINE = 57;
  static const int FF_SEMICOLON = 59;
  static const int FF_EQUALS = 61;
  /**
   * CAUTION: The question mark is for US-keyboard layouts. It varies
   * for other locales and keyboard layouts.
   */
  static const int QUESTION_MARK = 63;
  static const int A = 65;
  static const int B = 66;
  static const int C = 67;
  static const int D = 68;
  static const int E = 69;
  static const int F = 70;
  static const int G = 71;
  static const int H = 72;
  static const int I = 73;
  static const int J = 74;
  static const int K = 75;
  static const int L = 76;
  static const int M = 77;
  static const int N = 78;
  static const int O = 79;
  static const int P = 80;
  static const int Q = 81;
  static const int R = 82;
  static const int S = 83;
  static const int T = 84;
  static const int U = 85;
  static const int V = 86;
  static const int W = 87;
  static const int X = 88;
  static const int Y = 89;
  static const int Z = 90;
  static const int META = 91;
  static const int WIN_KEY_LEFT = 91;
  static const int WIN_KEY_RIGHT = 92;
  static const int CONTEXT_MENU = 93;
  static const int NUM_ZERO = 96;
  static const int NUM_ONE = 97;
  static const int NUM_TWO = 98;
  static const int NUM_THREE = 99;
  static const int NUM_FOUR = 100;
  static const int NUM_FIVE = 101;
  static const int NUM_SIX = 102;
  static const int NUM_SEVEN = 103;
  static const int NUM_EIGHT = 104;
  static const int NUM_NINE = 105;
  static const int NUM_MULTIPLY = 106;
  static const int NUM_PLUS = 107;
  static const int NUM_MINUS = 109;
  static const int NUM_PERIOD = 110;
  static const int NUM_DIVISION = 111;
  static const int F1 = 112;
  static const int F2 = 113;
  static const int F3 = 114;
  static const int F4 = 115;
  static const int F5 = 116;
  static const int F6 = 117;
  static const int F7 = 118;
  static const int F8 = 119;
  static const int F9 = 120;
  static const int F10 = 121;
  static const int F11 = 122;
  static const int F12 = 123;
  static const int NUMLOCK = 144;
  static const int SCROLL_LOCK = 145;

  // OS-specific media keys like volume controls and browser controls.
  static const int FIRST_MEDIA_KEY = 166;
  static const int LAST_MEDIA_KEY = 183;

  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int SEMICOLON = 186;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int DASH = 189;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int EQUALS = 187;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int COMMA = 188;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int PERIOD = 190;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int SLASH = 191;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int APOSTROPHE = 192;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int TILDE = 192;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int SINGLE_QUOTE = 222;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int OPEN_SQUARE_BRACKET = 219;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int BACKSLASH = 220;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int CLOSE_SQUARE_BRACKET = 221;
  static const int WIN_KEY = 224;
  static const int MAC_FF_META = 224;
  static const int WIN_IME = 229;

  /** A sentinel value if the keycode could not be determined. */
  static const int UNKNOWN = -1;

  /**
   * Returns true if the keyCode produces a (US keyboard) character.
   * Note: This does not (yet) cover characters on non-US keyboards (Russian,
   * Hebrew, etc.).
   */
  static bool isCharacterKey(int keyCode) {
    if ((keyCode >= ZERO && keyCode <= NINE) ||
        (keyCode >= NUM_ZERO && keyCode <= NUM_MULTIPLY) ||
        (keyCode >= A && keyCode <= Z)) {
      return true;
    }

    // Safari sends zero key code for non-latin characters.
    if (Device.isWebKit && keyCode == 0) {
      return true;
    }

    return (keyCode == SPACE ||
        keyCode == QUESTION_MARK ||
        keyCode == NUM_PLUS ||
        keyCode == NUM_MINUS ||
        keyCode == NUM_PERIOD ||
        keyCode == NUM_DIVISION ||
        keyCode == SEMICOLON ||
        keyCode == FF_SEMICOLON ||
        keyCode == DASH ||
        keyCode == EQUALS ||
        keyCode == FF_EQUALS ||
        keyCode == COMMA ||
        keyCode == PERIOD ||
        keyCode == SLASH ||
        keyCode == APOSTROPHE ||
        keyCode == SINGLE_QUOTE ||
        keyCode == OPEN_SQUARE_BRACKET ||
        keyCode == BACKSLASH ||
        keyCode == CLOSE_SQUARE_BRACKET);
  }

  /**
   * Experimental helper function for converting keyCodes to keyNames for the
   * keyIdentifier attribute still used in browsers not updated with current
   * spec. This is an imperfect conversion! It will need to be refined, but
   * hopefully it can just completely go away once all the browsers update to
   * follow the DOM3 spec.
   */
  static String _convertKeyCodeToKeyName(int keyCode) {
    switch (keyCode) {
      case KeyCode.ALT:
        return _KeyName.ALT;
      case KeyCode.BACKSPACE:
        return _KeyName.BACKSPACE;
      case KeyCode.CAPS_LOCK:
        return _KeyName.CAPS_LOCK;
      case KeyCode.CTRL:
        return _KeyName.CONTROL;
      case KeyCode.DELETE:
        return _KeyName.DEL;
      case KeyCode.DOWN:
        return _KeyName.DOWN;
      case KeyCode.END:
        return _KeyName.END;
      case KeyCode.ENTER:
        return _KeyName.ENTER;
      case KeyCode.ESC:
        return _KeyName.ESC;
      case KeyCode.F1:
        return _KeyName.F1;
      case KeyCode.F2:
        return _KeyName.F2;
      case KeyCode.F3:
        return _KeyName.F3;
      case KeyCode.F4:
        return _KeyName.F4;
      case KeyCode.F5:
        return _KeyName.F5;
      case KeyCode.F6:
        return _KeyName.F6;
      case KeyCode.F7:
        return _KeyName.F7;
      case KeyCode.F8:
        return _KeyName.F8;
      case KeyCode.F9:
        return _KeyName.F9;
      case KeyCode.F10:
        return _KeyName.F10;
      case KeyCode.F11:
        return _KeyName.F11;
      case KeyCode.F12:
        return _KeyName.F12;
      case KeyCode.HOME:
        return _KeyName.HOME;
      case KeyCode.INSERT:
        return _KeyName.INSERT;
      case KeyCode.LEFT:
        return _KeyName.LEFT;
      case KeyCode.META:
        return _KeyName.META;
      case KeyCode.NUMLOCK:
        return _KeyName.NUM_LOCK;
      case KeyCode.PAGE_DOWN:
        return _KeyName.PAGE_DOWN;
      case KeyCode.PAGE_UP:
        return _KeyName.PAGE_UP;
      case KeyCode.PAUSE:
        return _KeyName.PAUSE;
      case KeyCode.PRINT_SCREEN:
        return _KeyName.PRINT_SCREEN;
      case KeyCode.RIGHT:
        return _KeyName.RIGHT;
      case KeyCode.SCROLL_LOCK:
        return _KeyName.SCROLL;
      case KeyCode.SHIFT:
        return _KeyName.SHIFT;
      case KeyCode.SPACE:
        return _KeyName.SPACEBAR;
      case KeyCode.TAB:
        return _KeyName.TAB;
      case KeyCode.UP:
        return _KeyName.UP;
      case KeyCode.WIN_IME:
      case KeyCode.WIN_KEY:
      case KeyCode.WIN_KEY_LEFT:
      case KeyCode.WIN_KEY_RIGHT:
        return _KeyName.WIN;
      default:
        return _KeyName.UNIDENTIFIED;
    }
    return _KeyName.UNIDENTIFIED;
  }
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Defines the standard key locations returned by
 * KeyboardEvent.getKeyLocation.
 */
abstract class KeyLocation {
  /**
   * The event key is not distinguished as the left or right version
   * of the key, and did not originate from the numeric keypad (or did not
   * originate with a virtual key corresponding to the numeric keypad).
   */
  static const int STANDARD = 0;

  /**
   * The event key is in the left key location.
   */
  static const int LEFT = 1;

  /**
   * The event key is in the right key location.
   */
  static const int RIGHT = 2;

  /**
   * The event key originated on the numeric keypad or with a virtual key
   * corresponding to the numeric keypad.
   */
  static const int NUMPAD = 3;

  /**
   * The event key originated on a mobile device, either on a physical
   * keypad or a virtual keyboard.
   */
  static const int MOBILE = 4;

  /**
   * The event key originated on a game controller or a joystick on a mobile
   * device.
   */
  static const int JOYSTICK = 5;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Defines the standard keyboard identifier names for keys that are returned
 * by KeyboardEvent.getKeyboardIdentifier when the key does not have a direct
 * unicode mapping.
 */
abstract class _KeyName {
  /** The Accept (Commit, OK) key */
  static const String ACCEPT = "Accept";

  /** The Add key */
  static const String ADD = "Add";

  /** The Again key */
  static const String AGAIN = "Again";

  /** The All Candidates key */
  static const String ALL_CANDIDATES = "AllCandidates";

  /** The Alphanumeric key */
  static const String ALPHANUMERIC = "Alphanumeric";

  /** The Alt (Menu) key */
  static const String ALT = "Alt";

  /** The Alt-Graph key */
  static const String ALT_GRAPH = "AltGraph";

  /** The Application key */
  static const String APPS = "Apps";

  /** The ATTN key */
  static const String ATTN = "Attn";

  /** The Browser Back key */
  static const String BROWSER_BACK = "BrowserBack";

  /** The Browser Favorites key */
  static const String BROWSER_FAVORTIES = "BrowserFavorites";

  /** The Browser Forward key */
  static const String BROWSER_FORWARD = "BrowserForward";

  /** The Browser Home key */
  static const String BROWSER_NAME = "BrowserHome";

  /** The Browser Refresh key */
  static const String BROWSER_REFRESH = "BrowserRefresh";

  /** The Browser Search key */
  static const String BROWSER_SEARCH = "BrowserSearch";

  /** The Browser Stop key */
  static const String BROWSER_STOP = "BrowserStop";

  /** The Camera key */
  static const String CAMERA = "Camera";

  /** The Caps Lock (Capital) key */
  static const String CAPS_LOCK = "CapsLock";

  /** The Clear key */
  static const String CLEAR = "Clear";

  /** The Code Input key */
  static const String CODE_INPUT = "CodeInput";

  /** The Compose key */
  static const String COMPOSE = "Compose";

  /** The Control (Ctrl) key */
  static const String CONTROL = "Control";

  /** The Crsel key */
  static const String CRSEL = "Crsel";

  /** The Convert key */
  static const String CONVERT = "Convert";

  /** The Copy key */
  static const String COPY = "Copy";

  /** The Cut key */
  static const String CUT = "Cut";

  /** The Decimal key */
  static const String DECIMAL = "Decimal";

  /** The Divide key */
  static const String DIVIDE = "Divide";

  /** The Down Arrow key */
  static const String DOWN = "Down";

  /** The diagonal Down-Left Arrow key */
  static const String DOWN_LEFT = "DownLeft";

  /** The diagonal Down-Right Arrow key */
  static const String DOWN_RIGHT = "DownRight";

  /** The Eject key */
  static const String EJECT = "Eject";

  /** The End key */
  static const String END = "End";

  /**
   * The Enter key. Note: This key value must also be used for the Return
   *  (Macintosh numpad) key
   */
  static const String ENTER = "Enter";

  /** The Erase EOF key */
  static const String ERASE_EOF = "EraseEof";

  /** The Execute key */
  static const String EXECUTE = "Execute";

  /** The Exsel key */
  static const String EXSEL = "Exsel";

  /** The Function switch key */
  static const String FN = "Fn";

  /** The F1 key */
  static const String F1 = "F1";

  /** The F2 key */
  static const String F2 = "F2";

  /** The F3 key */
  static const String F3 = "F3";

  /** The F4 key */
  static const String F4 = "F4";

  /** The F5 key */
  static const String F5 = "F5";

  /** The F6 key */
  static const String F6 = "F6";

  /** The F7 key */
  static const String F7 = "F7";

  /** The F8 key */
  static const String F8 = "F8";

  /** The F9 key */
  static const String F9 = "F9";

  /** The F10 key */
  static const String F10 = "F10";

  /** The F11 key */
  static const String F11 = "F11";

  /** The F12 key */
  static const String F12 = "F12";

  /** The F13 key */
  static const String F13 = "F13";

  /** The F14 key */
  static const String F14 = "F14";

  /** The F15 key */
  static const String F15 = "F15";

  /** The F16 key */
  static const String F16 = "F16";

  /** The F17 key */
  static const String F17 = "F17";

  /** The F18 key */
  static const String F18 = "F18";

  /** The F19 key */
  static const String F19 = "F19";

  /** The F20 key */
  static const String F20 = "F20";

  /** The F21 key */
  static const String F21 = "F21";

  /** The F22 key */
  static const String F22 = "F22";

  /** The F23 key */
  static const String F23 = "F23";

  /** The F24 key */
  static const String F24 = "F24";

  /** The Final Mode (Final) key used on some asian keyboards */
  static const String FINAL_MODE = "FinalMode";

  /** The Find key */
  static const String FIND = "Find";

  /** The Full-Width Characters key */
  static const String FULL_WIDTH = "FullWidth";

  /** The Half-Width Characters key */
  static const String HALF_WIDTH = "HalfWidth";

  /** The Hangul (Korean characters) Mode key */
  static const String HANGUL_MODE = "HangulMode";

  /** The Hanja (Korean characters) Mode key */
  static const String HANJA_MODE = "HanjaMode";

  /** The Help key */
  static const String HELP = "Help";

  /** The Hiragana (Japanese Kana characters) key */
  static const String HIRAGANA = "Hiragana";

  /** The Home key */
  static const String HOME = "Home";

  /** The Insert (Ins) key */
  static const String INSERT = "Insert";

  /** The Japanese-Hiragana key */
  static const String JAPANESE_HIRAGANA = "JapaneseHiragana";

  /** The Japanese-Katakana key */
  static const String JAPANESE_KATAKANA = "JapaneseKatakana";

  /** The Japanese-Romaji key */
  static const String JAPANESE_ROMAJI = "JapaneseRomaji";

  /** The Junja Mode key */
  static const String JUNJA_MODE = "JunjaMode";

  /** The Kana Mode (Kana Lock) key */
  static const String KANA_MODE = "KanaMode";

  /**
   * The Kanji (Japanese name for ideographic characters of Chinese origin)
   * Mode key
   */
  static const String KANJI_MODE = "KanjiMode";

  /** The Katakana (Japanese Kana characters) key */
  static const String KATAKANA = "Katakana";

  /** The Start Application One key */
  static const String LAUNCH_APPLICATION_1 = "LaunchApplication1";

  /** The Start Application Two key */
  static const String LAUNCH_APPLICATION_2 = "LaunchApplication2";

  /** The Start Mail key */
  static const String LAUNCH_MAIL = "LaunchMail";

  /** The Left Arrow key */
  static const String LEFT = "Left";

  /** The Menu key */
  static const String MENU = "Menu";

  /**
   * The Meta key. Note: This key value shall be also used for the Apple
   * Command key
   */
  static const String META = "Meta";

  /** The Media Next Track key */
  static const String MEDIA_NEXT_TRACK = "MediaNextTrack";

  /** The Media Play Pause key */
  static const String MEDIA_PAUSE_PLAY = "MediaPlayPause";

  /** The Media Previous Track key */
  static const String MEDIA_PREVIOUS_TRACK = "MediaPreviousTrack";

  /** The Media Stop key */
  static const String MEDIA_STOP = "MediaStop";

  /** The Mode Change key */
  static const String MODE_CHANGE = "ModeChange";

  /** The Next Candidate function key */
  static const String NEXT_CANDIDATE = "NextCandidate";

  /** The Nonconvert (Don't Convert) key */
  static const String NON_CONVERT = "Nonconvert";

  /** The Number Lock key */
  static const String NUM_LOCK = "NumLock";

  /** The Page Down (Next) key */
  static const String PAGE_DOWN = "PageDown";

  /** The Page Up key */
  static const String PAGE_UP = "PageUp";

  /** The Paste key */
  static const String PASTE = "Paste";

  /** The Pause key */
  static const String PAUSE = "Pause";

  /** The Play key */
  static const String PLAY = "Play";

  /**
   * The Power key. Note: Some devices may not expose this key to the
   * operating environment
   */
  static const String POWER = "Power";

  /** The Previous Candidate function key */
  static const String PREVIOUS_CANDIDATE = "PreviousCandidate";

  /** The Print Screen (PrintScrn, SnapShot) key */
  static const String PRINT_SCREEN = "PrintScreen";

  /** The Process key */
  static const String PROCESS = "Process";

  /** The Props key */
  static const String PROPS = "Props";

  /** The Right Arrow key */
  static const String RIGHT = "Right";

  /** The Roman Characters function key */
  static const String ROMAN_CHARACTERS = "RomanCharacters";

  /** The Scroll Lock key */
  static const String SCROLL = "Scroll";

  /** The Select key */
  static const String SELECT = "Select";

  /** The Select Media key */
  static const String SELECT_MEDIA = "SelectMedia";

  /** The Separator key */
  static const String SEPARATOR = "Separator";

  /** The Shift key */
  static const String SHIFT = "Shift";

  /** The Soft1 key */
  static const String SOFT_1 = "Soft1";

  /** The Soft2 key */
  static const String SOFT_2 = "Soft2";

  /** The Soft3 key */
  static const String SOFT_3 = "Soft3";

  /** The Soft4 key */
  static const String SOFT_4 = "Soft4";

  /** The Stop key */
  static const String STOP = "Stop";

  /** The Subtract key */
  static const String SUBTRACT = "Subtract";

  /** The Symbol Lock key */
  static const String SYMBOL_LOCK = "SymbolLock";

  /** The Up Arrow key */
  static const String UP = "Up";

  /** The diagonal Up-Left Arrow key */
  static const String UP_LEFT = "UpLeft";

  /** The diagonal Up-Right Arrow key */
  static const String UP_RIGHT = "UpRight";

  /** The Undo key */
  static const String UNDO = "Undo";

  /** The Volume Down key */
  static const String VOLUME_DOWN = "VolumeDown";

  /** The Volume Mute key */
  static const String VOLUMN_MUTE = "VolumeMute";

  /** The Volume Up key */
  static const String VOLUMN_UP = "VolumeUp";

  /** The Windows Logo key */
  static const String WIN = "Win";

  /** The Zoom key */
  static const String ZOOM = "Zoom";

  /**
   * The Backspace (Back) key. Note: This key value shall be also used for the
   * key labeled 'delete' MacOS keyboards when not modified by the 'Fn' key
   */
  static const String BACKSPACE = "Backspace";

  /** The Horizontal Tabulation (Tab) key */
  static const String TAB = "Tab";

  /** The Cancel key */
  static const String CANCEL = "Cancel";

  /** The Escape (Esc) key */
  static const String ESC = "Esc";

  /** The Space (Spacebar) key:   */
  static const String SPACEBAR = "Spacebar";

  /**
   * The Delete (Del) Key. Note: This key value shall be also used for the key
   * labeled 'delete' MacOS keyboards when modified by the 'Fn' key
   */
  static const String DEL = "Del";

  /** The Combining Grave Accent (Greek Varia, Dead Grave) key */
  static const String DEAD_GRAVE = "DeadGrave";

  /**
   * The Combining Acute Accent (Stress Mark, Greek Oxia, Tonos, Dead Eacute)
   * key
   */
  static const String DEAD_EACUTE = "DeadEacute";

  /** The Combining Circumflex Accent (Hat, Dead Circumflex) key */
  static const String DEAD_CIRCUMFLEX = "DeadCircumflex";

  /** The Combining Tilde (Dead Tilde) key */
  static const String DEAD_TILDE = "DeadTilde";

  /** The Combining Macron (Long, Dead Macron) key */
  static const String DEAD_MACRON = "DeadMacron";

  /** The Combining Breve (Short, Dead Breve) key */
  static const String DEAD_BREVE = "DeadBreve";

  /** The Combining Dot Above (Derivative, Dead Above Dot) key */
  static const String DEAD_ABOVE_DOT = "DeadAboveDot";

  /**
   * The Combining Diaeresis (Double Dot Abode, Umlaut, Greek Dialytika,
   * Double Derivative, Dead Diaeresis) key
   */
  static const String DEAD_UMLAUT = "DeadUmlaut";

  /** The Combining Ring Above (Dead Above Ring) key */
  static const String DEAD_ABOVE_RING = "DeadAboveRing";

  /** The Combining Double Acute Accent (Dead Doubleacute) key */
  static const String DEAD_DOUBLEACUTE = "DeadDoubleacute";

  /** The Combining Caron (Hacek, V Above, Dead Caron) key */
  static const String DEAD_CARON = "DeadCaron";

  /** The Combining Cedilla (Dead Cedilla) key */
  static const String DEAD_CEDILLA = "DeadCedilla";

  /** The Combining Ogonek (Nasal Hook, Dead Ogonek) key */
  static const String DEAD_OGONEK = "DeadOgonek";

  /**
   * The Combining Greek Ypogegrammeni (Greek Non-Spacing Iota Below, Iota
   * Subscript, Dead Iota) key
   */
  static const String DEAD_IOTA = "DeadIota";

  /**
   * The Combining Katakana-Hiragana Voiced Sound Mark (Dead Voiced Sound) key
   */
  static const String DEAD_VOICED_SOUND = "DeadVoicedSound";

  /**
   * The Combining Katakana-Hiragana Semi-Voiced Sound Mark (Dead Semivoiced
   * Sound) key
   */
  static const String DEC_SEMIVOICED_SOUND = "DeadSemivoicedSound";

  /**
   * Key value used when an implementation is unable to identify another key
   * value, due to either hardware, platform, or software constraints
   */
  static const String UNIDENTIFIED = "Unidentified";
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Internal class that does the actual calculations to determine keyCode and
 * charCode for keydown, keypress, and keyup events for all browsers.
 */
class _KeyboardEventHandler extends EventStreamProvider<KeyEvent> {
  // This code inspired by Closure's KeyHandling library.
  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keyhandler.js.source.html

  /**
   * The set of keys that have been pressed down without seeing their
   * corresponding keyup event.
   */
  final List<KeyEvent> _keyDownList = <KeyEvent>[];

  /** 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)
      : _stream = new _CustomKeyEventStreamImpl('event'),
        _target = null,
        super(_EVENT_TYPE);

  /**
   * 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 character 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.location == 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 guesstimate 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 = attributes
        ?.map/*<String>*/((name) => '$tagNameUpper::${name.toLowerCase()}');
    var uriAttrs = uriAttributes
        ?.map/*<String>*/((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 = attributes
        ?.map/*<String>*/((name) => '$baseNameUpper::${name.toLowerCase()}');
    var uriAttrs = uriAttributes
        ?.map/*<String>*/((name) => '$baseNameUpper::${name.toLowerCase()}');
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }

    add(new _CustomElementNodeValidator(uriPolicy,
        [tagNameUpper, baseNameUpper], attrs, uriAttrs, true, false));
  }

  void allowElement(String tagName,
      {UriPolicy uriPolicy,
      Iterable<String> attributes,
      Iterable<String> uriAttributes}) {
    allowCustomElement(tagName,
        uriPolicy: uriPolicy,
        attributes: attributes,
        uriAttributes: uriAttributes);
  }

  /**
   * Allow templating elements (such as <template> and template-related
   * attributes.
   *
   * This still requires other validators to allow regular attributes to be
   * bound (such as [allowHtml5]).
   */
  void allowTemplating() {
    add(new _TemplatingNodeValidator());
  }

  /**
   * Add an additional validator to the current list of validators.
   *
   * Elements and attributes will be accepted if they are accepted by any
   * validators.
   */
  void add(NodeValidator validator) {
    _validators.add(validator);
  }

  bool allowsElement(Element element) {
    return _validators.any((v) => v.allowsElement(element));
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    return _validators
        .any((v) => v.allowsAttribute(element, attributeName, value));
  }
}

class _SimpleNodeValidator implements NodeValidator {
  final Set<String> allowedElements = new Set<String>();
  final Set<String> allowedAttributes = new Set<String>();
  final Set<String> allowedUriAttributes = new Set<String>();
  final UriPolicy uriPolicy;

  factory _SimpleNodeValidator.allowNavigation(UriPolicy uriPolicy) {
    return new _SimpleNodeValidator(uriPolicy, allowedElements: const [
      'A',
      'FORM'
    ], allowedAttributes: const [
      'A::accesskey',
      'A::coords',
      'A::hreflang',
      'A::name',
      'A::shape',
      'A::tabindex',
      'A::target',
      'A::type',
      'FORM::accept',
      'FORM::autocomplete',
      'FORM::enctype',
      'FORM::method',
      'FORM::name',
      'FORM::novalidate',
      'FORM::target',
    ], allowedUriAttributes: const [
      'A::href',
      'FORM::action',
    ]);
  }

  factory _SimpleNodeValidator.allowImages(UriPolicy uriPolicy) {
    return new _SimpleNodeValidator(uriPolicy, allowedElements: const [
      'IMG'
    ], allowedAttributes: const [
      'IMG::align',
      'IMG::alt',
      'IMG::border',
      'IMG::height',
      'IMG::hspace',
      'IMG::ismap',
      'IMG::name',
      'IMG::usemap',
      'IMG::vspace',
      'IMG::width',
    ], allowedUriAttributes: const [
      'IMG::src',
    ]);
  }

  factory _SimpleNodeValidator.allowTextElements() {
    return new _SimpleNodeValidator(null, allowedElements: const [
      'B',
      'BLOCKQUOTE',
      'BR',
      'EM',
      'H1',
      'H2',
      'H3',
      'H4',
      'H5',
      'H6',
      'HR',
      'I',
      'LI',
      'OL',
      'P',
      'SPAN',
      'UL',
    ]);
  }

  /**
   * Elements must be uppercased tag names. For example `'IMG'`.
   * Attributes must be uppercased tag name followed by :: followed by
   * lowercase attribute name. For example `'IMG:src'`.
   */
  _SimpleNodeValidator(this.uriPolicy,
      {Iterable<String> allowedElements,
      Iterable<String> allowedAttributes,
      Iterable<String> allowedUriAttributes}) {
    this.allowedElements.addAll(allowedElements ?? const []);
    allowedAttributes = allowedAttributes ?? const [];
    allowedUriAttributes = allowedUriAttributes ?? const [];
    var legalAttributes = allowedAttributes
        .where((x) => !_Html5NodeValidator._uriAttributes.contains(x));
    var extraUriAttributes = allowedAttributes
        .where((x) => _Html5NodeValidator._uriAttributes.contains(x));
    this.allowedAttributes.addAll(legalAttributes);
    this.allowedUriAttributes.addAll(allowedUriAttributes);
    this.allowedUriAttributes.addAll(extraUriAttributes);
  }

  bool allowsElement(Element element) {
    return allowedElements.contains(Element._safeTagName(element));
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    var tagName = Element._safeTagName(element);
    if (allowedUriAttributes.contains('$tagName::$attributeName')) {
      return uriPolicy.allowsUri(value);
    } else if (allowedUriAttributes.contains('*::$attributeName')) {
      return uriPolicy.allowsUri(value);
    } else if (allowedAttributes.contains('$tagName::$attributeName')) {
      return true;
    } else if (allowedAttributes.contains('*::$attributeName')) {
      return true;
    } else if (allowedAttributes.contains('$tagName::*')) {
      return true;
    } else if (allowedAttributes.contains('*::*')) {
      return true;
    }
    return false;
  }
}

class _CustomElementNodeValidator extends _SimpleNodeValidator {
  final bool allowTypeExtension;
  final bool allowCustomTag;

  _CustomElementNodeValidator(
      UriPolicy uriPolicy,
      Iterable<String> allowedElements,
      Iterable<String> allowedAttributes,
      Iterable<String> allowedUriAttributes,
      bool allowTypeExtension,
      bool allowCustomTag)
      : this.allowTypeExtension = allowTypeExtension == true,
        this.allowCustomTag = allowCustomTag == true,
        super(uriPolicy,
            allowedElements: allowedElements,
            allowedAttributes: allowedAttributes,
            allowedUriAttributes: allowedUriAttributes);

  bool allowsElement(Element element) {
    if (allowTypeExtension) {
      var isAttr = element.attributes['is'];
      if (isAttr != null) {
        return allowedElements.contains(isAttr.toUpperCase()) &&
            allowedElements.contains(Element._safeTagName(element));
      }
    }
    return allowCustomTag &&
        allowedElements.contains(Element._safeTagName(element));
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (allowsElement(element)) {
      if (allowTypeExtension &&
          attributeName == 'is' &&
          allowedElements.contains(value.toUpperCase())) {
        return true;
      }
      return super.allowsAttribute(element, attributeName, value);
    }
    return false;
  }
}

class _TemplatingNodeValidator extends _SimpleNodeValidator {
  static const _TEMPLATE_ATTRS = const <String>[
    'bind',
    'if',
    'ref',
    'repeat',
    'syntax'
  ];

  final Set<String> _templateAttrs;

  _TemplatingNodeValidator()
      : _templateAttrs = new Set<String>.from(_TEMPLATE_ATTRS),
        super(null,
            allowedElements: ['TEMPLATE'],
            allowedAttributes:
                _TEMPLATE_ATTRS.map((attr) => 'TEMPLATE::$attr')) {}

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (super.allowsAttribute(element, attributeName, value)) {
      return true;
    }

    if (attributeName == 'template' && value == "") {
      return true;
    }

    if (element.attributes['template'] == "") {
      return _templateAttrs.contains(attributeName);
    }
    return false;
  }
}

class _SvgNodeValidator implements NodeValidator {
  bool allowsElement(Element element) {
    if (element is svg.ScriptElement) {
      return false;
    }
    // Firefox 37 has issues with creating foreign elements inside a
    // foreignobject tag as SvgElement. We don't want foreignobject contents
    // anyway, so just remove the whole tree outright. And we can't rely
    // on IE recognizing the SvgForeignObject type, so go by tagName. Bug 23144
    if (element is svg.SvgElement &&
        Element._safeTagName(element) == 'foreignObject') {
      return false;
    }
    if (element is svg.SvgElement) {
      return true;
    }
    return false;
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (attributeName == 'is' || attributeName.startsWith('on')) {
      return false;
    }
    return allowsElement(element);
  }
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Contains the set of standard values returned by HTMLDocument.getReadyState.
 */
abstract class ReadyState {
  /**
   * Indicates the document is still loading and parsing.
   */
  static const String LOADING = "loading";

  /**
   * Indicates the document is finished parsing but is still loading
   * subresources.
   */
  static const String INTERACTIVE = "interactive";

  /**
   * Indicates the document and all subresources have been loaded.
   */
  static const String COMPLETE = "complete";
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * A list which just wraps another list, for either intercepting list calls or
 * retyping the list (for example, from List<A> to List<B> where B extends A).
 */
class _WrappedList<E extends Node> extends ListBase<E>
    implements NodeListWrapper {
  final List<Node> _list;

  _WrappedList(this._list);

  // Iterable APIs

  Iterator<E> get iterator => new _WrappedIterator<E>(_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) => _downcast/*<Node, E>*/(_list[index]);

  void operator []=(int index, E value) {
    _list[index] = value;
  }

  set length(int newLength) {
    _list.length = newLength;
  }

  void sort([int compare(E a, E b)]) {
    _list.sort((Node a, Node b) =>
        compare(_downcast/*<Node, E>*/(a), _downcast/*<Node, E>*/(b)));
  }

  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) => _downcast/*<Node, E>*/(_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 extends Node> implements Iterator<E> {
  Iterator<Node> _iterator;

  _WrappedIterator(this._iterator);

  bool moveNext() {
    return _iterator.moveNext();
  }

  E get current => _downcast/*<Node, E>*/(_iterator.current);
}

// ignore: STRONG_MODE_DOWN_CAST_COMPOSITE
/*=To*/ _downcast/*<From, To extends From>*/(dynamic/*=From*/ x) => x;
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

class _HttpRequestUtils {
  // Helper for factory HttpRequest.get
  static HttpRequest get(
      String url, onComplete(HttpRequest request), bool withCredentials) {
    final request = new HttpRequest();
    request.open('GET', url, async: true);

    request.withCredentials = withCredentials;

    request.onReadyStateChange.listen((e) {
      if (request.readyState == HttpRequest.DONE) {
        onComplete(request);
      }
    });

    request.send();

    return request;
  }
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Iterator for arrays with fixed size.
class FixedSizeListIterator<T> implements Iterator<T> {
  final List<T> _array;
  final int _length; // Cache array length for faster access.
  int _position;
  T _current;

  FixedSizeListIterator(List<T> array)
      : _array = array,
        _position = -1,
        _length = array.length;

  bool moveNext() {
    int nextPosition = _position + 1;
    if (nextPosition < _length) {
      _current = _array[nextPosition];
      _position = nextPosition;
      return true;
    }
    _current = null;
    _position = _length;
    return false;
  }

  T get current => _current;
}

// Iterator for arrays with variable size.
class _VariableSizeListIterator<T> implements Iterator<T> {
  final List<T> _array;
  int _position;
  T _current;

  _VariableSizeListIterator(List<T> array)
      : _array = array,
        _position = -1;

  bool moveNext() {
    int nextPosition = _position + 1;
    if (nextPosition < _array.length) {
      _current = _array[nextPosition];
      _position = nextPosition;
      return true;
    }
    _current = null;
    _position = _array.length;
    return false;
  }

  T get current => _current;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Conversions for Window.  These check if the window is the local
// window, and if it's not, wraps or unwraps it with a secure wrapper.
// We need to test for EventTarget here as well as it's a base type.
// We omit an unwrapper for Window as no methods take a non-local
// window as a parameter.

WindowBase _convertNativeToDart_Window(win) {
  if (win == null) return null;
  return _DOMWindowCrossFrame._createSafe(win);
}

EventTarget _convertNativeToDart_EventTarget(e) {
  if (e == null) {
    return null;
  }
  // Assume it's a Window if it contains the postMessage property.  It may be
  // from a different frame - without a patched prototype - so we cannot
  // rely on Dart type checking.
  if (JS('bool', r'"postMessage" in #', e)) {
    var window = _DOMWindowCrossFrame._createSafe(e);
    // If it's a native window.
    if (window is EventTarget) {
      return window;
    }
    return null;
  } else
    return e;
}

EventTarget _convertDartToNative_EventTarget(e) {
  if (e is _DOMWindowCrossFrame) {
    return e._window;
  } else {
    return e;
  }
}

_convertNativeToDart_XHR_Response(o) {
  if (o is Document) {
    return o;
  }
  return convertNativeToDart_SerializedScriptValue(o);
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

_callConstructor(constructor, interceptor) {
  return (receiver) {
    setNativeSubclassDispatchRecord(receiver, interceptor);

    // Mirrors uses the constructor property to cache lookups, so we need it to
    // be set correctly, including on IE where it is not automatically picked
    // up from the __proto__.
    JS('', '#.constructor = #.__proto__.constructor', receiver, receiver);
    return JS('', '#(#)', constructor, receiver);
  };
}

_callAttached(receiver) {
  return receiver.attached();
}

_callDetached(receiver) {
  return receiver.detached();
}

_callAttributeChanged(receiver, name, oldValue, newValue) {
  return receiver.attributeChanged(name, oldValue, newValue);
}

_makeCallbackMethod(callback) {
  return JS(
      '',
      '''((function(invokeCallback) {
             return function() {
               return invokeCallback(this);
             };
          })(#))''',
      convertDartClosureToJS(callback, 1));
}

_makeCallbackMethod3(callback) {
  return JS(
      '',
      '''((function(invokeCallback) {
             return function(arg1, arg2, arg3) {
               return invokeCallback(this, arg1, arg2, arg3);
             };
          })(#))''',
      convertDartClosureToJS(callback, 4));
}

/// Checks whether the given [element] correctly extends from the native class
/// with the given [baseClassName]. This method will throw if the base class
/// doesn't match, except when the element extends from `template` and it's base
/// class is `HTMLUnknownElement`. This exclusion is needed to support extension
/// of template elements (used heavily in Polymer 1.0) on IE11 when using the
/// webcomponents-lite.js polyfill.
void _checkExtendsNativeClassOrTemplate(
    Element element, String extendsTag, String baseClassName) {
  if (!JS('bool', '(# instanceof window[#])', element, baseClassName) &&
      !((extendsTag == 'template' &&
          JS('bool', '(# instanceof window["HTMLUnknownElement"])',
              element)))) {
    throw new UnsupportedError('extendsTag does not match base native class');
  }
}

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 {
    var element = document.createElement(extendsTagName);
    _checkExtendsNativeClassOrTemplate(element, extendsTagName, baseClassName);
  }

  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);
      _checkExtendsNativeClassOrTemplate(element, extendsTag, baseClassName);
      _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.
      registerGlobalObject(w);
      return new _DOMWindowCrossFrame(w);
    }
  }

  // TODO(efortuna): Remove this method. dartbug.com/16814
  Events get on => throw new UnsupportedError(
      'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  void _addEventListener(String type, EventListener listener,
          [bool useCapture]) =>
      throw new UnsupportedError(
          'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  void addEventListener(String type, EventListener listener,
          [bool useCapture]) =>
      throw new UnsupportedError(
          'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  bool dispatchEvent(Event event) => throw new UnsupportedError(
      'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  void _removeEventListener(String type, EventListener listener,
          [bool useCapture]) =>
      throw new UnsupportedError(
          'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  void removeEventListener(String type, EventListener listener,
          [bool useCapture]) =>
      throw new UnsupportedError(
          'You can only attach EventListeners to your own window.');
}

class _LocationCrossFrame implements LocationBase {
  // Private location.  Note, this is a location object in another frame, so it
  // cannot be typed as "Location" as its prototype is not patched
  // properly.  Its fields and methods can only be accessed via JavaScript.
  var _location;

  set href(String val) => _setHref(_location, val);
  static void _setHref(location, val) {
    JS('void', '#.href = #', location, val);
  }

  // Implementation support.
  _LocationCrossFrame(this._location);

  static LocationBase _createSafe(location) {
    if (identical(location, window.location)) {
      return location;
    } else {
      // TODO(vsm): Cache or implement equality.
      return new _LocationCrossFrame(location);
    }
  }
}

class _HistoryCrossFrame implements HistoryBase {
  // Private history.  Note, this is a history object in another frame, so it
  // cannot be typed as "History" as its prototype is not patched
  // properly.  Its fields and methods can only be accessed via JavaScript.
  var _history;

  void back() => JS('void', '#.back()', _history);

  void forward() => JS('void', '#.forward()', _history);

  void go(int distance) => JS('void', '#.go(#)', _history, distance);

  // Implementation support.
  _HistoryCrossFrame(this._history);

  static HistoryBase _createSafe(h) {
    if (identical(h, window.history)) {
      return h;
    } else {
      // TODO(vsm): Cache or implement equality.
      return new _HistoryCrossFrame(h);
    }
  }
}

/**
 * A custom KeyboardEvent that attempts to eliminate cross-browser
 * inconsistencies, and also provide both keyCode and charCode information
 * for all key events (when such information can be determined).
 *
 * KeyEvent tries to provide a higher level, more polished keyboard event
 * information on top of the "raw" [KeyboardEvent].
 *
 * The mechanics of using KeyEvents is a little different from the underlying
 * [KeyboardEvent]. To use KeyEvents, you need to create a stream and then add
 * KeyEvents to the stream, rather than using the [EventTarget.dispatchEvent].
 * Here's an example usage:
 *
 *     // Initialize a stream for the KeyEvents:
 *     var stream = KeyEvent.keyPressEvent.forTarget(document.body);
 *     // Start listening to the stream of KeyEvents.
 *     stream.listen((keyEvent) =>
 *         window.console.log('KeyPress event detected ${keyEvent.charCode}'));
 *     ...
 *     // Add a new KeyEvent of someone pressing the 'A' key to the stream so
 *     // listeners can know a KeyEvent happened.
 *     stream.add(new KeyEvent('keypress', keyCode: 65, charCode: 97));
 *
 * This class is very much a work in progress, and we'd love to get information
 * on how we can make this class work with as many international keyboards as
 * possible. Bugs welcome!
 */
@Experimental()
class KeyEvent extends _WrappedEvent implements KeyboardEvent {
  /** The parent KeyboardEvent that this KeyEvent is wrapping and "fixing". */
  KeyboardEvent _parent;

  /** The "fixed" value of whether the alt key is being pressed. */
  bool _shadowAltKey;

  /** Calculated value of what the estimated charCode is for this event. */
  int _shadowCharCode;

  /** Calculated value of what the estimated keyCode is for this event. */
  int _shadowKeyCode;

  /** Calculated value of what the estimated keyCode is for this event. */
  int get keyCode => _shadowKeyCode;

  /** Calculated value of what the estimated charCode is for this event. */
  int get charCode => this.type == 'keypress' ? _shadowCharCode : 0;

  /** Calculated value of whether the alt key is pressed is for this event. */
  bool get altKey => _shadowAltKey;

  /** Calculated 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;

  final InputDeviceCapabilities sourceCapabilities;

  /**
   * 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 location: 1,
      bool ctrlKey: false,
      bool altKey: false,
      bool shiftKey: false,
      bool metaKey: false,
      EventTarget currentTarget}) {
    if (view == null) {
      view = window;
    }

    var eventObj;
    // In these two branches we create an underlying native KeyboardEvent, but
    // we set it with our specified values. Because we are doing custom setting
    // of certain values (charCode/keyCode, etc) only in this class (as opposed
    // to KeyboardEvent) and the way we set these custom values depends on the
    // type of underlying JS object, we do all the construction 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', '#.location = #', eventObj, location);
      JS('void', '#.ctrlKey = #', eventObj, ctrlKey);
      JS('void', '#.altKey = #', eventObj, altKey);
      JS('void', '#.shiftKey = #', eventObj, shiftKey);
      JS('void', '#.metaKey = #', eventObj, metaKey);
    } else {
      // Currently this works on everything but Safari. Safari throws an
      // "Attempting to change access mechanism for an unconfigurable property"
      // TypeError when trying to do the Object.defineProperty hack, so we avoid
      // this branch if possible.
      // Also, if we want this branch to work in FF, we also need to modify
      // _initKeyboardEvent to also take charCode and keyCode values to
      // initialize initKeyEvent.

      eventObj = new Event.eventType('KeyboardEvent', type,
          canBubble: canBubble, cancelable: cancelable);

      // Chromium Hack
      JS(
          'void',
          "Object.defineProperty(#, 'keyCode', {"
          "  get : function() { return this.keyCodeVal; } })",
          eventObj);
      JS(
          'void',
          "Object.defineProperty(#, 'which', {"
          "  get : function() { return this.keyCodeVal; } })",
          eventObj);
      JS(
          'void',
          "Object.defineProperty(#, 'charCode', {"
          "  get : function() { return this.charCodeVal; } })",
          eventObj);

      var keyIdentifier = _convertToHexString(charCode, keyCode);
      eventObj._initKeyboardEvent(type, canBubble, cancelable, view,
          keyIdentifier, location, ctrlKey, altKey, shiftKey, metaKey);
      JS('void', '#.keyCodeVal = #', eventObj, keyCode);
      JS('void', '#.charCodeVal = #', eventObj, charCode);
    }
    // Tell dart2js that it smells like a KeyboardEvent!
    setDispatchProperty(eventObj, _keyboardEventDispatchRecord);

    var keyEvent = new KeyEvent.wrap(eventObj);
    if (keyEvent._currentTarget == null) {
      keyEvent._currentTarget = currentTarget == null ? window : currentTarget;
    }
    return keyEvent;
  }

  // Currently known to work on all browsers but IE.
  static bool get canUseDispatchEvent => JS(
      'bool',
      '(typeof document.body.dispatchEvent == "function")'
      '&& document.body.dispatchEvent.length > 0');

  /** The currently registered target for this event. */
  EventTarget get currentTarget => _currentTarget;

  // This is an experimental method to be sure.
  static String _convertToHexString(int charCode, int keyCode) {
    if (charCode != -1) {
      var hex = charCode.toRadixString(16); // Convert to hexadecimal.
      StringBuffer sb = new StringBuffer('U+');
      for (int i = 0; i < 4 - hex.length; i++) sb.write('0');
      sb.write(hex);
      return sb.toString();
    } else {
      return KeyCode._convertKeyCodeToKeyName(keyCode);
    }
  }

  // TODO(efortuna): If KeyEvent is sufficiently successful that we want to make
  // it the default keyboard event handling, move these methods over to Element.
  /** Accessor to provide a stream of KeyEvents on the desired target. */
  static EventStreamProvider<KeyEvent> keyDownEvent =
      new _KeyboardEventHandler('keydown');
  /** Accessor to provide a stream of KeyEvents on the desired target. */
  static EventStreamProvider<KeyEvent> keyUpEvent =
      new _KeyboardEventHandler('keyup');
  /** Accessor to provide a stream of KeyEvents on the desired target. */
  static EventStreamProvider<KeyEvent> keyPressEvent =
      new _KeyboardEventHandler('keypress');

  String get code => _parent.code;
  /** True if the ctrl key is pressed during this event. */
  bool get ctrlKey => _parent.ctrlKey;
  int get detail => _parent.detail;
  String get key => _parent.key;
  /**
   * 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 location => _parent.location;
  /** True if the Meta (or Mac command) key is pressed during this event. */
  bool get metaKey => _parent.metaKey;
  /** 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;
  int get _which => which;

  String get _keyIdentifier {
    throw new UnsupportedError("keyIdentifier is unsupported.");
  }

  void _initKeyboardEvent(
      String type,
      bool canBubble,
      bool cancelable,
      Window view,
      String keyIdentifier,
      int location,
      bool ctrlKey,
      bool altKey,
      bool shiftKey,
      bool metaKey) {
    throw new UnsupportedError(
        "Cannot initialize a KeyboardEvent from a KeyEvent.");
  }

  @Experimental() // untriaged
  bool getModifierState(String keyArgument) => 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;

  EventTarget get currentTarget => wrapped.currentTarget;

  List<EventTarget> deepPath() {
    return wrapped.deepPath();
  }

  bool get defaultPrevented => wrapped.defaultPrevented;

  int get eventPhase => wrapped.eventPhase;

  bool get isTrusted => wrapped.isTrusted;

  bool get scoped => wrapped.scoped;

  EventTarget get target => wrapped.target;

  double 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.');
    }
    Element currentTarget = this.currentTarget;
    Element 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.

// TODO(jacobr): remove these typedefs when dart:async supports generic types.
typedef R _wrapZoneCallback<A, R>(A a);
typedef R _wrapZoneBinaryCallback<A, B, R>(A a, B b);

_wrapZoneCallback/*<A, R>*/ _wrapZone/*<A, R>*/(
    _wrapZoneCallback/*<A, R>*/ callback) {
  // 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/*<R, A>*/(callback, runGuarded: true);
}

_wrapZoneBinaryCallback/*<A, B, R>*/ _wrapBinaryZone/*<A, B, R>*/(
    _wrapZoneBinaryCallback/*<A, B, R>*/ callback) {
  if (Zone.current == Zone.ROOT) return callback;
  if (callback == null) return null;
  return Zone.current
      .bindBinaryCallback/*<R, A, B>*/(callback, runGuarded: true);
}

/**
 * Alias for [querySelector]. Note this function is deprecated because its
 * semantics will be changing in the future.
 */
@deprecated
@Experimental()
Element query(String relativeSelectors) => document.query(relativeSelectors);
/**
 * Alias for [querySelectorAll]. Note this function is deprecated because its
 * semantics will be changing in the future.
 */
@deprecated
@Experimental()
ElementList<Element> queryAll(String relativeSelectors) =>
    document.queryAll(relativeSelectors);

/**
 * Finds the first descendant element of this document that matches the
 * specified group of selectors.
 *
 * Unless your webpage contains multiple documents, the top-level
 * [querySelector]
 * method behaves the same as this method, so you should use it instead to
 * save typing a few characters.
 *
 * [selectors] should be a string using CSS selector syntax.
 *
 *     var element1 = document.querySelector('.className');
 *     var element2 = document.querySelector('#id');
 *
 * For details about CSS selector syntax, see the
 * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
 */
Element querySelector(String selectors) => document.querySelector(selectors);

/**
 * Finds all descendant elements of this document that match the specified
 * group of selectors.
 *
 * Unless your webpage contains multiple documents, the top-level
 * [querySelectorAll]
 * method behaves the same as this method, so you should use it instead to
 * save typing a few characters.
 *
 * [selectors] should be a string using CSS selector syntax.
 *
 *     var items = document.querySelectorAll('.itemClassName');
 *
 * For details about CSS selector syntax, see the
 * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
 */
ElementList<Element> querySelectorAll(String selectors) =>
    document.querySelectorAll(selectors);

/// A utility for changing the Dart wrapper type for elements.
abstract class ElementUpgrader {
  /// Upgrade the specified element to be of the Dart type this was created for.
  ///
  /// After upgrading the element passed in is invalid and the returned value
  /// should be used instead.
  Element upgrade(Element element);
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Interface used to validate that only accepted elements and attributes are
 * allowed while parsing HTML strings into DOM nodes.
 *
 * In general, customization of validation behavior should be done via the
 * [NodeValidatorBuilder] class to mitigate the chances of incorrectly
 * implementing validation rules.
 */
abstract class NodeValidator {
  /**
   * Construct a default NodeValidator which only accepts whitelisted HTML5
   * elements and attributes.
   *
   * If a uriPolicy is not specified then the default uriPolicy will be used.
   */
  factory NodeValidator({UriPolicy uriPolicy}) =>
      new _Html5NodeValidator(uriPolicy: uriPolicy);

  factory NodeValidator.throws(NodeValidator base) =>
      new _ThrowsNodeValidator(base);

  /**
   * Returns true if the tagName is an accepted type.
   */
  bool allowsElement(Element element);

  /**
   * Returns true if the attribute is allowed.
   *
   * The attributeName parameter will always be in lowercase.
   *
   * See [allowsElement] for format of tagName.
   */
  bool allowsAttribute(Element element, String attributeName, String value);
}

/**
 * Performs sanitization of a node tree after construction to ensure that it
 * does not contain any disallowed elements or attributes.
 *
 * In general custom implementations of this class should not be necessary and
 * all validation customization should be done in custom NodeValidators, but
 * custom implementations of this class can be created to perform more complex
 * tree sanitization.
 */
abstract class NodeTreeSanitizer {
  /**
   * Constructs a default tree sanitizer which will remove all elements and
   * attributes which are not allowed by the provided validator.
   */
  factory NodeTreeSanitizer(NodeValidator validator) =>
      new _ValidatingTreeSanitizer(validator);

  /**
   * Called with the root of the tree which is to be sanitized.
   *
   * This method needs to walk the entire tree and either remove elements and
   * attributes which are not recognized as safe or throw an exception which
   * will mark the entire tree as unsafe.
   */
  void sanitizeTree(Node node);

  /**
   * A sanitizer for trees that we trust. It does no validation and allows
   * any elements. It is also more efficient, since it can pass the text
   * directly through to the underlying APIs without creating a document
   * fragment to be sanitized.
   */
  static const trusted = const _TrustedHtmlTreeSanitizer();
}

/**
 * A sanitizer for trees that we trust. It does no validation and allows
 * any elements.
 */
class _TrustedHtmlTreeSanitizer implements NodeTreeSanitizer {
  const _TrustedHtmlTreeSanitizer();

  sanitizeTree(Node node) {}
}

/**
 * Defines the policy for what types of uris are allowed for particular
 * attribute values.
 *
 * This can be used to provide custom rules such as allowing all http:// URIs
 * for image attributes but only same-origin URIs for anchor tags.
 */
abstract class UriPolicy {
  /**
   * Constructs the default UriPolicy which is to only allow Uris to the same
   * origin as the application was launched from.
   *
   * This will block all ftp: mailto: URIs. It will also block accessing
   * https://example.com if the app is running from http://example.com.
   */
  factory UriPolicy() => new _SameOriginUriPolicy();

  /**
   * Checks if the uri is allowed on the specified attribute.
   *
   * The uri provided may or may not be a relative path.
   */
  bool allowsUri(String uri);
}

/**
 * Allows URIs to the same origin as the current application was loaded from
 * (such as https://example.com:80).
 */
class _SameOriginUriPolicy implements UriPolicy {
  final AnchorElement _hiddenAnchor = new AnchorElement();
  final Location _loc = window.location;

  bool allowsUri(String uri) {
    _hiddenAnchor.href = uri;
    // IE leaves an empty hostname for same-origin URIs.
    return (_hiddenAnchor.hostname == _loc.hostname &&
            _hiddenAnchor.port == _loc.port &&
            _hiddenAnchor.protocol == _loc.protocol) ||
        (_hiddenAnchor.hostname == '' &&
            _hiddenAnchor.port == '' &&
            (_hiddenAnchor.protocol == ':' || _hiddenAnchor.protocol == ''));
  }
}

class _ThrowsNodeValidator implements NodeValidator {
  final NodeValidator validator;

  _ThrowsNodeValidator(this.validator) {}

  bool allowsElement(Element element) {
    if (!validator.allowsElement(element)) {
      throw new ArgumentError(Element._safeTagName(element));
    }
    return true;
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (!validator.allowsAttribute(element, attributeName, value)) {
      throw new ArgumentError(
          '${Element._safeTagName(element)}[$attributeName="$value"]');
    }
  }
}

/**
 * Standard tree sanitizer which validates a node tree against the provided
 * validator and removes any nodes or attributes which are not allowed.
 */
class _ValidatingTreeSanitizer implements NodeTreeSanitizer {
  NodeValidator validator;
  _ValidatingTreeSanitizer(this.validator) {}

  void sanitizeTree(Node node) {
    void walk(Node node, Node parent) {
      sanitizeNode(node, parent);

      var child = node.lastChild;
      while (null != child) {
        var nextChild;
        try {
          // Child may be removed during the walk, and we may not
          // even be able to get its previousNode.
          nextChild = child.previousNode;
        } catch (e) {
          // Child appears bad, remove it. We want to check the rest of the
          // children of node and, but we have no way of getting to the next
          // child, so start again from the last child.
          _removeNode(child, node);
          child = null;
          nextChild = node.lastChild;
        }
        if (child != null) walk(child, node);
        child = nextChild;
      }
    }

    walk(node, null);
  }

  /// Aggressively try to remove node.
  void _removeNode(Node node, Node parent) {
    // If we have the parent, it's presumably already passed more sanitization
    // or is the fragment, so ask it to remove the child. And if that fails
    // try to set the outer html.
    if (parent == null) {
      node.remove();
    } else {
      parent._removeChild(node);
    }
  }

  /// Sanitize the element, assuming we can't trust anything about it.
  void _sanitizeUntrustedElement(/* Element */ element, Node parent) {
    // If the _hasCorruptedAttributes does not successfully return false,
    // then we consider it corrupted and remove.
    // TODO(alanknight): This is a workaround because on Firefox
    // embed/object
    // tags typeof is "function", not "object". We don't recognize them, and
    // can't call methods. This does mean that you can't explicitly allow an
    // embed tag. The only thing that will let it through is a null
    // sanitizer that doesn't traverse the tree at all. But sanitizing while
    // allowing embeds seems quite unlikely. This is also the reason that we
    // can't declare the type of element, as an embed won't pass any type
    // check in dart2js.
    var corrupted = true;
    var attrs;
    var isAttr;
    try {
      // If getting/indexing attributes throws, count that as corrupt.
      attrs = element.attributes;
      isAttr = attrs['is'];
      var corruptedTest1 = Element._hasCorruptedAttributes(element);

      // On IE, erratically, the hasCorruptedAttributes test can return false,
      // even though it clearly is corrupted. A separate copy of the test
      // inlining just the basic check seems to help.
      corrupted = corruptedTest1
          ? true
          : Element._hasCorruptedAttributesAdditionalCheck(element);
    } catch (e) {}
    var elementText = 'element unprintable';
    try {
      elementText = element.toString();
    } catch (e) {}
    try {
      var elementTagName = Element._safeTagName(element);
      _sanitizeElement(element, parent, corrupted, elementText, elementTagName,
          attrs, isAttr);
    } on ArgumentError {
      // Thrown by _ThrowsNodeValidator
      rethrow;
    } catch (e) {
      // Unexpected exception sanitizing -> remove
      _removeNode(element, parent);
      window.console.warn('Removing corrupted element $elementText');
    }
  }

  /// Having done basic sanity checking on the element, and computed the
  /// important attributes we want to check, remove it if it's not valid
  /// or not allowed, either as a whole or particular attributes.
  void _sanitizeElement(Element element, Node parent, bool corrupted,
      String text, String tag, Map attrs, String isAttr) {
    if (false != corrupted) {
      _removeNode(element, parent);
      window.console
          .warn('Removing element due to corrupted attributes on <$text>');
      return;
    }
    if (!validator.allowsElement(element)) {
      _removeNode(element, parent);
      window.console.warn('Removing disallowed element <$tag> from $parent');
      return;
    }

    if (isAttr != null) {
      if (!validator.allowsAttribute(element, 'is', isAttr)) {
        _removeNode(element, parent);
        window.console.warn('Removing disallowed type extension '
            '<$tag is="$isAttr">');
        return;
      }
    }

    // TODO(blois): Need to be able to get all attributes, irrespective of
    // XMLNS.
    var keys = attrs.keys.toList();
    for (var i = attrs.length - 1; i >= 0; --i) {
      var name = keys[i];
      if (!validator.allowsAttribute(
          element, name.toLowerCase(), attrs[name])) {
        window.console.warn('Removing disallowed attribute '
            '<$tag $name="${attrs[name]}">');
        attrs.remove(name);
      }
    }

    if (element is TemplateElement) {
      TemplateElement template = element;
      sanitizeTree(template.content);
    }
  }

  /// Sanitize the node and its children recursively.
  void sanitizeNode(Node node, Node parent) {
    switch (node.nodeType) {
      case Node.ELEMENT_NODE:
        _sanitizeUntrustedElement(node, parent);
        break;
      case Node.COMMENT_NODE:
      case Node.DOCUMENT_FRAGMENT_NODE:
      case Node.TEXT_NODE:
      case Node.CDATA_SECTION_NODE:
        break;
      default:
        _removeNode(node, parent);
    }
  }
}
