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

import 'dart:async';
import 'dart:collection';
import 'dart:_internal' hide Symbol, deprecated;
import 'dart:html_common';
import 'dart:indexed_db';
import 'dart:indexed_db' show indexed_dbBlinkMap;
import 'dart:isolate';
import 'dart:js' as js;
import "dart:convert";
import 'dart:math';
import 'dart:mirrors';
import 'dart:nativewrappers';
import 'dart:typed_data';
import 'dart:web_gl' as gl;
import 'dart:web_gl' show web_glBlinkMap;
import 'dart:web_sql';
import 'dart:svg' as svg;
import 'dart:svg' show svgBlinkMap;
import 'dart:svg' show Matrix;
import 'dart:svg' show SvgSvgElement;
import 'dart:web_audio' as web_audio;
import 'dart:web_audio' show web_audioBlinkMap;
import 'dart:_blink' as _blink;
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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
// Auto-generated dart:html library.


// TODO(vsm): Remove this when we can do the proper checking in
// native code for custom elements.
// Not actually used, but imported since dart:html can generate these objects.

export 'dart:math' show Rectangle, Point;



// Issue 14721, order important for WrappedEvent.


Window _window;

/**
 * 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 {
  if (_window != null) {
    return _window;
  }
  _window = _Utils.window();
  return _window;
}

HtmlDocument _document;

/**
 * Root node for all content in a web page.
 */
HtmlDocument get document {
  if (_document != null) {
    return _document;
  }
  _document = window.document;
  return _document;
}

/**
 * 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): Plumb arguments and return value through.
  return _Utils.spawnDomUri(uri.toString());
}
// FIXME: Can we make this private?
final htmlBlinkMap = {
  '_HistoryCrossFrame': () => _HistoryCrossFrame,
  '_LocationCrossFrame': () => _LocationCrossFrame,
  '_DOMWindowCrossFrame': () => _DOMWindowCrossFrame,
  // FIXME: Move these to better locations.
  'DateTime': () => DateTime,
  'JsObject': () => js.JsObject,
  'JsFunction': () => js.JsFunction,
  'JsArray': () => js.JsArray,
  'AbstractWorker': () => AbstractWorker,
  'Animation': () => Animation,
  'AnimationEffect': () => AnimationEffect,
  'AnimationNode': () => AnimationNode,
  'AnimationPlayer': () => AnimationPlayer,
  'AnimationPlayerEvent': () => AnimationPlayerEvent,
  'AnimationTimeline': () => AnimationTimeline,
  'ApplicationCache': () => ApplicationCache,
  'ApplicationCacheErrorEvent': () => ApplicationCacheErrorEvent,
  'Attr': () => _Attr,
  'AudioTrack': () => AudioTrack,
  'AudioTrackList': () => AudioTrackList,
  'AutocompleteErrorEvent': () => AutocompleteErrorEvent,
  'BarProp': () => BarProp,
  'BatteryManager': () => BatteryManager,
  'BeforeUnloadEvent': () => BeforeUnloadEvent,
  'Blob': () => Blob,
  'CDATASection': () => CDataSection,
  'CSS': () => Css,
  'CSSCharsetRule': () => CssCharsetRule,
  'CSSFontFaceRule': () => CssFontFaceRule,
  'CSSImportRule': () => CssImportRule,
  'CSSKeyframeRule': () => CssKeyframeRule,
  'CSSKeyframesRule': () => CssKeyframesRule,
  'CSSMediaRule': () => CssMediaRule,
  'CSSPageRule': () => CssPageRule,
  'CSSPrimitiveValue': () => _CSSPrimitiveValue,
  'CSSRule': () => CssRule,
  'CSSRuleList': () => _CssRuleList,
  'CSSStyleDeclaration': () => CssStyleDeclaration,
  'CSSStyleRule': () => CssStyleRule,
  'CSSStyleSheet': () => CssStyleSheet,
  'CSSSupportsRule': () => CssSupportsRule,
  'CSSUnknownRule': () => _CSSUnknownRule,
  'CSSValue': () => _CSSValue,
  'CSSValueList': () => _CssValueList,
  'CSSViewportRule': () => CssViewportRule,
  'Cache': () => _Cache,
  'CacheStorage': () => CacheStorage,
  'Canvas2DContextAttributes': () => Canvas2DContextAttributes,
  'CanvasGradient': () => CanvasGradient,
  'CanvasPathMethods': () => _CanvasPathMethods,
  'CanvasPattern': () => CanvasPattern,
  'CanvasRenderingContext2D': () => CanvasRenderingContext2D,
  'CharacterData': () => CharacterData,
  'ChildNode': () => ChildNode,
  'CircularRegion': () => CircularRegion,
  'ClientRect': () => _ClientRect,
  'ClientRectList': () => _ClientRectList,
  'CloseEvent': () => CloseEvent,
  'Comment': () => Comment,
  'CompositionEvent': () => CompositionEvent,
  'Console': () => Console,
  'ConsoleBase': () => ConsoleBase,
  'Coordinates': () => Coordinates,
  'Counter': () => _Counter,
  'Credential': () => Credential,
  'CredentialsContainer': () => CredentialsContainer,
  'Crypto': () => Crypto,
  'CryptoKey': () => CryptoKey,
  'CustomEvent': () => CustomEvent,
  'DOMError': () => DomError,
  'DOMException': () => DomException,
  'DOMFileSystem': () => FileSystem,
  'DOMFileSystemSync': () => _DOMFileSystemSync,
  'DOMImplementation': () => DomImplementation,
  'DOMMatrix': () => DomMatrix,
  'DOMMatrixReadOnly': () => DomMatrixReadOnly,
  'DOMParser': () => DomParser,
  'DOMPoint': () => DomPoint,
  'DOMPointReadOnly': () => DomPointReadOnly,
  'DOMRect': () => _DomRect,
  'DOMRectReadOnly': () => DomRectReadOnly,
  'DOMSettableTokenList': () => DomSettableTokenList,
  'DOMStringList': () => DomStringList,
  'DOMStringMap': () => DomStringMap,
  'DOMTokenList': () => DomTokenList,
  'DataTransfer': () => DataTransfer,
  'DataTransferItem': () => DataTransferItem,
  'DataTransferItemList': () => DataTransferItemList,
  'DatabaseSync': () => _DatabaseSync,
  'DedicatedWorkerGlobalScope': () => DedicatedWorkerGlobalScope,
  'DeprecatedStorageInfo': () => DeprecatedStorageInfo,
  'DeprecatedStorageQuota': () => DeprecatedStorageQuota,
  'DeviceAcceleration': () => DeviceAcceleration,
  'DeviceLightEvent': () => DeviceLightEvent,
  'DeviceMotionEvent': () => DeviceMotionEvent,
  'DeviceOrientationEvent': () => DeviceOrientationEvent,
  'DeviceRotationRate': () => DeviceRotationRate,
  'DirectoryEntry': () => DirectoryEntry,
  'DirectoryEntrySync': () => _DirectoryEntrySync,
  'DirectoryReader': () => DirectoryReader,
  'DirectoryReaderSync': () => _DirectoryReaderSync,
  'Document': () => Document,
  'DocumentFragment': () => DocumentFragment,
  'DocumentType': () => _DocumentType,
  'Element': () => Element,
  'Entry': () => Entry,
  'EntrySync': () => _EntrySync,
  'ErrorEvent': () => ErrorEvent,
  'Event': () => Event,
  'EventSource': () => EventSource,
  'EventTarget': () => EventTarget,
  'FederatedCredential': () => FederatedCredential,
  'FetchBodyStream': () => FetchBodyStream,
  'FetchEvent': () => FetchEvent,
  'File': () => File,
  'FileEntry': () => FileEntry,
  'FileEntrySync': () => _FileEntrySync,
  'FileError': () => FileError,
  'FileList': () => FileList,
  'FileReader': () => FileReader,
  'FileReaderSync': () => _FileReaderSync,
  'FileWriter': () => FileWriter,
  'FileWriterSync': () => _FileWriterSync,
  'FocusEvent': () => FocusEvent,
  'FontFace': () => FontFace,
  'FontFaceSet': () => FontFaceSet,
  'FontFaceSetLoadEvent': () => FontFaceSetLoadEvent,
  'FormData': () => FormData,
  'Gamepad': () => Gamepad,
  'GamepadButton': () => GamepadButton,
  'GamepadEvent': () => GamepadEvent,
  'GamepadList': () => _GamepadList,
  'Geofencing': () => Geofencing,
  'GeofencingRegion': () => GeofencingRegion,
  'Geolocation': () => Geolocation,
  'Geoposition': () => Geoposition,
  'GlobalEventHandlers': () => GlobalEventHandlers,
  'HTMLAllCollection': () => _HTMLAllCollection,
  'HTMLAnchorElement': () => AnchorElement,
  'HTMLAppletElement': () => _HTMLAppletElement,
  'HTMLAreaElement': () => AreaElement,
  'HTMLAudioElement': () => AudioElement,
  'HTMLBRElement': () => BRElement,
  'HTMLBaseElement': () => BaseElement,
  'HTMLBodyElement': () => BodyElement,
  'HTMLButtonElement': () => ButtonElement,
  'HTMLCanvasElement': () => CanvasElement,
  'HTMLCollection': () => HtmlCollection,
  'HTMLContentElement': () => ContentElement,
  'HTMLDListElement': () => DListElement,
  'HTMLDataListElement': () => DataListElement,
  'HTMLDetailsElement': () => DetailsElement,
  'HTMLDialogElement': () => DialogElement,
  'HTMLDirectoryElement': () => _HTMLDirectoryElement,
  'HTMLDivElement': () => DivElement,
  'HTMLDocument': () => HtmlDocument,
  'HTMLElement': () => HtmlElement,
  'HTMLEmbedElement': () => EmbedElement,
  'HTMLFieldSetElement': () => FieldSetElement,
  'HTMLFontElement': () => _HTMLFontElement,
  'HTMLFormControlsCollection': () => HtmlFormControlsCollection,
  'HTMLFormElement': () => FormElement,
  'HTMLFrameElement': () => _HTMLFrameElement,
  'HTMLFrameSetElement': () => _HTMLFrameSetElement,
  'HTMLHRElement': () => HRElement,
  'HTMLHeadElement': () => HeadElement,
  'HTMLHeadingElement': () => HeadingElement,
  'HTMLHtmlElement': () => HtmlHtmlElement,
  'HTMLIFrameElement': () => IFrameElement,
  'HTMLImageElement': () => ImageElement,
  'HTMLInputElement': () => InputElement,
  'HTMLKeygenElement': () => KeygenElement,
  'HTMLLIElement': () => LIElement,
  'HTMLLabelElement': () => LabelElement,
  'HTMLLegendElement': () => LegendElement,
  'HTMLLinkElement': () => LinkElement,
  'HTMLMapElement': () => MapElement,
  'HTMLMarqueeElement': () => _HTMLMarqueeElement,
  'HTMLMediaElement': () => MediaElement,
  'HTMLMenuElement': () => MenuElement,
  'HTMLMenuItemElement': () => MenuItemElement,
  'HTMLMetaElement': () => MetaElement,
  'HTMLMeterElement': () => MeterElement,
  'HTMLModElement': () => ModElement,
  'HTMLOListElement': () => OListElement,
  'HTMLObjectElement': () => ObjectElement,
  'HTMLOptGroupElement': () => OptGroupElement,
  'HTMLOptionElement': () => OptionElement,
  'HTMLOptionsCollection': () => HtmlOptionsCollection,
  'HTMLOutputElement': () => OutputElement,
  'HTMLParagraphElement': () => ParagraphElement,
  'HTMLParamElement': () => ParamElement,
  'HTMLPictureElement': () => PictureElement,
  'HTMLPreElement': () => PreElement,
  'HTMLProgressElement': () => ProgressElement,
  'HTMLQuoteElement': () => QuoteElement,
  'HTMLScriptElement': () => ScriptElement,
  'HTMLSelectElement': () => SelectElement,
  'HTMLShadowElement': () => ShadowElement,
  'HTMLSourceElement': () => SourceElement,
  'HTMLSpanElement': () => SpanElement,
  'HTMLStyleElement': () => StyleElement,
  'HTMLTableCaptionElement': () => TableCaptionElement,
  'HTMLTableCellElement': () => TableCellElement,
  'HTMLTableColElement': () => TableColElement,
  'HTMLTableElement': () => TableElement,
  'HTMLTableRowElement': () => TableRowElement,
  'HTMLTableSectionElement': () => TableSectionElement,
  'HTMLTemplateElement': () => TemplateElement,
  'HTMLTextAreaElement': () => TextAreaElement,
  'HTMLTitleElement': () => TitleElement,
  'HTMLTrackElement': () => TrackElement,
  'HTMLUListElement': () => UListElement,
  'HTMLUnknownElement': () => UnknownElement,
  'HTMLVideoElement': () => VideoElement,
  'HashChangeEvent': () => HashChangeEvent,
  'Headers': () => Headers,
  'History': () => History,
  'ImageBitmap': () => ImageBitmap,
  'ImageData': () => ImageData,
  'InjectedScriptHost': () => InjectedScriptHost,
  'InputMethodContext': () => InputMethodContext,
  'InstallEvent': () => InstallEvent,
  'InstallPhaseEvent': () => InstallPhaseEvent,
  'KeyboardEvent': () => KeyboardEvent,
  'LocalCredential': () => LocalCredential,
  'Location': () => Location,
  'MIDIAccess': () => MidiAccess,
  'MIDIConnectionEvent': () => MidiConnectionEvent,
  'MIDIInput': () => MidiInput,
  'MIDIMessageEvent': () => MidiMessageEvent,
  'MIDIOutput': () => MidiOutput,
  'MIDIPort': () => MidiPort,
  'MediaController': () => MediaController,
  'MediaDeviceInfo': () => MediaDeviceInfo,
  'MediaError': () => MediaError,
  'MediaKeyError': () => MediaKeyError,
  'MediaKeyEvent': () => MediaKeyEvent,
  'MediaKeyMessageEvent': () => MediaKeyMessageEvent,
  'MediaKeyNeededEvent': () => MediaKeyNeededEvent,
  'MediaKeySession': () => MediaKeySession,
  'MediaKeys': () => MediaKeys,
  'MediaList': () => MediaList,
  'MediaQueryList': () => MediaQueryList,
  'MediaSource': () => MediaSource,
  'MediaStream': () => MediaStream,
  'MediaStreamEvent': () => MediaStreamEvent,
  'MediaStreamTrack': () => MediaStreamTrack,
  'MediaStreamTrackEvent': () => MediaStreamTrackEvent,
  'MemoryInfo': () => MemoryInfo,
  'MessageChannel': () => MessageChannel,
  'MessageEvent': () => MessageEvent,
  'MessagePort': () => MessagePort,
  'Metadata': () => Metadata,
  'MimeType': () => MimeType,
  'MimeTypeArray': () => MimeTypeArray,
  'MouseEvent': () => MouseEvent,
  'MutationEvent': () => _MutationEvent,
  'MutationObserver': () => MutationObserver,
  'MutationRecord': () => MutationRecord,
  'NamedNodeMap': () => _NamedNodeMap,
  'Navigator': () => Navigator,
  'NavigatorCPU': () => NavigatorCpu,
  'NavigatorID': () => NavigatorID,
  'NavigatorLanguage': () => NavigatorLanguage,
  'NavigatorOnLine': () => NavigatorOnLine,
  'NavigatorUserMediaError': () => NavigatorUserMediaError,
  'NetworkInformation': () => NetworkInformation,
  'Node': () => Node,
  'NodeFilter': () => NodeFilter,
  'NodeIterator': () => NodeIterator,
  'NodeList': () => NodeList,
  'Notation': () => _Notation,
  'Notification': () => Notification,
  'OverflowEvent': () => OverflowEvent,
  'PagePopupController': () => _PagePopupController,
  'PageTransitionEvent': () => PageTransitionEvent,
  'ParentNode': () => ParentNode,
  'Path2D': () => Path2D,
  'Performance': () => Performance,
  'PerformanceEntry': () => PerformanceEntry,
  'PerformanceMark': () => PerformanceMark,
  'PerformanceMeasure': () => PerformanceMeasure,
  'PerformanceNavigation': () => PerformanceNavigation,
  'PerformanceResourceTiming': () => PerformanceResourceTiming,
  'PerformanceTiming': () => PerformanceTiming,
  'Plugin': () => Plugin,
  'PluginArray': () => PluginArray,
  'PopStateEvent': () => PopStateEvent,
  'PositionError': () => PositionError,
  'ProcessingInstruction': () => ProcessingInstruction,
  'ProgressEvent': () => ProgressEvent,
  'PushEvent': () => PushEvent,
  'PushManager': () => PushManager,
  'PushRegistration': () => PushRegistration,
  'RGBColor': () => _RGBColor,
  'RTCDTMFSender': () => RtcDtmfSender,
  'RTCDTMFToneChangeEvent': () => RtcDtmfToneChangeEvent,
  'RTCDataChannel': () => RtcDataChannel,
  'RTCDataChannelEvent': () => RtcDataChannelEvent,
  'RTCIceCandidate': () => RtcIceCandidate,
  'RTCIceCandidateEvent': () => RtcIceCandidateEvent,
  'RTCPeerConnection': () => RtcPeerConnection,
  'RTCSessionDescription': () => RtcSessionDescription,
  'RTCStatsReport': () => RtcStatsReport,
  'RTCStatsResponse': () => RtcStatsResponse,
  'RadioNodeList': () => _RadioNodeList,
  'Range': () => Range,
  'ReadableStream': () => ReadableStream,
  'Rect': () => _Rect,
  'RelatedEvent': () => RelatedEvent,
  'Request': () => _Request,
  'ResourceProgressEvent': () => ResourceProgressEvent,
  'Response': () => _Response,
  'Screen': () => Screen,
  'ScreenOrientation': () => ScreenOrientation,
  'SecurityPolicyViolationEvent': () => SecurityPolicyViolationEvent,
  'Selection': () => Selection,
  'ServiceWorker': () => _ServiceWorker,
  'ServiceWorkerClient': () => ServiceWorkerClient,
  'ServiceWorkerClients': () => ServiceWorkerClients,
  'ServiceWorkerContainer': () => ServiceWorkerContainer,
  'ServiceWorkerGlobalScope': () => ServiceWorkerGlobalScope,
  'ServiceWorkerRegistration': () => ServiceWorkerRegistration,
  'ShadowRoot': () => ShadowRoot,
  'SharedWorker': () => SharedWorker,
  'SharedWorkerGlobalScope': () => SharedWorkerGlobalScope,
  'SourceBuffer': () => SourceBuffer,
  'SourceBufferList': () => SourceBufferList,
  'SourceInfo': () => SourceInfo,
  'SpeechGrammar': () => SpeechGrammar,
  'SpeechGrammarList': () => SpeechGrammarList,
  'SpeechRecognition': () => SpeechRecognition,
  'SpeechRecognitionAlternative': () => SpeechRecognitionAlternative,
  'SpeechRecognitionError': () => SpeechRecognitionError,
  'SpeechRecognitionEvent': () => SpeechRecognitionEvent,
  'SpeechRecognitionResult': () => SpeechRecognitionResult,
  'SpeechRecognitionResultList': () => _SpeechRecognitionResultList,
  'SpeechSynthesis': () => SpeechSynthesis,
  'SpeechSynthesisEvent': () => SpeechSynthesisEvent,
  'SpeechSynthesisUtterance': () => SpeechSynthesisUtterance,
  'SpeechSynthesisVoice': () => SpeechSynthesisVoice,
  'Storage': () => Storage,
  'StorageEvent': () => StorageEvent,
  'StorageInfo': () => StorageInfo,
  'StorageQuota': () => StorageQuota,
  'Stream': () => FileStream,
  'StyleMedia': () => StyleMedia,
  'StyleSheet': () => StyleSheet,
  'StyleSheetList': () => _StyleSheetList,
  'SubtleCrypto': () => _SubtleCrypto,
  'Text': () => Text,
  'TextEvent': () => TextEvent,
  'TextMetrics': () => TextMetrics,
  'TextTrack': () => TextTrack,
  'TextTrackCue': () => TextTrackCue,
  'TextTrackCueList': () => TextTrackCueList,
  'TextTrackList': () => TextTrackList,
  'TimeRanges': () => TimeRanges,
  'Timing': () => Timing,
  'Touch': () => Touch,
  'TouchEvent': () => TouchEvent,
  'TouchList': () => TouchList,
  'TrackEvent': () => TrackEvent,
  'TransitionEvent': () => TransitionEvent,
  'TreeWalker': () => TreeWalker,
  'UIEvent': () => UIEvent,
  'URL': () => Url,
  'URLUtils': () => UrlUtils,
  'URLUtilsReadOnly': () => UrlUtilsReadOnly,
  'VTTCue': () => VttCue,
  'VTTRegion': () => VttRegion,
  'VTTRegionList': () => VttRegionList,
  'ValidityState': () => ValidityState,
  'VideoPlaybackQuality': () => VideoPlaybackQuality,
  'VideoTrack': () => VideoTrack,
  'VideoTrackList': () => VideoTrackList,
  'WebKitAnimationEvent': () => AnimationEvent,
  'WebKitCSSFilterRule': () => CssFilterRule,
  'WebKitCSSFilterValue': () => _WebKitCSSFilterValue,
  'WebKitCSSMatrix': () => _WebKitCSSMatrix,
  'WebKitCSSTransformValue': () => _WebKitCSSTransformValue,
  'WebKitPoint': () => _DomPoint,
  'WebSocket': () => WebSocket,
  'WheelEvent': () => WheelEvent,
  'Window': () => Window,
  'WindowBase64': () => WindowBase64,
  'WindowEventHandlers': () => WindowEventHandlers,
  'WindowTimers': () => _WindowTimers,
  'Worker': () => Worker,
  'WorkerConsole': () => WorkerConsole,
  'WorkerGlobalScope': () => WorkerGlobalScope,
  'WorkerLocation': () => _WorkerLocation,
  'WorkerNavigator': () => _WorkerNavigator,
  'WorkerPerformance': () => WorkerPerformance,
  'XMLDocument': () => XmlDocument,
  'XMLHttpRequest': () => HttpRequest,
  'XMLHttpRequestEventTarget': () => HttpRequestEventTarget,
  'XMLHttpRequestProgressEvent': () => _XMLHttpRequestProgressEvent,
  'XMLHttpRequestUpload': () => HttpRequestUpload,
  'XMLSerializer': () => XmlSerializer,
  'XPathEvaluator': () => XPathEvaluator,
  'XPathExpression': () => XPathExpression,
  'XPathNSResolver': () => XPathNSResolver,
  'XPathResult': () => XPathResult,
  'XSLTProcessor': () => XsltProcessor,

};

// TODO(leafp): We may want to move this elsewhere if html becomes
// a package to avoid dartium depending on pkg:html.
Type _getType(String key) {
  var result;

  // TODO(vsm): Add Cross Frame and JS types here as well.

  // Check the html library.
  result = _getHtmlType(key);
  if (result != null) {
    return result;
  }

  // Check the web gl library.
  result = _getWebGlType(key);
  if (result != null) {
    return result;
  }

  // Check the indexed db library.
  result = _getIndexDbType(key);
  if (result != null) {
    return result;
  }

  // Check the web audio library.
  result = _getWebAudioType(key);
  if (result != null) {
    return result;
  }

  // Check the web sql library.
  result = _getWebSqlType(key);
  if (result != null) {
    return result;
  }

  // Check the svg library.
  result = _getSvgType(key);
  if (result != null) {
    return result;
  }

  return null;
}

Type _getHtmlType(String key) {
  if (htmlBlinkMap.containsKey(key)) {
    return htmlBlinkMap[key]();
  }
  return null;
}

Type _getWebGlType(String key) {
  if (web_glBlinkMap.containsKey(key)) {
    return web_glBlinkMap[key]();
  }
  return null;
}

Type _getIndexDbType(String key) {
  if (indexed_dbBlinkMap.containsKey(key)) {
    return indexed_dbBlinkMap[key]();
  }
  return null;
}

Type _getWebAudioType(String key) {
  if (web_audioBlinkMap.containsKey(key)) {
    return web_audioBlinkMap[key]();
  }
  return null;
}

Type _getWebSqlType(String key) {
  if (web_sqlBlinkMap.containsKey(key)) {
    return web_sqlBlinkMap[key]();
  }
  return null;
}

Type _getSvgType(String key) {
  if (svgBlinkMap.containsKey(key)) {
    return svgBlinkMap[key]();
  }
  return null;
}
// 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 NativeFieldWrapperClass2 implements EventTarget {
  // To suppress missing implicit constructor warnings.
  factory AbstractWorker._() { throw new UnsupportedError("Not supported"); }

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

  /// Stream of `error` events handled by this [AbstractWorker].
  @DomName('AbstractWorker.onerror')
  @DocsEditable()
  Stream<ErrorEvent> get onError => errorEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

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

  @DomName('HTMLAnchorElement.download')
  @DocsEditable()
  String get download => _blink.BlinkHTMLAnchorElement.instance.download_Getter_(this);

  @DomName('HTMLAnchorElement.download')
  @DocsEditable()
  void set download(String value) => _blink.BlinkHTMLAnchorElement.instance.download_Setter_(this, value);

  @DomName('HTMLAnchorElement.hreflang')
  @DocsEditable()
  String get hreflang => _blink.BlinkHTMLAnchorElement.instance.hreflang_Getter_(this);

  @DomName('HTMLAnchorElement.hreflang')
  @DocsEditable()
  void set hreflang(String value) => _blink.BlinkHTMLAnchorElement.instance.hreflang_Setter_(this, value);

  @DomName('HTMLAnchorElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String get integrity => _blink.BlinkHTMLAnchorElement.instance.integrity_Getter_(this);

  @DomName('HTMLAnchorElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  void set integrity(String value) => _blink.BlinkHTMLAnchorElement.instance.integrity_Setter_(this, value);

  @DomName('HTMLAnchorElement.rel')
  @DocsEditable()
  String get rel => _blink.BlinkHTMLAnchorElement.instance.rel_Getter_(this);

  @DomName('HTMLAnchorElement.rel')
  @DocsEditable()
  void set rel(String value) => _blink.BlinkHTMLAnchorElement.instance.rel_Setter_(this, value);

  @DomName('HTMLAnchorElement.target')
  @DocsEditable()
  String get target => _blink.BlinkHTMLAnchorElement.instance.target_Getter_(this);

  @DomName('HTMLAnchorElement.target')
  @DocsEditable()
  void set target(String value) => _blink.BlinkHTMLAnchorElement.instance.target_Setter_(this, value);

  @DomName('HTMLAnchorElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLAnchorElement.instance.type_Getter_(this);

  @DomName('HTMLAnchorElement.type')
  @DocsEditable()
  void set type(String value) => _blink.BlinkHTMLAnchorElement.instance.type_Setter_(this, value);

  @DomName('HTMLAnchorElement.hash')
  @DocsEditable()
  String get hash => _blink.BlinkHTMLAnchorElement.instance.hash_Getter_(this);

  @DomName('HTMLAnchorElement.hash')
  @DocsEditable()
  void set hash(String value) => _blink.BlinkHTMLAnchorElement.instance.hash_Setter_(this, value);

  @DomName('HTMLAnchorElement.host')
  @DocsEditable()
  String get host => _blink.BlinkHTMLAnchorElement.instance.host_Getter_(this);

  @DomName('HTMLAnchorElement.host')
  @DocsEditable()
  void set host(String value) => _blink.BlinkHTMLAnchorElement.instance.host_Setter_(this, value);

  @DomName('HTMLAnchorElement.hostname')
  @DocsEditable()
  String get hostname => _blink.BlinkHTMLAnchorElement.instance.hostname_Getter_(this);

  @DomName('HTMLAnchorElement.hostname')
  @DocsEditable()
  void set hostname(String value) => _blink.BlinkHTMLAnchorElement.instance.hostname_Setter_(this, value);

  @DomName('HTMLAnchorElement.href')
  @DocsEditable()
  String get href => _blink.BlinkHTMLAnchorElement.instance.href_Getter_(this);

  @DomName('HTMLAnchorElement.href')
  @DocsEditable()
  void set href(String value) => _blink.BlinkHTMLAnchorElement.instance.href_Setter_(this, value);

  @DomName('HTMLAnchorElement.origin')
  @DocsEditable()
  // WebKit only
  @Experimental() // non-standard
  String get origin => _blink.BlinkHTMLAnchorElement.instance.origin_Getter_(this);

  @DomName('HTMLAnchorElement.password')
  @DocsEditable()
  @Experimental() // untriaged
  String get password => _blink.BlinkHTMLAnchorElement.instance.password_Getter_(this);

  @DomName('HTMLAnchorElement.password')
  @DocsEditable()
  @Experimental() // untriaged
  void set password(String value) => _blink.BlinkHTMLAnchorElement.instance.password_Setter_(this, value);

  @DomName('HTMLAnchorElement.pathname')
  @DocsEditable()
  String get pathname => _blink.BlinkHTMLAnchorElement.instance.pathname_Getter_(this);

  @DomName('HTMLAnchorElement.pathname')
  @DocsEditable()
  void set pathname(String value) => _blink.BlinkHTMLAnchorElement.instance.pathname_Setter_(this, value);

  @DomName('HTMLAnchorElement.port')
  @DocsEditable()
  String get port => _blink.BlinkHTMLAnchorElement.instance.port_Getter_(this);

  @DomName('HTMLAnchorElement.port')
  @DocsEditable()
  void set port(String value) => _blink.BlinkHTMLAnchorElement.instance.port_Setter_(this, value);

  @DomName('HTMLAnchorElement.protocol')
  @DocsEditable()
  String get protocol => _blink.BlinkHTMLAnchorElement.instance.protocol_Getter_(this);

  @DomName('HTMLAnchorElement.protocol')
  @DocsEditable()
  void set protocol(String value) => _blink.BlinkHTMLAnchorElement.instance.protocol_Setter_(this, value);

  @DomName('HTMLAnchorElement.search')
  @DocsEditable()
  String get search => _blink.BlinkHTMLAnchorElement.instance.search_Getter_(this);

  @DomName('HTMLAnchorElement.search')
  @DocsEditable()
  void set search(String value) => _blink.BlinkHTMLAnchorElement.instance.search_Setter_(this, value);

  @DomName('HTMLAnchorElement.username')
  @DocsEditable()
  @Experimental() // untriaged
  String get username => _blink.BlinkHTMLAnchorElement.instance.username_Getter_(this);

  @DomName('HTMLAnchorElement.username')
  @DocsEditable()
  @Experimental() // untriaged
  void set username(String value) => _blink.BlinkHTMLAnchorElement.instance.username_Setter_(this, value);

  @DomName('HTMLAnchorElement.toString')
  @DocsEditable()
  String toString() => _blink.BlinkHTMLAnchorElement.instance.toString_Callback_0_(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.


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

  @DomName('Animation.Animation')
  @DocsEditable()
  factory Animation(Element target, List<Map> keyframes, [timingInput]) {
    if ((keyframes is List<Map> || keyframes == null) && (target is Element || target == null) && timingInput == null) {
      return _blink.BlinkAnimation.instance.constructorCallback_2_(target, keyframes);
    }
    if ((timingInput is num || timingInput == null) && (keyframes is List<Map> || keyframes == null) && (target is Element || target == null)) {
      return _blink.BlinkAnimation.instance.constructorCallback_3_(target, keyframes, timingInput);
    }
    if ((timingInput is Map || timingInput == null) && (keyframes is List<Map> || keyframes == null) && (target is Element || target == null)) {
      return _blink.BlinkAnimation.instance.constructorCallback_3_(target, keyframes, timingInput);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

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

// WARNING: Do not edit - generated code.


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

  @DomName('WebKitAnimationEvent.animationName')
  @DocsEditable()
  String get animationName => _blink.BlinkWebKitAnimationEvent.instance.animationName_Getter_(this);

  @DomName('WebKitAnimationEvent.elapsedTime')
  @DocsEditable()
  double get elapsedTime => _blink.BlinkWebKitAnimationEvent.instance.elapsedTime_Getter_(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.


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

  @DomName('AnimationNode.activeDuration')
  @DocsEditable()
  @Experimental() // untriaged
  double get activeDuration => _blink.BlinkAnimationNode.instance.activeDuration_Getter_(this);

  @DomName('AnimationNode.currentIteration')
  @DocsEditable()
  @Experimental() // untriaged
  int get currentIteration => _blink.BlinkAnimationNode.instance.currentIteration_Getter_(this);

  @DomName('AnimationNode.duration')
  @DocsEditable()
  @Experimental() // untriaged
  double get duration => _blink.BlinkAnimationNode.instance.duration_Getter_(this);

  @DomName('AnimationNode.endTime')
  @DocsEditable()
  @Experimental() // untriaged
  double get endTime => _blink.BlinkAnimationNode.instance.endTime_Getter_(this);

  @DomName('AnimationNode.localTime')
  @DocsEditable()
  @Experimental() // untriaged
  double get localTime => _blink.BlinkAnimationNode.instance.localTime_Getter_(this);

  @DomName('AnimationNode.player')
  @DocsEditable()
  @Experimental() // untriaged
  AnimationPlayer get player => _blink.BlinkAnimationNode.instance.player_Getter_(this);

  @DomName('AnimationNode.startTime')
  @DocsEditable()
  @Experimental() // untriaged
  double get startTime => _blink.BlinkAnimationNode.instance.startTime_Getter_(this);

  @DomName('AnimationNode.timing')
  @DocsEditable()
  @Experimental() // untriaged
  Timing get timing => _blink.BlinkAnimationNode.instance.timing_Getter_(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.


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

  @DomName('AnimationPlayer.currentTime')
  @DocsEditable()
  @Experimental() // untriaged
  num get currentTime => _blink.BlinkAnimationPlayer.instance.currentTime_Getter_(this);

  @DomName('AnimationPlayer.currentTime')
  @DocsEditable()
  @Experimental() // untriaged
  void set currentTime(num value) => _blink.BlinkAnimationPlayer.instance.currentTime_Setter_(this, value);

  @DomName('AnimationPlayer.finished')
  @DocsEditable()
  @Experimental() // untriaged
  bool get finished => _blink.BlinkAnimationPlayer.instance.finished_Getter_(this);

  @DomName('AnimationPlayer.paused')
  @DocsEditable()
  @Experimental() // untriaged
  bool get paused => _blink.BlinkAnimationPlayer.instance.paused_Getter_(this);

  @DomName('AnimationPlayer.playbackRate')
  @DocsEditable()
  @Experimental() // untriaged
  num get playbackRate => _blink.BlinkAnimationPlayer.instance.playbackRate_Getter_(this);

  @DomName('AnimationPlayer.playbackRate')
  @DocsEditable()
  @Experimental() // untriaged
  void set playbackRate(num value) => _blink.BlinkAnimationPlayer.instance.playbackRate_Setter_(this, value);

  @DomName('AnimationPlayer.source')
  @DocsEditable()
  @Experimental() // untriaged
  AnimationNode get source => _blink.BlinkAnimationPlayer.instance.source_Getter_(this);

  @DomName('AnimationPlayer.source')
  @DocsEditable()
  @Experimental() // untriaged
  void set source(AnimationNode value) => _blink.BlinkAnimationPlayer.instance.source_Setter_(this, value);

  @DomName('AnimationPlayer.startTime')
  @DocsEditable()
  @Experimental() // untriaged
  num get startTime => _blink.BlinkAnimationPlayer.instance.startTime_Getter_(this);

  @DomName('AnimationPlayer.startTime')
  @DocsEditable()
  @Experimental() // untriaged
  void set startTime(num value) => _blink.BlinkAnimationPlayer.instance.startTime_Setter_(this, value);

  @DomName('AnimationPlayer.cancel')
  @DocsEditable()
  @Experimental() // untriaged
  void cancel() => _blink.BlinkAnimationPlayer.instance.cancel_Callback_0_(this);

  @DomName('AnimationPlayer.finish')
  @DocsEditable()
  @Experimental() // untriaged
  void finish() => _blink.BlinkAnimationPlayer.instance.finish_Callback_0_(this);

  @DomName('AnimationPlayer.pause')
  @DocsEditable()
  @Experimental() // untriaged
  void pause() => _blink.BlinkAnimationPlayer.instance.pause_Callback_0_(this);

  @DomName('AnimationPlayer.play')
  @DocsEditable()
  @Experimental() // untriaged
  void play() => _blink.BlinkAnimationPlayer.instance.play_Callback_0_(this);

  @DomName('AnimationPlayer.reverse')
  @DocsEditable()
  @Experimental() // untriaged
  void reverse() => _blink.BlinkAnimationPlayer.instance.reverse_Callback_0_(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.


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

  @DomName('AnimationPlayerEvent.currentTime')
  @DocsEditable()
  @Experimental() // untriaged
  double get currentTime => _blink.BlinkAnimationPlayerEvent.instance.currentTime_Getter_(this);

  @DomName('AnimationPlayerEvent.timelineTime')
  @DocsEditable()
  @Experimental() // untriaged
  double get timelineTime => _blink.BlinkAnimationPlayerEvent.instance.timelineTime_Getter_(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.


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

  @DomName('AnimationTimeline.currentTime')
  @DocsEditable()
  @Experimental() // untriaged
  double get currentTime => _blink.BlinkAnimationTimeline.instance.currentTime_Getter_(this);

  @DomName('AnimationTimeline.getAnimationPlayers')
  @DocsEditable()
  @Experimental() // untriaged
  List<AnimationPlayer> getAnimationPlayers() => _blink.BlinkAnimationTimeline.instance.getAnimationPlayers_Callback_0_(this);

  @DomName('AnimationTimeline.play')
  @DocsEditable()
  @Experimental() // untriaged
  AnimationPlayer play(AnimationNode source) => _blink.BlinkAnimationTimeline.instance.play_Callback_1_(this, 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.

// WARNING: Do not edit - generated code.


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

  @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()
  int get status => _blink.BlinkApplicationCache.instance.status_Getter_(this);

  @DomName('ApplicationCache.abort')
  @DocsEditable()
  void abort() => _blink.BlinkApplicationCache.instance.abort_Callback_0_(this);

  @DomName('ApplicationCache.swapCache')
  @DocsEditable()
  void swapCache() => _blink.BlinkApplicationCache.instance.swapCache_Callback_0_(this);

  @DomName('ApplicationCache.update')
  @DocsEditable()
  void update() => _blink.BlinkApplicationCache.instance.update_Callback_0_(this);

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

// WARNING: Do not edit - generated code.


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

  @DomName('ApplicationCacheErrorEvent.message')
  @DocsEditable()
  @Experimental() // untriaged
  String get message => _blink.BlinkApplicationCacheErrorEvent.instance.message_Getter_(this);

  @DomName('ApplicationCacheErrorEvent.reason')
  @DocsEditable()
  @Experimental() // untriaged
  String get reason => _blink.BlinkApplicationCacheErrorEvent.instance.reason_Getter_(this);

  @DomName('ApplicationCacheErrorEvent.status')
  @DocsEditable()
  @Experimental() // untriaged
  int get status => _blink.BlinkApplicationCacheErrorEvent.instance.status_Getter_(this);

  @DomName('ApplicationCacheErrorEvent.url')
  @DocsEditable()
  @Experimental() // untriaged
  String get url => _blink.BlinkApplicationCacheErrorEvent.instance.url_Getter_(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.


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

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

  @DomName('HTMLAreaElement.alt')
  @DocsEditable()
  String get alt => _blink.BlinkHTMLAreaElement.instance.alt_Getter_(this);

  @DomName('HTMLAreaElement.alt')
  @DocsEditable()
  void set alt(String value) => _blink.BlinkHTMLAreaElement.instance.alt_Setter_(this, value);

  @DomName('HTMLAreaElement.coords')
  @DocsEditable()
  String get coords => _blink.BlinkHTMLAreaElement.instance.coords_Getter_(this);

  @DomName('HTMLAreaElement.coords')
  @DocsEditable()
  void set coords(String value) => _blink.BlinkHTMLAreaElement.instance.coords_Setter_(this, value);

  @DomName('HTMLAreaElement.shape')
  @DocsEditable()
  String get shape => _blink.BlinkHTMLAreaElement.instance.shape_Getter_(this);

  @DomName('HTMLAreaElement.shape')
  @DocsEditable()
  void set shape(String value) => _blink.BlinkHTMLAreaElement.instance.shape_Setter_(this, value);

  @DomName('HTMLAreaElement.target')
  @DocsEditable()
  String get target => _blink.BlinkHTMLAreaElement.instance.target_Getter_(this);

  @DomName('HTMLAreaElement.target')
  @DocsEditable()
  void set target(String value) => _blink.BlinkHTMLAreaElement.instance.target_Setter_(this, value);

  @DomName('HTMLAreaElement.hash')
  @DocsEditable()
  String get hash => _blink.BlinkHTMLAreaElement.instance.hash_Getter_(this);

  @DomName('HTMLAreaElement.hash')
  @DocsEditable()
  void set hash(String value) => _blink.BlinkHTMLAreaElement.instance.hash_Setter_(this, value);

  @DomName('HTMLAreaElement.host')
  @DocsEditable()
  String get host => _blink.BlinkHTMLAreaElement.instance.host_Getter_(this);

  @DomName('HTMLAreaElement.host')
  @DocsEditable()
  void set host(String value) => _blink.BlinkHTMLAreaElement.instance.host_Setter_(this, value);

  @DomName('HTMLAreaElement.hostname')
  @DocsEditable()
  String get hostname => _blink.BlinkHTMLAreaElement.instance.hostname_Getter_(this);

  @DomName('HTMLAreaElement.hostname')
  @DocsEditable()
  void set hostname(String value) => _blink.BlinkHTMLAreaElement.instance.hostname_Setter_(this, value);

  @DomName('HTMLAreaElement.href')
  @DocsEditable()
  String get href => _blink.BlinkHTMLAreaElement.instance.href_Getter_(this);

  @DomName('HTMLAreaElement.href')
  @DocsEditable()
  void set href(String value) => _blink.BlinkHTMLAreaElement.instance.href_Setter_(this, value);

  @DomName('HTMLAreaElement.origin')
  @DocsEditable()
  @Experimental() // untriaged
  String get origin => _blink.BlinkHTMLAreaElement.instance.origin_Getter_(this);

  @DomName('HTMLAreaElement.password')
  @DocsEditable()
  @Experimental() // untriaged
  String get password => _blink.BlinkHTMLAreaElement.instance.password_Getter_(this);

  @DomName('HTMLAreaElement.password')
  @DocsEditable()
  @Experimental() // untriaged
  void set password(String value) => _blink.BlinkHTMLAreaElement.instance.password_Setter_(this, value);

  @DomName('HTMLAreaElement.pathname')
  @DocsEditable()
  String get pathname => _blink.BlinkHTMLAreaElement.instance.pathname_Getter_(this);

  @DomName('HTMLAreaElement.pathname')
  @DocsEditable()
  void set pathname(String value) => _blink.BlinkHTMLAreaElement.instance.pathname_Setter_(this, value);

  @DomName('HTMLAreaElement.port')
  @DocsEditable()
  String get port => _blink.BlinkHTMLAreaElement.instance.port_Getter_(this);

  @DomName('HTMLAreaElement.port')
  @DocsEditable()
  void set port(String value) => _blink.BlinkHTMLAreaElement.instance.port_Setter_(this, value);

  @DomName('HTMLAreaElement.protocol')
  @DocsEditable()
  String get protocol => _blink.BlinkHTMLAreaElement.instance.protocol_Getter_(this);

  @DomName('HTMLAreaElement.protocol')
  @DocsEditable()
  void set protocol(String value) => _blink.BlinkHTMLAreaElement.instance.protocol_Setter_(this, value);

  @DomName('HTMLAreaElement.search')
  @DocsEditable()
  String get search => _blink.BlinkHTMLAreaElement.instance.search_Getter_(this);

  @DomName('HTMLAreaElement.search')
  @DocsEditable()
  void set search(String value) => _blink.BlinkHTMLAreaElement.instance.search_Setter_(this, value);

  @DomName('HTMLAreaElement.username')
  @DocsEditable()
  @Experimental() // untriaged
  String get username => _blink.BlinkHTMLAreaElement.instance.username_Getter_(this);

  @DomName('HTMLAreaElement.username')
  @DocsEditable()
  @Experimental() // untriaged
  void set username(String value) => _blink.BlinkHTMLAreaElement.instance.username_Setter_(this, value);

  @DomName('HTMLAreaElement.toString')
  @DocsEditable()
  @Experimental() // untriaged
  String toString() => _blink.BlinkHTMLAreaElement.instance.toString_Callback_0_(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.


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

  @DomName('HTMLAudioElement.HTMLAudioElement')
  @DocsEditable()
  factory AudioElement([String src]) {
    return _blink.BlinkHTMLAudioElement.instance.constructorCallback_1_(src);
  }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  AudioElement.created() : super.created();

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

// WARNING: Do not edit - generated code.


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

  @DomName('AudioTrack.enabled')
  @DocsEditable()
  @Experimental() // untriaged
  bool get enabled => _blink.BlinkAudioTrack.instance.enabled_Getter_(this);

  @DomName('AudioTrack.enabled')
  @DocsEditable()
  @Experimental() // untriaged
  void set enabled(bool value) => _blink.BlinkAudioTrack.instance.enabled_Setter_(this, value);

  @DomName('AudioTrack.id')
  @DocsEditable()
  @Experimental() // untriaged
  String get id => _blink.BlinkAudioTrack.instance.id_Getter_(this);

  @DomName('AudioTrack.kind')
  @DocsEditable()
  @Experimental() // untriaged
  String get kind => _blink.BlinkAudioTrack.instance.kind_Getter_(this);

  @DomName('AudioTrack.label')
  @DocsEditable()
  @Experimental() // untriaged
  String get label => _blink.BlinkAudioTrack.instance.label_Getter_(this);

  @DomName('AudioTrack.language')
  @DocsEditable()
  @Experimental() // untriaged
  String get language => _blink.BlinkAudioTrack.instance.language_Getter_(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.


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

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

  @DomName('AudioTrackList.length')
  @DocsEditable()
  @Experimental() // untriaged
  int get length => _blink.BlinkAudioTrackList.instance.length_Getter_(this);

  @DomName('AudioTrackList.__getter__')
  @DocsEditable()
  @Experimental() // untriaged
  AudioTrack __getter__(int index) => _blink.BlinkAudioTrackList.instance.$__getter___Callback_1_(this, index);

  @DomName('AudioTrackList.getTrackById')
  @DocsEditable()
  @Experimental() // untriaged
  AudioTrack getTrackById(String id) => _blink.BlinkAudioTrackList.instance.getTrackById_Callback_1_(this, id);

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

// WARNING: Do not edit - generated code.


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

  @DomName('AutocompleteErrorEvent.reason')
  @DocsEditable()
  String get reason => _blink.BlinkAutocompleteErrorEvent.instance.reason_Getter_(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.


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

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

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

// WARNING: Do not edit - generated code.


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

  @DomName('BarProp.visible')
  @DocsEditable()
  bool get visible => _blink.BlinkBarProp.instance.visible_Getter_(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.


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

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

  @DomName('HTMLBaseElement.href')
  @DocsEditable()
  String get href => _blink.BlinkHTMLBaseElement.instance.href_Getter_(this);

  @DomName('HTMLBaseElement.href')
  @DocsEditable()
  void set href(String value) => _blink.BlinkHTMLBaseElement.instance.href_Setter_(this, value);

  @DomName('HTMLBaseElement.target')
  @DocsEditable()
  String get target => _blink.BlinkHTMLBaseElement.instance.target_Getter_(this);

  @DomName('HTMLBaseElement.target')
  @DocsEditable()
  void set target(String value) => _blink.BlinkHTMLBaseElement.instance.target_Setter_(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.

// WARNING: Do not edit - generated code.


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

  @DomName('BatteryManager.charging')
  @DocsEditable()
  bool get charging => _blink.BlinkBatteryManager.instance.charging_Getter_(this);

  @DomName('BatteryManager.chargingTime')
  @DocsEditable()
  double get chargingTime => _blink.BlinkBatteryManager.instance.chargingTime_Getter_(this);

  @DomName('BatteryManager.dischargingTime')
  @DocsEditable()
  double get dischargingTime => _blink.BlinkBatteryManager.instance.dischargingTime_Getter_(this);

  @DomName('BatteryManager.level')
  @DocsEditable()
  double get level => _blink.BlinkBatteryManager.instance.level_Getter_(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.


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

  @DomName('BeforeUnloadEvent.returnValue')
  @DocsEditable()
  String get returnValue => _blink.BlinkBeforeUnloadEvent.instance.returnValue_Getter_(this);

  @DomName('BeforeUnloadEvent.returnValue')
  @DocsEditable()
  void set returnValue(String value) => _blink.BlinkBeforeUnloadEvent.instance.returnValue_Setter_(this, value);

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


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

  @DomName('Blob.Blob')
  @DocsEditable()
  factory Blob(List blobParts, [String type, String endings]) => _create(blobParts, type, endings);

  @DocsEditable()
  static Blob _create(blobParts, type, endings) => _blink.BlinkBlob.instance.constructorCallback_3_(blobParts, type, endings);

  @DomName('Blob.size')
  @DocsEditable()
  int get size => _blink.BlinkBlob.instance.size_Getter_(this);

  @DomName('Blob.type')
  @DocsEditable()
  String get type => _blink.BlinkBlob.instance.type_Getter_(this);

  @DomName('Blob.close')
  @DocsEditable()
  @Experimental() // untriaged
  void close() => _blink.BlinkBlob.instance.close_Callback_0_(this);

  Blob slice([int start, int end, String contentType]) {
    if (contentType != null) {
      return _blink.BlinkBlob.instance.slice_Callback_3_(this, start, end, contentType);
    }
    if (end != null) {
      return _blink.BlinkBlob.instance.slice_Callback_2_(this, start, end);
    }
    if (start != null) {
      return _blink.BlinkBlob.instance.slice_Callback_1_(this, start);
    }
    return _blink.BlinkBlob.instance.slice_Callback_0_(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.


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// WARNING: Do not edit - generated code.


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

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

  @DomName('HTMLButtonElement.autofocus')
  @DocsEditable()
  bool get autofocus => _blink.BlinkHTMLButtonElement.instance.autofocus_Getter_(this);

  @DomName('HTMLButtonElement.autofocus')
  @DocsEditable()
  void set autofocus(bool value) => _blink.BlinkHTMLButtonElement.instance.autofocus_Setter_(this, value);

  @DomName('HTMLButtonElement.disabled')
  @DocsEditable()
  bool get disabled => _blink.BlinkHTMLButtonElement.instance.disabled_Getter_(this);

  @DomName('HTMLButtonElement.disabled')
  @DocsEditable()
  void set disabled(bool value) => _blink.BlinkHTMLButtonElement.instance.disabled_Setter_(this, value);

  @DomName('HTMLButtonElement.form')
  @DocsEditable()
  FormElement get form => _blink.BlinkHTMLButtonElement.instance.form_Getter_(this);

  @DomName('HTMLButtonElement.formAction')
  @DocsEditable()
  String get formAction => _blink.BlinkHTMLButtonElement.instance.formAction_Getter_(this);

  @DomName('HTMLButtonElement.formAction')
  @DocsEditable()
  void set formAction(String value) => _blink.BlinkHTMLButtonElement.instance.formAction_Setter_(this, value);

  @DomName('HTMLButtonElement.formEnctype')
  @DocsEditable()
  String get formEnctype => _blink.BlinkHTMLButtonElement.instance.formEnctype_Getter_(this);

  @DomName('HTMLButtonElement.formEnctype')
  @DocsEditable()
  void set formEnctype(String value) => _blink.BlinkHTMLButtonElement.instance.formEnctype_Setter_(this, value);

  @DomName('HTMLButtonElement.formMethod')
  @DocsEditable()
  String get formMethod => _blink.BlinkHTMLButtonElement.instance.formMethod_Getter_(this);

  @DomName('HTMLButtonElement.formMethod')
  @DocsEditable()
  void set formMethod(String value) => _blink.BlinkHTMLButtonElement.instance.formMethod_Setter_(this, value);

  @DomName('HTMLButtonElement.formNoValidate')
  @DocsEditable()
  bool get formNoValidate => _blink.BlinkHTMLButtonElement.instance.formNoValidate_Getter_(this);

  @DomName('HTMLButtonElement.formNoValidate')
  @DocsEditable()
  void set formNoValidate(bool value) => _blink.BlinkHTMLButtonElement.instance.formNoValidate_Setter_(this, value);

  @DomName('HTMLButtonElement.formTarget')
  @DocsEditable()
  String get formTarget => _blink.BlinkHTMLButtonElement.instance.formTarget_Getter_(this);

  @DomName('HTMLButtonElement.formTarget')
  @DocsEditable()
  void set formTarget(String value) => _blink.BlinkHTMLButtonElement.instance.formTarget_Setter_(this, value);

  @DomName('HTMLButtonElement.labels')
  @DocsEditable()
  @Unstable()
  List<Node> get labels => _blink.BlinkHTMLButtonElement.instance.labels_Getter_(this);

  @DomName('HTMLButtonElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLButtonElement.instance.name_Getter_(this);

  @DomName('HTMLButtonElement.name')
  @DocsEditable()
  void set name(String value) => _blink.BlinkHTMLButtonElement.instance.name_Setter_(this, value);

  @DomName('HTMLButtonElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLButtonElement.instance.type_Getter_(this);

  @DomName('HTMLButtonElement.type')
  @DocsEditable()
  void set type(String value) => _blink.BlinkHTMLButtonElement.instance.type_Setter_(this, value);

  @DomName('HTMLButtonElement.validationMessage')
  @DocsEditable()
  String get validationMessage => _blink.BlinkHTMLButtonElement.instance.validationMessage_Getter_(this);

  @DomName('HTMLButtonElement.validity')
  @DocsEditable()
  ValidityState get validity => _blink.BlinkHTMLButtonElement.instance.validity_Getter_(this);

  @DomName('HTMLButtonElement.value')
  @DocsEditable()
  String get value => _blink.BlinkHTMLButtonElement.instance.value_Getter_(this);

  @DomName('HTMLButtonElement.value')
  @DocsEditable()
  void set value(String value) => _blink.BlinkHTMLButtonElement.instance.value_Setter_(this, value);

  @DomName('HTMLButtonElement.willValidate')
  @DocsEditable()
  bool get willValidate => _blink.BlinkHTMLButtonElement.instance.willValidate_Getter_(this);

  @DomName('HTMLButtonElement.checkValidity')
  @DocsEditable()
  bool checkValidity() => _blink.BlinkHTMLButtonElement.instance.checkValidity_Callback_0_(this);

  @DomName('HTMLButtonElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) => _blink.BlinkHTMLButtonElement.instance.setCustomValidity_Callback_1_(this, 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.


@DocsEditable()
@DomName('CDATASection')
// http://dom.spec.whatwg.org/#cdatasection
@deprecated // deprecated
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.

// WARNING: Do not edit - generated code.


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

  @DomName('CacheStorage.create')
  @DocsEditable()
  @Experimental() // untriaged
  Future create(String cacheName) => _blink.BlinkCacheStorage.instance.create_Callback_1_(this, cacheName);

  @DomName('CacheStorage.delete')
  @DocsEditable()
  @Experimental() // untriaged
  Future delete(String cacheName) => _blink.BlinkCacheStorage.instance.delete_Callback_1_(this, cacheName);

  @DomName('CacheStorage.get')
  @DocsEditable()
  @Experimental() // untriaged
  Future get(String cacheName) => _blink.BlinkCacheStorage.instance.get_Callback_1_(this, cacheName);

  @DomName('CacheStorage.has')
  @DocsEditable()
  @Experimental() // untriaged
  Future has(String cacheName) => _blink.BlinkCacheStorage.instance.has_Callback_1_(this, cacheName);

  @DomName('CacheStorage.keys')
  @DocsEditable()
  @Experimental() // untriaged
  Future keys() => _blink.BlinkCacheStorage.instance.keys_Callback_0_(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.


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

  @DomName('Canvas2DContextAttributes.alpha')
  @DocsEditable()
  bool get alpha => _blink.BlinkCanvas2DContextAttributes.instance.alpha_Getter_(this);

  @DomName('Canvas2DContextAttributes.alpha')
  @DocsEditable()
  void set alpha(bool value) => _blink.BlinkCanvas2DContextAttributes.instance.alpha_Setter_(this, value);

  @DomName('Canvas2DContextAttributes.storage')
  @DocsEditable()
  @Experimental() // untriaged
  String get storage => _blink.BlinkCanvas2DContextAttributes.instance.storage_Getter_(this);

  @DomName('Canvas2DContextAttributes.storage')
  @DocsEditable()
  @Experimental() // untriaged
  void set storage(String value) => _blink.BlinkCanvas2DContextAttributes.instance.storage_Setter_(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('HTMLCanvasElement')
class CanvasElement extends HtmlElement implements CanvasImageSource {
  // To suppress missing implicit constructor warnings.
  factory CanvasElement._() { throw new UnsupportedError("Not supported"); }

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

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

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

  /// The height of this canvas element in CSS pixels.
  @DomName('HTMLCanvasElement.height')
  @DocsEditable()
  int get height => _blink.BlinkHTMLCanvasElement.instance.height_Getter_(this);

  /// The height of this canvas element in CSS pixels.
  @DomName('HTMLCanvasElement.height')
  @DocsEditable()
  void set height(int value) => _blink.BlinkHTMLCanvasElement.instance.height_Setter_(this, value);

  /// The width of this canvas element in CSS pixels.
  @DomName('HTMLCanvasElement.width')
  @DocsEditable()
  int get width => _blink.BlinkHTMLCanvasElement.instance.width_Getter_(this);

  /// The width of this canvas element in CSS pixels.
  @DomName('HTMLCanvasElement.width')
  @DocsEditable()
  void set width(int value) => _blink.BlinkHTMLCanvasElement.instance.width_Setter_(this, value);

  @DomName('HTMLCanvasElement.getContext')
  @DocsEditable()
  Object getContext(String contextId, [Map attrs]) => _blink.BlinkHTMLCanvasElement.instance.getContext_Callback_2_(this, contextId, attrs);

  @DomName('HTMLCanvasElement.toDataURL')
  @DocsEditable()
  String _toDataUrl(String type, [num quality]) => _blink.BlinkHTMLCanvasElement.instance.toDataURL_Callback_2_(this, type, quality);

  /// 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 => getContext('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.

// WARNING: Do not edit - generated code.


@DocsEditable()
/**
 * An opaque canvas object representing a gradient.
 *
 * Created by calling [createLinearGradient] or [createRadialGradient] on a
 * [CanvasRenderingContext2D] object.
 *
 * Example usage:
 *
 *     var canvas = new CanvasElement(width: 600, height: 600);
 *     var ctx = canvas.context2D;
 *     ctx.clearRect(0, 0, 600, 600);
 *     ctx.save();
 *     // Create radial gradient.
 *     CanvasGradient gradient = ctx.createRadialGradient(0, 0, 0, 0, 0, 600);
 *     gradient.addColorStop(0, '#000');
 *     gradient.addColorStop(1, 'rgb(255, 255, 255)');
 *     // Assign gradients to fill.
 *     ctx.fillStyle = gradient;
 *     // Draw a rectangle with a gradient fill.
 *     ctx.fillRect(0, 0, 600, 600);
 *     ctx.save();
 *     document.body.children.add(canvas);
 *
 * See also:
 *
 * * [CanvasGradient](https://developer.mozilla.org/en-US/docs/DOM/CanvasGradient) from MDN.
 * * [CanvasGradient](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvasgradient) from whatwg.
 * * [CanvasGradient](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvasgradient) from W3C.
 */
@DomName('CanvasGradient')
class CanvasGradient extends NativeFieldWrapperClass2 {
  // 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) => _blink.BlinkCanvasGradient.instance.addColorStop_Callback_2_(this, offset, color);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

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


abstract class CanvasRenderingContext {
  CanvasElement get canvas;
}

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

  @DomName('CanvasRenderingContext2D.canvas')
  @DocsEditable()
  @Experimental() // untriaged
  CanvasElement get canvas => _blink.BlinkCanvasRenderingContext2D.instance.canvas_Getter_(this);

  @DomName('CanvasRenderingContext2D.currentTransform')
  @DocsEditable()
  @Experimental() // untriaged
  Matrix get currentTransform => _blink.BlinkCanvasRenderingContext2D.instance.currentTransform_Getter_(this);

  @DomName('CanvasRenderingContext2D.currentTransform')
  @DocsEditable()
  @Experimental() // untriaged
  void set currentTransform(Matrix value) => _blink.BlinkCanvasRenderingContext2D.instance.currentTransform_Setter_(this, value);

  @DomName('CanvasRenderingContext2D.fillStyle')
  @DocsEditable()
  Object get fillStyle => _blink.BlinkCanvasRenderingContext2D.instance.fillStyle_Getter_(this);

  @DomName('CanvasRenderingContext2D.fillStyle')
  @DocsEditable()
  void set fillStyle(Object value) => _blink.BlinkCanvasRenderingContext2D.instance.fillStyle_Setter_(this, value);

  @DomName('CanvasRenderingContext2D.font')
  @DocsEditable()
  String get font => _blink.BlinkCanvasRenderingContext2D.instance.font_Getter_(this);

  @DomName('CanvasRenderingContext2D.font')
  @DocsEditable()
  void set font(String value) => _blink.BlinkCanvasRenderingContext2D.instance.font_Setter_(this, value);

  @DomName('CanvasRenderingContext2D.globalAlpha')
  @DocsEditable()
  num get globalAlpha => _blink.BlinkCanvasRenderingContext2D.instance.globalAlpha_Getter_(this);

  @DomName('CanvasRenderingContext2D.globalAlpha')
  @DocsEditable()
  void set globalAlpha(num value) => _blink.BlinkCanvasRenderingContext2D.instance.globalAlpha_Setter_(this, value);

  @DomName('CanvasRenderingContext2D.globalCompositeOperation')
  @DocsEditable()
  String get globalCompositeOperation => _blink.BlinkCanvasRenderingContext2D.instance.globalCompositeOperation_Getter_(this);

  @DomName('CanvasRenderingContext2D.globalCompositeOperation')
  @DocsEditable()
  void set globalCompositeOperation(String value) => _blink.BlinkCanvasRenderingContext2D.instance.globalCompositeOperation_Setter_(this, value);

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

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

  @DomName('CanvasRenderingContext2D.lineCap')
  @DocsEditable()
  String get lineCap => _blink.BlinkCanvasRenderingContext2D.instance.lineCap_Getter_(this);

  @DomName('CanvasRenderingContext2D.lineCap')
  @DocsEditable()
  void set lineCap(String value) => _blink.BlinkCanvasRenderingContext2D.instance.lineCap_Setter_(this, value);

  @DomName('CanvasRenderingContext2D.lineDashOffset')
  @DocsEditable()
  num get lineDashOffset => _blink.BlinkCanvasRenderingContext2D.instance.lineDashOffset_Getter_(this);

  @DomName('CanvasRenderingContext2D.lineDashOffset')
  @DocsEditable()
  void set lineDashOffset(num value) => _blink.BlinkCanvasRenderingContext2D.instance.lineDashOffset_Setter_(this, value);

  @DomName('CanvasRenderingContext2D.lineJoin')
  @DocsEditable()
  String get lineJoin => _blink.BlinkCanvasRenderingContext2D.instance.lineJoin_Getter_(this);

  @DomName('CanvasRenderingContext2D.lineJoin')
  @DocsEditable()
  void set lineJoin(String value) => _blink.BlinkCanvasRenderingContext2D.instance.lineJoin_Setter_(this, value);

  @DomName('CanvasRenderingContext2D.lineWidth')
  @DocsEditable()
  num get lineWidth => _blink.BlinkCanvasRenderingContext2D.instance.lineWidth_Getter_(this);

  @DomName('CanvasRenderingContext2D.lineWidth')
  @DocsEditable()
  void set lineWidth(num value) => _blink.BlinkCanvasRenderingContext2D.instance.lineWidth_Setter_(this, value);

  @DomName('CanvasRenderingContext2D.miterLimit')
  @DocsEditable()
  num get miterLimit => _blink.BlinkCanvasRenderingContext2D.instance.miterLimit_Getter_(this);

  @DomName('CanvasRenderingContext2D.miterLimit')
  @DocsEditable()
  void set miterLimit(num value) => _blink.BlinkCanvasRenderingContext2D.instance.miterLimit_Setter_(this, value);

  @DomName('CanvasRenderingContext2D.shadowBlur')
  @DocsEditable()
  num get shadowBlur => _blink.BlinkCanvasRenderingContext2D.instance.shadowBlur_Getter_(this);

  @DomName('CanvasRenderingContext2D.shadowBlur')
  @DocsEditable()
  void set shadowBlur(num value) => _blink.BlinkCanvasRenderingContext2D.instance.shadowBlur_Setter_(this, value);

  @DomName('CanvasRenderingContext2D.shadowColor')
  @DocsEditable()
  String get shadowColor => _blink.BlinkCanvasRenderingContext2D.instance.shadowColor_Getter_(this);

  @DomName('CanvasRenderingContext2D.shadowColor')
  @DocsEditable()
  void set shadowColor(String value) => _blink.BlinkCanvasRenderingContext2D.instance.shadowColor_Setter_(this, value);

  @DomName('CanvasRenderingContext2D.shadowOffsetX')
  @DocsEditable()
  num get shadowOffsetX => _blink.BlinkCanvasRenderingContext2D.instance.shadowOffsetX_Getter_(this);

  @DomName('CanvasRenderingContext2D.shadowOffsetX')
  @DocsEditable()
  void set shadowOffsetX(num value) => _blink.BlinkCanvasRenderingContext2D.instance.shadowOffsetX_Setter_(this, value);

  @DomName('CanvasRenderingContext2D.shadowOffsetY')
  @DocsEditable()
  num get shadowOffsetY => _blink.BlinkCanvasRenderingContext2D.instance.shadowOffsetY_Getter_(this);

  @DomName('CanvasRenderingContext2D.shadowOffsetY')
  @DocsEditable()
  void set shadowOffsetY(num value) => _blink.BlinkCanvasRenderingContext2D.instance.shadowOffsetY_Setter_(this, value);

  @DomName('CanvasRenderingContext2D.strokeStyle')
  @DocsEditable()
  Object get strokeStyle => _blink.BlinkCanvasRenderingContext2D.instance.strokeStyle_Getter_(this);

  @DomName('CanvasRenderingContext2D.strokeStyle')
  @DocsEditable()
  void set strokeStyle(Object value) => _blink.BlinkCanvasRenderingContext2D.instance.strokeStyle_Setter_(this, value);

  @DomName('CanvasRenderingContext2D.textAlign')
  @DocsEditable()
  String get textAlign => _blink.BlinkCanvasRenderingContext2D.instance.textAlign_Getter_(this);

  @DomName('CanvasRenderingContext2D.textAlign')
  @DocsEditable()
  void set textAlign(String value) => _blink.BlinkCanvasRenderingContext2D.instance.textAlign_Setter_(this, value);

  @DomName('CanvasRenderingContext2D.textBaseline')
  @DocsEditable()
  String get textBaseline => _blink.BlinkCanvasRenderingContext2D.instance.textBaseline_Getter_(this);

  @DomName('CanvasRenderingContext2D.textBaseline')
  @DocsEditable()
  void set textBaseline(String value) => _blink.BlinkCanvasRenderingContext2D.instance.textBaseline_Setter_(this, value);

  void addHitRegion([Map options]) {
    if (options != null) {
      _blink.BlinkCanvasRenderingContext2D.instance.addHitRegion_Callback_1_(this, options);
      return;
    }
    _blink.BlinkCanvasRenderingContext2D.instance.addHitRegion_Callback_0_(this);
    return;
  }

  @DomName('CanvasRenderingContext2D.beginPath')
  @DocsEditable()
  void beginPath() => _blink.BlinkCanvasRenderingContext2D.instance.beginPath_Callback_0_(this);

  @DomName('CanvasRenderingContext2D.clearHitRegions')
  @DocsEditable()
  @Experimental() // untriaged
  void clearHitRegions() => _blink.BlinkCanvasRenderingContext2D.instance.clearHitRegions_Callback_0_(this);

  @DomName('CanvasRenderingContext2D.clearRect')
  @DocsEditable()
  void clearRect(num x, num y, num width, num height) => _blink.BlinkCanvasRenderingContext2D.instance.clearRect_Callback_4_(this, x, y, width, height);

  void clip([path_OR_winding, String winding]) {
    if (path_OR_winding == null && winding == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.clip_Callback_0_(this);
      return;
    }
    if ((path_OR_winding is String) && winding == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.clip_Callback_1_(this, path_OR_winding);
      return;
    }
    if ((path_OR_winding is Path2D) && winding == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.clip_Callback_1_(this, path_OR_winding);
      return;
    }
    if ((winding is String) && (path_OR_winding is Path2D)) {
      _blink.BlinkCanvasRenderingContext2D.instance.clip_Callback_2_(this, path_OR_winding, winding);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('CanvasRenderingContext2D.createImageData')
  @DocsEditable()
  ImageData createImageData(num sw, num sh) => _blink.BlinkCanvasRenderingContext2D.instance.createImageData_Callback_2_(this, sw, sh);

  @DomName('CanvasRenderingContext2D.createImageDataFromImageData')
  @DocsEditable()
  ImageData createImageDataFromImageData(ImageData imagedata) => _blink.BlinkCanvasRenderingContext2D.instance.createImageData_Callback_1_(this, imagedata);

  @DomName('CanvasRenderingContext2D.createLinearGradient')
  @DocsEditable()
  CanvasGradient createLinearGradient(num x0, num y0, num x1, num y1) => _blink.BlinkCanvasRenderingContext2D.instance.createLinearGradient_Callback_4_(this, x0, y0, x1, y1);

  CanvasPattern createPattern(canvas_OR_image, String repetitionType) {
    if ((repetitionType is String || repetitionType == null) && (canvas_OR_image is CanvasElement)) {
      return _blink.BlinkCanvasRenderingContext2D.instance.createPattern_Callback_2_(this, canvas_OR_image, repetitionType);
    }
    if ((repetitionType is String || repetitionType == null) && (canvas_OR_image is VideoElement)) {
      return _blink.BlinkCanvasRenderingContext2D.instance.createPattern_Callback_2_(this, canvas_OR_image, repetitionType);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('CanvasRenderingContext2D.createPatternFromImage')
  @DocsEditable()
  CanvasPattern createPatternFromImage(ImageElement image, String repetitionType) => _blink.BlinkCanvasRenderingContext2D.instance.createPattern_Callback_2_(this, image, repetitionType);

  @DomName('CanvasRenderingContext2D.createRadialGradient')
  @DocsEditable()
  CanvasGradient createRadialGradient(num x0, num y0, num r0, num x1, num y1, num r1) => _blink.BlinkCanvasRenderingContext2D.instance.createRadialGradient_Callback_6_(this, x0, y0, r0, x1, y1, r1);

  void drawFocusIfNeeded(element_OR_path, [Element element]) {
    if ((element_OR_path is Element) && element == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawFocusIfNeeded_Callback_1_(this, element_OR_path);
      return;
    }
    if ((element is Element) && (element_OR_path is Path2D)) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawFocusIfNeeded_Callback_2_(this, element_OR_path, element);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  void _drawImage(canvas_OR_image_OR_imageBitmap_OR_video, num sx_OR_x, num sy_OR_y, [num sw_OR_width, num height_OR_sh, num dx, num dy, num dw, num dh]) {
    if ((sy_OR_y is num) && (sx_OR_x is num) && (canvas_OR_image_OR_imageBitmap_OR_video is ImageElement) && sw_OR_width == null && height_OR_sh == null && dx == null && dy == null && dw == null && dh == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_3_(this, canvas_OR_image_OR_imageBitmap_OR_video, sx_OR_x, sy_OR_y);
      return;
    }
    if ((height_OR_sh is num) && (sw_OR_width is num) && (sy_OR_y is num) && (sx_OR_x is num) && (canvas_OR_image_OR_imageBitmap_OR_video is ImageElement) && dx == null && dy == null && dw == null && dh == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_5_(this, canvas_OR_image_OR_imageBitmap_OR_video, sx_OR_x, sy_OR_y, sw_OR_width, height_OR_sh);
      return;
    }
    if ((dh is num) && (dw is num) && (dy is num) && (dx is num) && (height_OR_sh is num) && (sw_OR_width is num) && (sy_OR_y is num) && (sx_OR_x is num) && (canvas_OR_image_OR_imageBitmap_OR_video is ImageElement)) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_9_(this, canvas_OR_image_OR_imageBitmap_OR_video, sx_OR_x, sy_OR_y, sw_OR_width, height_OR_sh, dx, dy, dw, dh);
      return;
    }
    if ((sy_OR_y is num) && (sx_OR_x is num) && (canvas_OR_image_OR_imageBitmap_OR_video is CanvasElement) && sw_OR_width == null && height_OR_sh == null && dx == null && dy == null && dw == null && dh == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_3_(this, canvas_OR_image_OR_imageBitmap_OR_video, sx_OR_x, sy_OR_y);
      return;
    }
    if ((height_OR_sh is num) && (sw_OR_width is num) && (sy_OR_y is num) && (sx_OR_x is num) && (canvas_OR_image_OR_imageBitmap_OR_video is CanvasElement) && dx == null && dy == null && dw == null && dh == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_5_(this, canvas_OR_image_OR_imageBitmap_OR_video, sx_OR_x, sy_OR_y, sw_OR_width, height_OR_sh);
      return;
    }
    if ((dh is num) && (dw is num) && (dy is num) && (dx is num) && (height_OR_sh is num) && (sw_OR_width is num) && (sy_OR_y is num) && (sx_OR_x is num) && (canvas_OR_image_OR_imageBitmap_OR_video is CanvasElement)) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_9_(this, canvas_OR_image_OR_imageBitmap_OR_video, sx_OR_x, sy_OR_y, sw_OR_width, height_OR_sh, dx, dy, dw, dh);
      return;
    }
    if ((sy_OR_y is num) && (sx_OR_x is num) && (canvas_OR_image_OR_imageBitmap_OR_video is VideoElement) && sw_OR_width == null && height_OR_sh == null && dx == null && dy == null && dw == null && dh == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_3_(this, canvas_OR_image_OR_imageBitmap_OR_video, sx_OR_x, sy_OR_y);
      return;
    }
    if ((height_OR_sh is num) && (sw_OR_width is num) && (sy_OR_y is num) && (sx_OR_x is num) && (canvas_OR_image_OR_imageBitmap_OR_video is VideoElement) && dx == null && dy == null && dw == null && dh == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_5_(this, canvas_OR_image_OR_imageBitmap_OR_video, sx_OR_x, sy_OR_y, sw_OR_width, height_OR_sh);
      return;
    }
    if ((dh is num) && (dw is num) && (dy is num) && (dx is num) && (height_OR_sh is num) && (sw_OR_width is num) && (sy_OR_y is num) && (sx_OR_x is num) && (canvas_OR_image_OR_imageBitmap_OR_video is VideoElement)) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_9_(this, canvas_OR_image_OR_imageBitmap_OR_video, sx_OR_x, sy_OR_y, sw_OR_width, height_OR_sh, dx, dy, dw, dh);
      return;
    }
    if ((sy_OR_y is num) && (sx_OR_x is num) && (canvas_OR_image_OR_imageBitmap_OR_video is ImageBitmap) && sw_OR_width == null && height_OR_sh == null && dx == null && dy == null && dw == null && dh == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_3_(this, canvas_OR_image_OR_imageBitmap_OR_video, sx_OR_x, sy_OR_y);
      return;
    }
    if ((height_OR_sh is num) && (sw_OR_width is num) && (sy_OR_y is num) && (sx_OR_x is num) && (canvas_OR_image_OR_imageBitmap_OR_video is ImageBitmap) && dx == null && dy == null && dw == null && dh == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_5_(this, canvas_OR_image_OR_imageBitmap_OR_video, sx_OR_x, sy_OR_y, sw_OR_width, height_OR_sh);
      return;
    }
    if ((dh is num) && (dw is num) && (dy is num) && (dx is num) && (height_OR_sh is num) && (sw_OR_width is num) && (sy_OR_y is num) && (sx_OR_x is num) && (canvas_OR_image_OR_imageBitmap_OR_video is ImageBitmap)) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_9_(this, canvas_OR_image_OR_imageBitmap_OR_video, sx_OR_x, sy_OR_y, sw_OR_width, height_OR_sh, dx, dy, dw, dh);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  void fill([path_OR_winding, String winding]) {
    if (path_OR_winding == null && winding == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.fill_Callback_0_(this);
      return;
    }
    if ((path_OR_winding is String) && winding == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.fill_Callback_1_(this, path_OR_winding);
      return;
    }
    if ((path_OR_winding is Path2D) && winding == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.fill_Callback_1_(this, path_OR_winding);
      return;
    }
    if ((winding is String) && (path_OR_winding is Path2D)) {
      _blink.BlinkCanvasRenderingContext2D.instance.fill_Callback_2_(this, path_OR_winding, winding);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('CanvasRenderingContext2D.fillRect')
  @DocsEditable()
  void fillRect(num x, num y, num width, num height) => _blink.BlinkCanvasRenderingContext2D.instance.fillRect_Callback_4_(this, x, y, width, height);

  void fillText(String text, num x, num y, [num maxWidth]) {
    if (maxWidth != null) {
      _blink.BlinkCanvasRenderingContext2D.instance.fillText_Callback_4_(this, text, x, y, maxWidth);
      return;
    }
    _blink.BlinkCanvasRenderingContext2D.instance.fillText_Callback_3_(this, text, x, y);
    return;
  }

  @DomName('CanvasRenderingContext2D.getContextAttributes')
  @DocsEditable()
  // http://wiki.whatwg.org/wiki/CanvasOpaque#Suggested_IDL
  @Experimental()
  Canvas2DContextAttributes getContextAttributes() => _blink.BlinkCanvasRenderingContext2D.instance.getContextAttributes_Callback_0_(this);

  @DomName('CanvasRenderingContext2D.getImageData')
  @DocsEditable()
  ImageData getImageData(num sx, num sy, num sw, num sh) => _blink.BlinkCanvasRenderingContext2D.instance.getImageData_Callback_4_(this, sx, sy, sw, sh);

  @DomName('CanvasRenderingContext2D.getLineDash')
  @DocsEditable()
  List<num> _getLineDash() => _blink.BlinkCanvasRenderingContext2D.instance.getLineDash_Callback_0_(this);

  @DomName('CanvasRenderingContext2D.isContextLost')
  @DocsEditable()
  @Experimental() // untriaged
  bool isContextLost() => _blink.BlinkCanvasRenderingContext2D.instance.isContextLost_Callback_0_(this);

  bool isPointInPath(path_OR_x, num x_OR_y, [winding_OR_y, String winding]) {
    if ((x_OR_y is num) && (path_OR_x is num) && winding_OR_y == null && winding == null) {
      return _blink.BlinkCanvasRenderingContext2D.instance.isPointInPath_Callback_2_(this, path_OR_x, x_OR_y);
    }
    if ((winding_OR_y is String) && (x_OR_y is num) && (path_OR_x is num) && winding == null) {
      return _blink.BlinkCanvasRenderingContext2D.instance.isPointInPath_Callback_3_(this, path_OR_x, x_OR_y, winding_OR_y);
    }
    if ((winding_OR_y is num) && (x_OR_y is num) && (path_OR_x is Path2D) && winding == null) {
      return _blink.BlinkCanvasRenderingContext2D.instance.isPointInPath_Callback_3_(this, path_OR_x, x_OR_y, winding_OR_y);
    }
    if ((winding is String) && (winding_OR_y is num) && (x_OR_y is num) && (path_OR_x is Path2D)) {
      return _blink.BlinkCanvasRenderingContext2D.instance.isPointInPath_Callback_4_(this, path_OR_x, x_OR_y, winding_OR_y, winding);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  bool isPointInStroke(path_OR_x, num x_OR_y, [num y]) {
    if ((x_OR_y is num) && (path_OR_x is num) && y == null) {
      return _blink.BlinkCanvasRenderingContext2D.instance.isPointInStroke_Callback_2_(this, path_OR_x, x_OR_y);
    }
    if ((y is num) && (x_OR_y is num) && (path_OR_x is Path2D)) {
      return _blink.BlinkCanvasRenderingContext2D.instance.isPointInStroke_Callback_3_(this, path_OR_x, x_OR_y, y);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('CanvasRenderingContext2D.measureText')
  @DocsEditable()
  TextMetrics measureText(String text) => _blink.BlinkCanvasRenderingContext2D.instance.measureText_Callback_1_(this, text);

  void putImageData(ImageData imagedata, num dx, num dy, [num dirtyX, num dirtyY, num dirtyWidth, num dirtyHeight]) {
    if ((dy is num) && (dx is num) && (imagedata is ImageData) && dirtyX == null && dirtyY == null && dirtyWidth == null && dirtyHeight == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.putImageData_Callback_3_(this, imagedata, dx, dy);
      return;
    }
    if ((dirtyHeight is num) && (dirtyWidth is num) && (dirtyY is num) && (dirtyX is num) && (dy is num) && (dx is num) && (imagedata is ImageData)) {
      _blink.BlinkCanvasRenderingContext2D.instance.putImageData_Callback_7_(this, imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('CanvasRenderingContext2D.removeHitRegion')
  @DocsEditable()
  @Experimental() // untriaged
  void removeHitRegion(String id) => _blink.BlinkCanvasRenderingContext2D.instance.removeHitRegion_Callback_1_(this, id);

  @DomName('CanvasRenderingContext2D.resetTransform')
  @DocsEditable()
  @Experimental() // untriaged
  void resetTransform() => _blink.BlinkCanvasRenderingContext2D.instance.resetTransform_Callback_0_(this);

  @DomName('CanvasRenderingContext2D.restore')
  @DocsEditable()
  void restore() => _blink.BlinkCanvasRenderingContext2D.instance.restore_Callback_0_(this);

  @DomName('CanvasRenderingContext2D.rotate')
  @DocsEditable()
  void rotate(num angle) => _blink.BlinkCanvasRenderingContext2D.instance.rotate_Callback_1_(this, angle);

  @DomName('CanvasRenderingContext2D.save')
  @DocsEditable()
  void save() => _blink.BlinkCanvasRenderingContext2D.instance.save_Callback_0_(this);

  @DomName('CanvasRenderingContext2D.scale')
  @DocsEditable()
  void scale(num x, num y) => _blink.BlinkCanvasRenderingContext2D.instance.scale_Callback_2_(this, x, y);

  void scrollPathIntoView([Path2D path]) {
    if (path != null) {
      _blink.BlinkCanvasRenderingContext2D.instance.scrollPathIntoView_Callback_1_(this, path);
      return;
    }
    _blink.BlinkCanvasRenderingContext2D.instance.scrollPathIntoView_Callback_0_(this);
    return;
  }

  @DomName('CanvasRenderingContext2D.setLineDash')
  @DocsEditable()
  void setLineDash(List<num> dash) => _blink.BlinkCanvasRenderingContext2D.instance.setLineDash_Callback_1_(this, dash);

  @DomName('CanvasRenderingContext2D.setTransform')
  @DocsEditable()
  void setTransform(num a, num b, num c, num d, num e, num f) => _blink.BlinkCanvasRenderingContext2D.instance.setTransform_Callback_6_(this, a, b, c, d, e, f);

  void stroke([Path2D path]) {
    if (path == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.stroke_Callback_0_(this);
      return;
    }
    if ((path is Path2D)) {
      _blink.BlinkCanvasRenderingContext2D.instance.stroke_Callback_1_(this, path);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('CanvasRenderingContext2D.strokeRect')
  @DocsEditable()
  void strokeRect(num x, num y, num width, num height) => _blink.BlinkCanvasRenderingContext2D.instance.strokeRect_Callback_4_(this, x, y, width, height);

  void strokeText(String text, num x, num y, [num maxWidth]) {
    if (maxWidth != null) {
      _blink.BlinkCanvasRenderingContext2D.instance.strokeText_Callback_4_(this, text, x, y, maxWidth);
      return;
    }
    _blink.BlinkCanvasRenderingContext2D.instance.strokeText_Callback_3_(this, text, x, y);
    return;
  }

  @DomName('CanvasRenderingContext2D.transform')
  @DocsEditable()
  void transform(num a, num b, num c, num d, num e, num f) => _blink.BlinkCanvasRenderingContext2D.instance.transform_Callback_6_(this, a, b, c, d, e, f);

  @DomName('CanvasRenderingContext2D.translate')
  @DocsEditable()
  void translate(num x, num y) => _blink.BlinkCanvasRenderingContext2D.instance.translate_Callback_2_(this, x, y);

  @DomName('CanvasRenderingContext2D.arc')
  @DocsEditable()
  void _arc(num x, num y, num radius, num startAngle, num endAngle, bool anticlockwise) => _blink.BlinkCanvasRenderingContext2D.instance.arc_Callback_6_(this, x, y, radius, startAngle, endAngle, anticlockwise);

  @DomName('CanvasRenderingContext2D.arcTo')
  @DocsEditable()
  void arcTo(num x1, num y1, num x2, num y2, num radius) => _blink.BlinkCanvasRenderingContext2D.instance.arcTo_Callback_5_(this, x1, y1, x2, y2, radius);

  @DomName('CanvasRenderingContext2D.bezierCurveTo')
  @DocsEditable()
  void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y, num x, num y) => _blink.BlinkCanvasRenderingContext2D.instance.bezierCurveTo_Callback_6_(this, cp1x, cp1y, cp2x, cp2y, x, y);

  @DomName('CanvasRenderingContext2D.closePath')
  @DocsEditable()
  void closePath() => _blink.BlinkCanvasRenderingContext2D.instance.closePath_Callback_0_(this);

  @DomName('CanvasRenderingContext2D.ellipse')
  @DocsEditable()
  @Experimental() // untriaged
  void ellipse(num x, num y, num radiusX, num radiusY, num rotation, num startAngle, num endAngle, bool anticlockwise) => _blink.BlinkCanvasRenderingContext2D.instance.ellipse_Callback_8_(this, x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise);

  @DomName('CanvasRenderingContext2D.lineTo')
  @DocsEditable()
  void lineTo(num x, num y) => _blink.BlinkCanvasRenderingContext2D.instance.lineTo_Callback_2_(this, x, y);

  @DomName('CanvasRenderingContext2D.moveTo')
  @DocsEditable()
  void moveTo(num x, num y) => _blink.BlinkCanvasRenderingContext2D.instance.moveTo_Callback_2_(this, x, y);

  @DomName('CanvasRenderingContext2D.quadraticCurveTo')
  @DocsEditable()
  void quadraticCurveTo(num cpx, num cpy, num x, num y) => _blink.BlinkCanvasRenderingContext2D.instance.quadraticCurveTo_Callback_4_(this, cpx, cpy, x, y);

  @DomName('CanvasRenderingContext2D.rect')
  @DocsEditable()
  void rect(num x, num y, num width, num height) => _blink.BlinkCanvasRenderingContext2D.instance.rect_Callback_4_(this, x, y, width, height);


  /**
   * 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.
    _arc(x, y, radius, startAngle, endAngle, anticlockwise);
  }

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

  /**
   * 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')
  void drawImageScaled(CanvasImageSource source,
      num destX, num destY, num destWidth, num destHeight) {
    _drawImage(source, destX, destY, destWidth, destHeight);
  }

  /**
   * 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')
  void drawImageScaledFromSource(CanvasImageSource source,
      num sourceX, num sourceY, num sourceWidth, num sourceHeight,
      num destX, num destY, num destWidth, num destHeight) {
    _drawImage(source, sourceX, sourceY, sourceWidth, sourceHeight,
        destX, destY, destWidth, destHeight);
  }

  // TODO(amouravski): Add Dartium native methods for drawImage once we figure
  // out how to not break native bindings.

  @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.
    var result = _getLineDash();
    if (result == null) {
      result = [];
    }
    return result;
  }



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

// WARNING: Do not edit - generated code.


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

  @DomName('CharacterData.data')
  @DocsEditable()
  String get data => _blink.BlinkCharacterData.instance.data_Getter_(this);

  @DomName('CharacterData.data')
  @DocsEditable()
  void set data(String value) => _blink.BlinkCharacterData.instance.data_Setter_(this, value);

  @DomName('CharacterData.length')
  @DocsEditable()
  int get length => _blink.BlinkCharacterData.instance.length_Getter_(this);

  @DomName('CharacterData.appendData')
  @DocsEditable()
  void appendData(String data) => _blink.BlinkCharacterData.instance.appendData_Callback_1_(this, data);

  @DomName('CharacterData.deleteData')
  @DocsEditable()
  void deleteData(int offset, int length) => _blink.BlinkCharacterData.instance.deleteData_Callback_2_(this, offset, length);

  @DomName('CharacterData.insertData')
  @DocsEditable()
  void insertData(int offset, String data) => _blink.BlinkCharacterData.instance.insertData_Callback_2_(this, offset, data);

  @DomName('CharacterData.replaceData')
  @DocsEditable()
  void replaceData(int offset, int length, String data) => _blink.BlinkCharacterData.instance.replaceData_Callback_3_(this, offset, length, data);

  @DomName('CharacterData.substringData')
  @DocsEditable()
  String substringData(int offset, int length) => _blink.BlinkCharacterData.instance.substringData_Callback_2_(this, offset, length);

  @DomName('CharacterData.nextElementSibling')
  @DocsEditable()
  Element get nextElementSibling => _blink.BlinkCharacterData.instance.nextElementSibling_Getter_(this);

  @DomName('CharacterData.previousElementSibling')
  @DocsEditable()
  Element get previousElementSibling => _blink.BlinkCharacterData.instance.previousElementSibling_Getter_(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.


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

  @DomName('ChildNode.nextElementSibling')
  @DocsEditable()
  @Experimental() // untriaged
  Element get nextElementSibling;

  @DomName('ChildNode.previousElementSibling')
  @DocsEditable()
  @Experimental() // untriaged
  Element get previousElementSibling;

  @DomName('ChildNode.remove')
  @DocsEditable()
  @Experimental() // untriaged
  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.

// WARNING: Do not edit - generated code.


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

  @DomName('CircularRegion.CircularRegion')
  @DocsEditable()
  factory CircularRegion(Map init) {
    return _blink.BlinkCircularRegion.instance.constructorCallback_1_(init);
  }

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

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

  @DomName('CircularRegion.latitude')
  @DocsEditable()
  @Experimental() // untriaged
  double get latitude => _blink.BlinkCircularRegion.instance.latitude_Getter_(this);

  @DomName('CircularRegion.longitude')
  @DocsEditable()
  @Experimental() // untriaged
  double get longitude => _blink.BlinkCircularRegion.instance.longitude_Getter_(this);

  @DomName('CircularRegion.radius')
  @DocsEditable()
  @Experimental() // untriaged
  double get radius => _blink.BlinkCircularRegion.instance.radius_Getter_(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.


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

  @DomName('CloseEvent.code')
  @DocsEditable()
  int get code => _blink.BlinkCloseEvent.instance.code_Getter_(this);

  @DomName('CloseEvent.reason')
  @DocsEditable()
  String get reason => _blink.BlinkCloseEvent.instance.reason_Getter_(this);

  @DomName('CloseEvent.wasClean')
  @DocsEditable()
  bool get wasClean => _blink.BlinkCloseEvent.instance.wasClean_Getter_(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('Comment')
class Comment extends CharacterData {
  // To suppress missing implicit constructor warnings.
  factory Comment._() { throw new UnsupportedError("Not supported"); }

  @DomName('Comment.Comment')
  @DocsEditable()
  factory Comment([String data]) {
    if (data != null) {
      return _blink.BlinkComment.instance.constructorCallback_1_(data);
    }
    return _blink.BlinkComment.instance.constructorCallback_0_();
  }
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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

  @DomName('CompositionEvent.activeSegmentEnd')
  @DocsEditable()
  @Experimental() // untriaged
  int get activeSegmentEnd => _blink.BlinkCompositionEvent.instance.activeSegmentEnd_Getter_(this);

  @DomName('CompositionEvent.activeSegmentStart')
  @DocsEditable()
  @Experimental() // untriaged
  int get activeSegmentStart => _blink.BlinkCompositionEvent.instance.activeSegmentStart_Getter_(this);

  @DomName('CompositionEvent.data')
  @DocsEditable()
  String get data => _blink.BlinkCompositionEvent.instance.data_Getter_(this);

  @DomName('CompositionEvent.getSegments')
  @DocsEditable()
  @Experimental() // untriaged
  List<int> getSegments() => _blink.BlinkCompositionEvent.instance.getSegments_Callback_0_(this);

  @DomName('CompositionEvent.initCompositionEvent')
  @DocsEditable()
  void _initCompositionEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Window viewArg, String dataArg) => _blink.BlinkCompositionEvent.instance.initCompositionEvent_Callback_5_(this, typeArg, canBubbleArg, cancelableArg, viewArg, dataArg);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

  @DomName('Console.memory')
  @DocsEditable()
  @Experimental()
  MemoryInfo get memory => _blink.BlinkConsole.instance.memory_Getter_(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.


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

  @DomName('ConsoleBase.assertCondition')
  @DocsEditable()
  @Experimental() // untriaged
  void assertCondition(bool condition, Object arg) => _blink.BlinkConsoleBase.instance.assert_Callback_2_(this, condition, arg);

  @DomName('ConsoleBase.clear')
  @DocsEditable()
  @Experimental() // untriaged
  void clear(Object arg) => _blink.BlinkConsoleBase.instance.clear_Callback_1_(this, arg);

  @DomName('ConsoleBase.count')
  @DocsEditable()
  @Experimental() // untriaged
  void count(Object arg) => _blink.BlinkConsoleBase.instance.count_Callback_1_(this, arg);

  @DomName('ConsoleBase.debug')
  @DocsEditable()
  @Experimental() // untriaged
  void debug(Object arg) => _blink.BlinkConsoleBase.instance.debug_Callback_1_(this, arg);

  @DomName('ConsoleBase.dir')
  @DocsEditable()
  @Experimental() // untriaged
  void dir(Object arg) => _blink.BlinkConsoleBase.instance.dir_Callback_1_(this, arg);

  @DomName('ConsoleBase.dirxml')
  @DocsEditable()
  @Experimental() // untriaged
  void dirxml(Object arg) => _blink.BlinkConsoleBase.instance.dirxml_Callback_1_(this, arg);

  @DomName('ConsoleBase.error')
  @DocsEditable()
  @Experimental() // untriaged
  void error(Object arg) => _blink.BlinkConsoleBase.instance.error_Callback_1_(this, arg);

  @DomName('ConsoleBase.group')
  @DocsEditable()
  @Experimental() // untriaged
  void group(Object arg) => _blink.BlinkConsoleBase.instance.group_Callback_1_(this, arg);

  @DomName('ConsoleBase.groupCollapsed')
  @DocsEditable()
  @Experimental() // untriaged
  void groupCollapsed(Object arg) => _blink.BlinkConsoleBase.instance.groupCollapsed_Callback_1_(this, arg);

  @DomName('ConsoleBase.groupEnd')
  @DocsEditable()
  @Experimental() // untriaged
  void groupEnd() => _blink.BlinkConsoleBase.instance.groupEnd_Callback_0_(this);

  @DomName('ConsoleBase.info')
  @DocsEditable()
  @Experimental() // untriaged
  void info(Object arg) => _blink.BlinkConsoleBase.instance.info_Callback_1_(this, arg);

  @DomName('ConsoleBase.log')
  @DocsEditable()
  @Experimental() // untriaged
  void log(Object arg) => _blink.BlinkConsoleBase.instance.log_Callback_1_(this, arg);

  @DomName('ConsoleBase.markTimeline')
  @DocsEditable()
  @Experimental() // untriaged
  void markTimeline(String title) => _blink.BlinkConsoleBase.instance.markTimeline_Callback_1_(this, title);

  @DomName('ConsoleBase.profile')
  @DocsEditable()
  @Experimental() // untriaged
  void profile(String title) => _blink.BlinkConsoleBase.instance.profile_Callback_1_(this, title);

  @DomName('ConsoleBase.profileEnd')
  @DocsEditable()
  @Experimental() // untriaged
  void profileEnd(String title) => _blink.BlinkConsoleBase.instance.profileEnd_Callback_1_(this, title);

  @DomName('ConsoleBase.table')
  @DocsEditable()
  @Experimental() // untriaged
  void table(Object arg) => _blink.BlinkConsoleBase.instance.table_Callback_1_(this, arg);

  @DomName('ConsoleBase.time')
  @DocsEditable()
  @Experimental() // untriaged
  void time(String title) => _blink.BlinkConsoleBase.instance.time_Callback_1_(this, title);

  @DomName('ConsoleBase.timeEnd')
  @DocsEditable()
  @Experimental() // untriaged
  void timeEnd(String title) => _blink.BlinkConsoleBase.instance.timeEnd_Callback_1_(this, title);

  @DomName('ConsoleBase.timeStamp')
  @DocsEditable()
  @Experimental() // untriaged
  void timeStamp(String title) => _blink.BlinkConsoleBase.instance.timeStamp_Callback_1_(this, title);

  @DomName('ConsoleBase.timeline')
  @DocsEditable()
  @Experimental() // untriaged
  void timeline(String title) => _blink.BlinkConsoleBase.instance.timeline_Callback_1_(this, title);

  @DomName('ConsoleBase.timelineEnd')
  @DocsEditable()
  @Experimental() // untriaged
  void timelineEnd(String title) => _blink.BlinkConsoleBase.instance.timelineEnd_Callback_1_(this, title);

  @DomName('ConsoleBase.trace')
  @DocsEditable()
  @Experimental() // untriaged
  void trace(Object arg) => _blink.BlinkConsoleBase.instance.trace_Callback_1_(this, arg);

  @DomName('ConsoleBase.warn')
  @DocsEditable()
  @Experimental() // untriaged
  void warn(Object arg) => _blink.BlinkConsoleBase.instance.warn_Callback_1_(this, arg);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


@DocsEditable()
@DomName('HTMLContentElement')
@SupportedBrowser(SupportedBrowser.CHROME, '26')
@Experimental()
// https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#content-element
class ContentElement extends HtmlElement {
  // 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 => true;

  @DomName('HTMLContentElement.select')
  @DocsEditable()
  String get select => _blink.BlinkHTMLContentElement.instance.select_Getter_(this);

  @DomName('HTMLContentElement.select')
  @DocsEditable()
  void set select(String value) => _blink.BlinkHTMLContentElement.instance.select_Setter_(this, value);

  @DomName('HTMLContentElement.getDistributedNodes')
  @DocsEditable()
  List<Node> getDistributedNodes() => _blink.BlinkHTMLContentElement.instance.getDistributedNodes_Callback_0_(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.


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

  @DomName('Coordinates.accuracy')
  @DocsEditable()
  double get accuracy => _blink.BlinkCoordinates.instance.accuracy_Getter_(this);

  @DomName('Coordinates.altitude')
  @DocsEditable()
  double get altitude => _blink.BlinkCoordinates.instance.altitude_Getter_(this);

  @DomName('Coordinates.altitudeAccuracy')
  @DocsEditable()
  double get altitudeAccuracy => _blink.BlinkCoordinates.instance.altitudeAccuracy_Getter_(this);

  @DomName('Coordinates.heading')
  @DocsEditable()
  double get heading => _blink.BlinkCoordinates.instance.heading_Getter_(this);

  @DomName('Coordinates.latitude')
  @DocsEditable()
  double get latitude => _blink.BlinkCoordinates.instance.latitude_Getter_(this);

  @DomName('Coordinates.longitude')
  @DocsEditable()
  double get longitude => _blink.BlinkCoordinates.instance.longitude_Getter_(this);

  @DomName('Coordinates.speed')
  @DocsEditable()
  double get speed => _blink.BlinkCoordinates.instance.speed_Getter_(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.


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

  @DomName('Credential.avatarURL')
  @DocsEditable()
  @Experimental() // untriaged
  String get avatarUrl => _blink.BlinkCredential.instance.avatarURL_Getter_(this);

  @DomName('Credential.id')
  @DocsEditable()
  @Experimental() // untriaged
  String get id => _blink.BlinkCredential.instance.id_Getter_(this);

  @DomName('Credential.name')
  @DocsEditable()
  @Experimental() // untriaged
  String get name => _blink.BlinkCredential.instance.name_Getter_(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.


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

  Future notifyFailedSignIn([Credential credential]) {
    if (credential != null) {
      return _blink.BlinkCredentialsContainer.instance.notifyFailedSignIn_Callback_1_(this, credential);
    }
    return _blink.BlinkCredentialsContainer.instance.notifyFailedSignIn_Callback_0_(this);
  }

  Future notifySignedIn([Credential credential]) {
    if (credential != null) {
      return _blink.BlinkCredentialsContainer.instance.notifySignedIn_Callback_1_(this, credential);
    }
    return _blink.BlinkCredentialsContainer.instance.notifySignedIn_Callback_0_(this);
  }

  @DomName('CredentialsContainer.notifySignedOut')
  @DocsEditable()
  @Experimental() // untriaged
  Future notifySignedOut() => _blink.BlinkCredentialsContainer.instance.notifySignedOut_Callback_0_(this);

  Future request([Map options]) {
    if (options != null) {
      return _blink.BlinkCredentialsContainer.instance.request_Callback_1_(this, options);
    }
    return _blink.BlinkCredentialsContainer.instance.request_Callback_0_(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.


@DocsEditable()
@DomName('Crypto')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
// http://www.w3.org/TR/WebCryptoAPI/
class Crypto extends NativeFieldWrapperClass2 {
  // 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 => true;

  @DomName('Crypto.subtle')
  @DocsEditable()
  @Experimental() // untriaged
  _SubtleCrypto get subtle => _blink.BlinkCrypto.instance.subtle_Getter_(this);

  @DomName('Crypto.getRandomValues')
  @DocsEditable()
  TypedData getRandomValues(TypedData array) => _blink.BlinkCrypto.instance.getRandomValues_Callback_1_(this, array);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

  @DomName('CryptoKey.algorithm')
  @DocsEditable()
  @Experimental() // untriaged
  Object get algorithm => _blink.BlinkCryptoKey.instance.algorithm_Getter_(this);

  @DomName('CryptoKey.extractable')
  @DocsEditable()
  @Experimental() // untriaged
  bool get extractable => _blink.BlinkCryptoKey.instance.extractable_Getter_(this);

  @DomName('CryptoKey.type')
  @DocsEditable()
  @Experimental() // untriaged
  String get type => _blink.BlinkCryptoKey.instance.type_Getter_(this);

  @DomName('CryptoKey.usages')
  @DocsEditable()
  @Experimental() // untriaged
  List<String> get usages => _blink.BlinkCryptoKey.instance.usages_Getter_(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.


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

  @DomName('CSS.supports')
  @DocsEditable()
  bool supports(String property, String value) => _blink.BlinkCSS.instance.supports_Callback_2_(this, property, value);

  @DomName('CSS.supportsCondition')
  @DocsEditable()
  bool supportsCondition(String conditionText) => _blink.BlinkCSS.instance.supports_Callback_1_(this, conditionText);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

  @DomName('CSSCharsetRule.encoding')
  @DocsEditable()
  String get encoding => _blink.BlinkCSSCharsetRule.instance.encoding_Getter_(this);

  @DomName('CSSCharsetRule.encoding')
  @DocsEditable()
  void set encoding(String value) => _blink.BlinkCSSCharsetRule.instance.encoding_Setter_(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.

// WARNING: Do not edit - generated code.


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

  @DomName('WebKitCSSFilterRule.style')
  @DocsEditable()
  CssStyleDeclaration get style => _blink.BlinkWebKitCSSFilterRule.instance.style_Getter_(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.


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

  @DomName('CSSFontFaceRule.style')
  @DocsEditable()
  CssStyleDeclaration get style => _blink.BlinkCSSFontFaceRule.instance.style_Getter_(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.


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

  @DomName('CSSImportRule.href')
  @DocsEditable()
  String get href => _blink.BlinkCSSImportRule.instance.href_Getter_(this);

  @DomName('CSSImportRule.media')
  @DocsEditable()
  MediaList get media => _blink.BlinkCSSImportRule.instance.media_Getter_(this);

  @DomName('CSSImportRule.styleSheet')
  @DocsEditable()
  CssStyleSheet get styleSheet => _blink.BlinkCSSImportRule.instance.styleSheet_Getter_(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.


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

  @DomName('CSSKeyframeRule.keyText')
  @DocsEditable()
  @Experimental() // untriaged
  String get keyText => _blink.BlinkCSSKeyframeRule.instance.keyText_Getter_(this);

  @DomName('CSSKeyframeRule.keyText')
  @DocsEditable()
  @Experimental() // untriaged
  void set keyText(String value) => _blink.BlinkCSSKeyframeRule.instance.keyText_Setter_(this, value);

  @DomName('CSSKeyframeRule.style')
  @DocsEditable()
  @Experimental() // untriaged
  CssStyleDeclaration get style => _blink.BlinkCSSKeyframeRule.instance.style_Getter_(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.


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

  @DomName('CSSKeyframesRule.cssRules')
  @DocsEditable()
  @Experimental() // untriaged
  List<CssRule> get cssRules => _blink.BlinkCSSKeyframesRule.instance.cssRules_Getter_(this);

  @DomName('CSSKeyframesRule.name')
  @DocsEditable()
  @Experimental() // untriaged
  String get name => _blink.BlinkCSSKeyframesRule.instance.name_Getter_(this);

  @DomName('CSSKeyframesRule.name')
  @DocsEditable()
  @Experimental() // untriaged
  void set name(String value) => _blink.BlinkCSSKeyframesRule.instance.name_Setter_(this, value);

  @DomName('CSSKeyframesRule.__getter__')
  @DocsEditable()
  @Experimental() // untriaged
  CssKeyframeRule __getter__(int index) => _blink.BlinkCSSKeyframesRule.instance.$__getter___Callback_1_(this, index);

  @DomName('CSSKeyframesRule.deleteRule')
  @DocsEditable()
  @Experimental() // untriaged
  void deleteRule(String key) => _blink.BlinkCSSKeyframesRule.instance.deleteRule_Callback_1_(this, key);

  @DomName('CSSKeyframesRule.findRule')
  @DocsEditable()
  @Experimental() // untriaged
  CssKeyframeRule findRule(String key) => _blink.BlinkCSSKeyframesRule.instance.findRule_Callback_1_(this, key);

  @DomName('CSSKeyframesRule.insertRule')
  @DocsEditable()
  @Experimental() // untriaged
  void appendRule(String rule) => _blink.BlinkCSSKeyframesRule.instance.insertRule_Callback_1_(this, rule);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

  @DomName('CSSMediaRule.cssRules')
  @DocsEditable()
  List<CssRule> get cssRules => _blink.BlinkCSSMediaRule.instance.cssRules_Getter_(this);

  @DomName('CSSMediaRule.media')
  @DocsEditable()
  MediaList get media => _blink.BlinkCSSMediaRule.instance.media_Getter_(this);

  @DomName('CSSMediaRule.deleteRule')
  @DocsEditable()
  void deleteRule(int index) => _blink.BlinkCSSMediaRule.instance.deleteRule_Callback_1_(this, index);

  @DomName('CSSMediaRule.insertRule')
  @DocsEditable()
  int insertRule(String rule, int index) => _blink.BlinkCSSMediaRule.instance.insertRule_Callback_2_(this, rule, 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.


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

  @DomName('CSSPageRule.selectorText')
  @DocsEditable()
  String get selectorText => _blink.BlinkCSSPageRule.instance.selectorText_Getter_(this);

  @DomName('CSSPageRule.selectorText')
  @DocsEditable()
  void set selectorText(String value) => _blink.BlinkCSSPageRule.instance.selectorText_Setter_(this, value);

  @DomName('CSSPageRule.style')
  @DocsEditable()
  CssStyleDeclaration get style => _blink.BlinkCSSPageRule.instance.style_Getter_(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.


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

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

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

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

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

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

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

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

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

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

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

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

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

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

  @DomName('CSSRule.cssText')
  @DocsEditable()
  String get cssText => _blink.BlinkCSSRule.instance.cssText_Getter_(this);

  @DomName('CSSRule.cssText')
  @DocsEditable()
  void set cssText(String value) => _blink.BlinkCSSRule.instance.cssText_Setter_(this, value);

  @DomName('CSSRule.parentRule')
  @DocsEditable()
  CssRule get parentRule => _blink.BlinkCSSRule.instance.parentRule_Getter_(this);

  @DomName('CSSRule.parentStyleSheet')
  @DocsEditable()
  CssStyleSheet get parentStyleSheet => _blink.BlinkCSSRule.instance.parentStyleSheet_Getter_(this);

  @DomName('CSSRule.type')
  @DocsEditable()
  int get type => _blink.BlinkCSSRule.instance.type_Getter_(this);

}

// 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')
 class CssStyleDeclaration  extends NativeFieldWrapperClass2 with
    CssStyleDeclarationBase  {
  factory CssStyleDeclaration() => new CssStyleDeclaration.css('');

  factory CssStyleDeclaration.css(String css) {
    final style = new Element.tag('div').style;
    style.cssText = css;
    return style;
  }

  String getPropertyValue(String propertyName) {
    var propValue = _getPropertyValueHelper(propertyName);
    return propValue != null ? propValue : '';
  }

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

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

  bool _supportsProperty(String propertyName) {
    // You can't just check the value of a property, because there is no way
    // to distinguish between property not being present in the browser and
    // not having a value at all. (Ultimately we'll want the native method to
    // return null if the property doesn't exist and empty string if it's
    // defined but just doesn't have a value.
    return _hasProperty(propertyName);
  }

  bool _hasProperty(String propertyName) =>
      _blink.BlinkCSSStyleDeclaration.$__propertyQuery___Callback_1(this, propertyName);

  @DomName('CSSStyleDeclaration.setProperty')
  void setProperty(String propertyName, String value, [String priority]) {
    if (_supportsProperty(_camelCase(propertyName))) {
      return _setPropertyHelper(propertyName, value, priority);
    } else {
      return _setPropertyHelper(Device.cssPrefix + propertyName, value,
          priority);
    }
  }

  static String _camelCase(String hyphenated) {
    // The "ms" prefix is always lowercased.
    return hyphenated.replaceFirst(new RegExp('^-ms-'), 'ms-').replaceAllMapped(
        new RegExp('-([a-z]+)', caseSensitive: false),
        (match) => match[0][1].toUpperCase() + match[0].substring(2));
  }

  void _setPropertyHelper(String propertyName, String value, [String priority]) {
    if (priority == null) {
      priority = '';
    }
    _setProperty(propertyName, value, priority);
  }

  /**
   * Checks to see if CSS Transitions are supported.
   */
  static bool get supportsTransitions => true;
  // To suppress missing implicit constructor warnings.
  factory CssStyleDeclaration._() { throw new UnsupportedError("Not supported"); }

  @DomName('CSSStyleDeclaration.cssText')
  @DocsEditable()
  String get cssText => _blink.BlinkCSSStyleDeclaration.instance.cssText_Getter_(this);

  @DomName('CSSStyleDeclaration.cssText')
  @DocsEditable()
  void set cssText(String value) => _blink.BlinkCSSStyleDeclaration.instance.cssText_Setter_(this, value);

  @DomName('CSSStyleDeclaration.length')
  @DocsEditable()
  int get length => _blink.BlinkCSSStyleDeclaration.instance.length_Getter_(this);

  @DomName('CSSStyleDeclaration.parentRule')
  @DocsEditable()
  CssRule get parentRule => _blink.BlinkCSSStyleDeclaration.instance.parentRule_Getter_(this);

  @DomName('CSSStyleDeclaration.__getter__')
  @DocsEditable()
  @Experimental() // untriaged
  Object __getter__(String name) => _blink.BlinkCSSStyleDeclaration.instance.$__getter___Callback_1_(this, name);

  @DomName('CSSStyleDeclaration.__propertyQuery__')
  @DocsEditable()
  @Experimental() // untriaged
  bool __propertyQuery__(String name) => _blink.BlinkCSSStyleDeclaration.instance.$__propertyQuery___Callback_1_(this, name);

  @DomName('CSSStyleDeclaration.__setter__')
  @DocsEditable()
  void __setter__(String propertyName, String propertyValue) => _blink.BlinkCSSStyleDeclaration.instance.$__setter___Callback_2_(this, propertyName, propertyValue);

  @DomName('CSSStyleDeclaration.getPropertyPriority')
  @DocsEditable()
  String getPropertyPriority(String propertyName) => _blink.BlinkCSSStyleDeclaration.instance.getPropertyPriority_Callback_1_(this, propertyName);

  @DomName('CSSStyleDeclaration.getPropertyValue')
  @DocsEditable()
  String _getPropertyValue(String propertyName) => _blink.BlinkCSSStyleDeclaration.instance.getPropertyValue_Callback_1_(this, propertyName);

  @DomName('CSSStyleDeclaration.item')
  @DocsEditable()
  String item(int index) => _blink.BlinkCSSStyleDeclaration.instance.item_Callback_1_(this, index);

  @DomName('CSSStyleDeclaration.removeProperty')
  @DocsEditable()
  String removeProperty(String propertyName) => _blink.BlinkCSSStyleDeclaration.instance.removeProperty_Callback_1_(this, propertyName);

  @DomName('CSSStyleDeclaration.setProperty')
  @DocsEditable()
  void _setProperty(String propertyName, String value, String priority) => _blink.BlinkCSSStyleDeclaration.instance.setProperty_Callback_3_(this, propertyName, value, priority);

}

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

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

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

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

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

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

  /** Sets the value of "align-content" */
  void 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" */
  void 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" */
  void set alignSelf(String value) {
    setProperty('align-self', value, '');
  }

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

  /** Sets the value of "animation" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void set appRegion(String value) {
    setProperty('app-region', value, '');
  }

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

  /** Sets the value of "appearance" */
  void 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" */
  void 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" */
  void set backfaceVisibility(String value) {
    setProperty('backface-visibility', value, '');
  }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  /** Sets the value of "box-align" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void set captionSide(String value) {
    setProperty('caption-side', value, '');
  }

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

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

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

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

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

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

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

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

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

  /** Sets the value of "column-break-after" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void set columnWidth(String value) {
    setProperty('column-width', value, '');
  }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  /** Sets the value of "grid" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void set gridTemplateRows(String value) {
    setProperty('grid-template-rows', value, '');
  }

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

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

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

  /** Sets the value of "highlight" */
  void 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" */
  void 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" */
  void set imageRendering(String value) {
    setProperty('image-rendering', value, '');
  }

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

  /** Sets the value of "isolation" */
  void 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" */
  void 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" */
  void set justifySelf(String value) {
    setProperty('justify-self', value, '');
  }

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

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

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

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

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

  /** Sets the value of "line-box-contain" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void set listStyle(String value) {
    setProperty('list-style', value, '');
  }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  /** Sets the value of "margin-start" */
  void 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" */
  void 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" */
  void set marginTopCollapse(String value) {
    setProperty('margin-top-collapse', value, '');
  }

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

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

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

  /** Sets the value of "max-zoom" */
  void set maxZoom(String value) {
    setProperty('max-zoom', value, '');
  }

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

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

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

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

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

  /** Sets the value of "min-zoom" */
  void set minZoom(String value) {
    setProperty('min-zoom', value, '');
  }

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

  /** Sets the value of "mix-blend-mode" */
  void 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" */
  void 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" */
  void set objectPosition(String value) {
    setProperty('object-position', value, '');
  }

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

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

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

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

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

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

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

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

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

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

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

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

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

  /** Sets the value of "outline-offset" */
  void set outlineOffset(String value) {
    setProperty('outline-offset', value, '');
  }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  /** Sets the value of "padding-start" */
  void 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" */
  void set paddingTop(String value) {
    setProperty('padding-top', value, '');
  }

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

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

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

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

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

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

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

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

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

  /** Sets the value of "perspective" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void set pointerEvents(String value) {
    setProperty('pointer-events', value, '');
  }

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

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

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

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

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

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

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

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

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

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

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

  /** Sets the value of "rtl-ordering" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void set shapeOutside(String value) {
    setProperty('shape-outside', value, '');
  }

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

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

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

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

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

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

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

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

  /** Gets the value of "table-layout" */
  String get tableLayout =>
    getPropertyValue('table-layout');

  /** Sets the value of "table-layout" */
  void set tableLayout(String value) {
    setProperty('table-layout', value, '');
  }

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

  /** Sets the value of "tap-highlight-color" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void 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" */
  void set textLineThroughColor(String value) {
    setProperty('text-line-through-color', value, '');
  }

  /** Gets the value of "text-line-through-mode" */
  String get textLineThroughMode =>
    getPropertyValue('text-line-through-mode');

  /** Sets the value of "text-line-through-mode" */
  void set textLineThroughMode(String value) {
    setProperty('text-line-through-mode', value, '');
  }

  /** Gets the value of "text-line-through-style" */
  String get textLineThroughStyle =>
    getPropertyValue('text-line-through-style');

  /** Sets the value of "text-line-through-style" */
  void set textLineThroughStyle(String value) {
    setProperty('text-line-through-style', value, '');
  }

  /** Gets the value of "text-line-through-width" */
  String get textLineThroughWidth =>
    getPropertyValue('text-line-through-width');

  /** Sets the value of "text-line-through-width" */
  void set textLineThroughWidth(String value) {
    setProperty('text-line-through-width', value, '');
  }

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

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

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

  /** Sets the value of "text-overline-mode" */
  void set textOverlineMode(String value) {
    setProperty('text-overline-mode', value, '');
  }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  /** Sets the value of "touch-action" */
  void 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" */
  void set touchActionDelay(String value) {
    setProperty('touch-action-delay', value, '');
  }

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

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

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

  /** Sets the value of "unicode-range" */
  void set unicodeRange(String value) {
    setProperty('unicode-range', value, '');
  }

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

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

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

  /** Sets the value of "vertical-align" */
  void set verticalAlign(String value) {
    setProperty('vertical-align', value, '');
  }

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

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

  /** Gets the value of "white-space" */
  String get whiteSpace =>
    getPropertyValue('white-space');

  /** Sets the value of "white-space" */
  void set whiteSpace(String value) {
    setProperty('white-space', value, '');
  }

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

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

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

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

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

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

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

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

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

  /** Sets the value of "word-wrap" */
  void set wordWrap(String value) {
    setProperty('word-wrap', value, '');
  }

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

  /** Sets the value of "wrap-flow" */
  void 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" */
  void 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" */
  void 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" */
  void set zIndex(String value) {
    setProperty('z-index', value, '');
  }

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

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

// WARNING: Do not edit - generated code.


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

  @DomName('CSSStyleRule.selectorText')
  @DocsEditable()
  String get selectorText => _blink.BlinkCSSStyleRule.instance.selectorText_Getter_(this);

  @DomName('CSSStyleRule.selectorText')
  @DocsEditable()
  void set selectorText(String value) => _blink.BlinkCSSStyleRule.instance.selectorText_Setter_(this, value);

  @DomName('CSSStyleRule.style')
  @DocsEditable()
  CssStyleDeclaration get style => _blink.BlinkCSSStyleRule.instance.style_Getter_(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.


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

  @DomName('CSSStyleSheet.cssRules')
  @DocsEditable()
  List<CssRule> get cssRules => _blink.BlinkCSSStyleSheet.instance.cssRules_Getter_(this);

  @DomName('CSSStyleSheet.ownerRule')
  @DocsEditable()
  CssRule get ownerRule => _blink.BlinkCSSStyleSheet.instance.ownerRule_Getter_(this);

  @DomName('CSSStyleSheet.rules')
  @DocsEditable()
  @Experimental() // non-standard
  List<CssRule> get rules => _blink.BlinkCSSStyleSheet.instance.rules_Getter_(this);

  int addRule(String selector, String style, [int index]) {
    if (index != null) {
      return _blink.BlinkCSSStyleSheet.instance.addRule_Callback_3_(this, selector, style, index);
    }
    return _blink.BlinkCSSStyleSheet.instance.addRule_Callback_2_(this, selector, style);
  }

  @DomName('CSSStyleSheet.deleteRule')
  @DocsEditable()
  void deleteRule(int index) => _blink.BlinkCSSStyleSheet.instance.deleteRule_Callback_1_(this, index);

  int insertRule(String rule, [int index]) {
    if (index != null) {
      return _blink.BlinkCSSStyleSheet.instance.insertRule_Callback_2_(this, rule, index);
    }
    return _blink.BlinkCSSStyleSheet.instance.insertRule_Callback_1_(this, rule);
  }

  @DomName('CSSStyleSheet.removeRule')
  @DocsEditable()
  @Experimental() // non-standard
  void removeRule(int index) => _blink.BlinkCSSStyleSheet.instance.removeRule_Callback_1_(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.


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

  @DomName('CSSSupportsRule.conditionText')
  @DocsEditable()
  String get conditionText => _blink.BlinkCSSSupportsRule.instance.conditionText_Getter_(this);

  @DomName('CSSSupportsRule.cssRules')
  @DocsEditable()
  List<CssRule> get cssRules => _blink.BlinkCSSSupportsRule.instance.cssRules_Getter_(this);

  @DomName('CSSSupportsRule.deleteRule')
  @DocsEditable()
  void deleteRule(int index) => _blink.BlinkCSSSupportsRule.instance.deleteRule_Callback_1_(this, index);

  @DomName('CSSSupportsRule.insertRule')
  @DocsEditable()
  int insertRule(String rule, int index) => _blink.BlinkCSSSupportsRule.instance.insertRule_Callback_2_(this, rule, 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.


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

  @DomName('CSSViewportRule.style')
  @DocsEditable()
  @Experimental() // untriaged
  CssStyleDeclaration get style => _blink.BlinkCSSViewportRule.instance.style_Getter_(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('CustomEvent')
class CustomEvent extends Event {
  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 {
        e._initCustomEvent(type, canBubble, cancelable, detail);
      } catch(_) {
        e._initCustomEvent(type, canBubble, cancelable, null);
      }
    } else {
      e._initCustomEvent(type, canBubble, cancelable, null);
    }

    return e;
  }

  @DomName('CustomEvent.detail')
  get detail {
    if (_dartDetail != null) {
      return _dartDetail;
    }
    return _detail;
  }
  // To suppress missing implicit constructor warnings.
  factory CustomEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('CustomEvent.detail')
  @DocsEditable()
  Object get _detail => _blink.BlinkCustomEvent.instance.detail_Getter_(this);

  @DomName('CustomEvent.initCustomEvent')
  @DocsEditable()
  void _initCustomEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Object detailArg) => _blink.BlinkCustomEvent.instance.initCustomEvent_Callback_4_(this, typeArg, canBubbleArg, cancelableArg, detailArg);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

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

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

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('HTMLDataListElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
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 => true;

  @DomName('HTMLDataListElement.options')
  @DocsEditable()
  List<Node> get options => _blink.BlinkHTMLDataListElement.instance.options_Getter_(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.


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

  @DomName('DataTransfer.dropEffect')
  @DocsEditable()
  @Experimental() // untriaged
  String get dropEffect => _blink.BlinkDataTransfer.instance.dropEffect_Getter_(this);

  @DomName('DataTransfer.dropEffect')
  @DocsEditable()
  @Experimental() // untriaged
  void set dropEffect(String value) => _blink.BlinkDataTransfer.instance.dropEffect_Setter_(this, value);

  @DomName('DataTransfer.effectAllowed')
  @DocsEditable()
  @Experimental() // untriaged
  String get effectAllowed => _blink.BlinkDataTransfer.instance.effectAllowed_Getter_(this);

  @DomName('DataTransfer.effectAllowed')
  @DocsEditable()
  @Experimental() // untriaged
  void set effectAllowed(String value) => _blink.BlinkDataTransfer.instance.effectAllowed_Setter_(this, value);

  @DomName('DataTransfer.files')
  @DocsEditable()
  @Experimental() // untriaged
  List<File> get files => _blink.BlinkDataTransfer.instance.files_Getter_(this);

  @DomName('DataTransfer.items')
  @DocsEditable()
  @Experimental() // untriaged
  DataTransferItemList get items => _blink.BlinkDataTransfer.instance.items_Getter_(this);

  @DomName('DataTransfer.types')
  @DocsEditable()
  @Experimental() // untriaged
  List<String> get types => _blink.BlinkDataTransfer.instance.types_Getter_(this);

  void clearData([String type]) {
    if (type != null) {
      _blink.BlinkDataTransfer.instance.clearData_Callback_1_(this, type);
      return;
    }
    _blink.BlinkDataTransfer.instance.clearData_Callback_0_(this);
    return;
  }

  @DomName('DataTransfer.getData')
  @DocsEditable()
  @Experimental() // untriaged
  String getData(String type) => _blink.BlinkDataTransfer.instance.getData_Callback_1_(this, type);

  @DomName('DataTransfer.setData')
  @DocsEditable()
  @Experimental() // untriaged
  void setData(String type, String data) => _blink.BlinkDataTransfer.instance.setData_Callback_2_(this, type, data);

  @DomName('DataTransfer.setDragImage')
  @DocsEditable()
  @Experimental() // untriaged
  void setDragImage(Element image, int x, int y) => _blink.BlinkDataTransfer.instance.setDragImage_Callback_3_(this, image, x, 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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('DataTransferItem')
// http://www.w3.org/TR/2011/WD-html5-20110113/dnd.html#the-datatransferitem-interface
@Experimental()
class DataTransferItem extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory DataTransferItem._() { throw new UnsupportedError("Not supported"); }

  @DomName('DataTransferItem.kind')
  @DocsEditable()
  String get kind => _blink.BlinkDataTransferItem.instance.kind_Getter_(this);

  @DomName('DataTransferItem.type')
  @DocsEditable()
  String get type => _blink.BlinkDataTransferItem.instance.type_Getter_(this);

  @DomName('DataTransferItem.getAsFile')
  @DocsEditable()
  Blob getAsFile() => _blink.BlinkDataTransferItem.instance.getAsFile_Callback_0_(this);

  @DomName('DataTransferItem.getAsString')
  @DocsEditable()
  void _getAsString(_StringCallback callback) => _blink.BlinkDataTransferItem.instance.getAsString_Callback_1_(this, callback);

  Future<String> getAsString() {
    var completer = new Completer<String>();
    _getAsString(
        (value) { completer.complete(value); });
    return completer.future;
  }

  @DomName('DataTransferItem.webkitGetAsEntry')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  Entry getAsEntry() => _blink.BlinkDataTransferItem.instance.webkitGetAsEntry_Callback_0_(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('DataTransferItemList')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#the-datatransferitemlist-interface
@Experimental()
class DataTransferItemList extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory DataTransferItemList._() { throw new UnsupportedError("Not supported"); }

  @DomName('DataTransferItemList.length')
  @DocsEditable()
  int get length => _blink.BlinkDataTransferItemList.instance.length_Getter_(this);

  @DomName('DataTransferItemList.__getter__')
  @DocsEditable()
  @Experimental() // untriaged
  DataTransferItem __getter__(int index) => _blink.BlinkDataTransferItemList.instance.$__getter___Callback_1_(this, index);

  DataTransferItem add(data_OR_file, [String type]) {
    if ((type is String) && (data_OR_file is String)) {
      return _blink.BlinkDataTransferItemList.instance.add_Callback_2_(this, data_OR_file, type);
    }
    if ((data_OR_file is File || data_OR_file == null) && type == null) {
      return _blink.BlinkDataTransferItemList.instance.add_Callback_1_(this, data_OR_file);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('DataTransferItemList.addData')
  @DocsEditable()
  DataTransferItem addData(String data, String type) => _blink.BlinkDataTransferItemList.instance.add_Callback_2_(this, data, type);

  @DomName('DataTransferItemList.addFile')
  @DocsEditable()
  DataTransferItem addFile(File file) => _blink.BlinkDataTransferItemList.instance.add_Callback_1_(this, file);

  @DomName('DataTransferItemList.clear')
  @DocsEditable()
  void clear() => _blink.BlinkDataTransferItemList.instance.clear_Callback_0_(this);

  @DomName('DataTransferItemList.remove')
  @DocsEditable()
  @Experimental() // untriaged
  void remove(int index) => _blink.BlinkDataTransferItemList.instance.remove_Callback_1_(this, index);


  DataTransferItem operator[] (int index) {
    return __getter__(index);
  }

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

// WARNING: Do not edit - generated code.


@DomName('DatabaseCallback')
// http://www.w3.org/TR/webdatabase/#databasecallback
@Experimental() // deprecated
typedef void DatabaseCallback(database);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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

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

  @DomName('DedicatedWorkerGlobalScope.postMessage')
  @DocsEditable()
  @Experimental() // untriaged
  void postMessage(Object message, [List<MessagePort> transfer]) => _blink.BlinkDedicatedWorkerGlobalScope.instance.postMessage_Callback_2_(this, message, transfer);

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

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('DeprecatedStorageInfo')
@Experimental() // untriaged
class DeprecatedStorageInfo extends NativeFieldWrapperClass2 {
  // 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;

  void queryUsageAndQuota(int storageType, [StorageUsageCallback usageCallback, StorageErrorCallback errorCallback]) {
    if (errorCallback != null) {
      _blink.BlinkDeprecatedStorageInfo.instance.queryUsageAndQuota_Callback_3_(this, storageType, usageCallback, errorCallback);
      return;
    }
    if (usageCallback != null) {
      _blink.BlinkDeprecatedStorageInfo.instance.queryUsageAndQuota_Callback_2_(this, storageType, usageCallback);
      return;
    }
    _blink.BlinkDeprecatedStorageInfo.instance.queryUsageAndQuota_Callback_1_(this, storageType);
    return;
  }

  void requestQuota(int storageType, int newQuotaInBytes, [StorageQuotaCallback quotaCallback, StorageErrorCallback errorCallback]) {
    if (errorCallback != null) {
      _blink.BlinkDeprecatedStorageInfo.instance.requestQuota_Callback_4_(this, storageType, newQuotaInBytes, quotaCallback, errorCallback);
      return;
    }
    if (quotaCallback != null) {
      _blink.BlinkDeprecatedStorageInfo.instance.requestQuota_Callback_3_(this, storageType, newQuotaInBytes, quotaCallback);
      return;
    }
    _blink.BlinkDeprecatedStorageInfo.instance.requestQuota_Callback_2_(this, storageType, newQuotaInBytes);
    return;
  }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

  void queryUsageAndQuota(StorageUsageCallback usageCallback, [StorageErrorCallback errorCallback]) {
    if (errorCallback != null) {
      _blink.BlinkDeprecatedStorageQuota.instance.queryUsageAndQuota_Callback_2_(this, usageCallback, errorCallback);
      return;
    }
    _blink.BlinkDeprecatedStorageQuota.instance.queryUsageAndQuota_Callback_1_(this, usageCallback);
    return;
  }

  void requestQuota(int newQuotaInBytes, [StorageQuotaCallback quotaCallback, StorageErrorCallback errorCallback]) {
    if (errorCallback != null) {
      _blink.BlinkDeprecatedStorageQuota.instance.requestQuota_Callback_3_(this, newQuotaInBytes, quotaCallback, errorCallback);
      return;
    }
    if (quotaCallback != null) {
      _blink.BlinkDeprecatedStorageQuota.instance.requestQuota_Callback_2_(this, newQuotaInBytes, quotaCallback);
      return;
    }
    _blink.BlinkDeprecatedStorageQuota.instance.requestQuota_Callback_1_(this, newQuotaInBytes);
    return;
  }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


@DocsEditable()
@DomName('HTMLDetailsElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
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 => true;

  @DomName('HTMLDetailsElement.open')
  @DocsEditable()
  bool get open => _blink.BlinkHTMLDetailsElement.instance.open_Getter_(this);

  @DomName('HTMLDetailsElement.open')
  @DocsEditable()
  void set open(bool value) => _blink.BlinkHTMLDetailsElement.instance.open_Setter_(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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('DeviceAcceleration')
// http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
@Experimental()
class DeviceAcceleration extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory DeviceAcceleration._() { throw new UnsupportedError("Not supported"); }

  @DomName('DeviceAcceleration.x')
  @DocsEditable()
  double get x => _blink.BlinkDeviceAcceleration.instance.x_Getter_(this);

  @DomName('DeviceAcceleration.y')
  @DocsEditable()
  double get y => _blink.BlinkDeviceAcceleration.instance.y_Getter_(this);

  @DomName('DeviceAcceleration.z')
  @DocsEditable()
  double get z => _blink.BlinkDeviceAcceleration.instance.z_Getter_(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.


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

  @DomName('DeviceLightEvent.value')
  @DocsEditable()
  @Experimental() // untriaged
  double get value => _blink.BlinkDeviceLightEvent.instance.value_Getter_(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.


@DocsEditable()
@DomName('DeviceMotionEvent')
// http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
@Experimental()
class DeviceMotionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory DeviceMotionEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('DeviceMotionEvent.acceleration')
  @DocsEditable()
  DeviceAcceleration get acceleration => _blink.BlinkDeviceMotionEvent.instance.acceleration_Getter_(this);

  @DomName('DeviceMotionEvent.accelerationIncludingGravity')
  @DocsEditable()
  DeviceAcceleration get accelerationIncludingGravity => _blink.BlinkDeviceMotionEvent.instance.accelerationIncludingGravity_Getter_(this);

  @DomName('DeviceMotionEvent.interval')
  @DocsEditable()
  double get interval => _blink.BlinkDeviceMotionEvent.instance.interval_Getter_(this);

  @DomName('DeviceMotionEvent.rotationRate')
  @DocsEditable()
  DeviceRotationRate get rotationRate => _blink.BlinkDeviceMotionEvent.instance.rotationRate_Getter_(this);

  @DomName('DeviceMotionEvent.initDeviceMotionEvent')
  @DocsEditable()
  @Experimental() // untriaged
  void initDeviceMotionEvent(String type, bool bubbles, bool cancelable, DeviceAcceleration acceleration, DeviceAcceleration accelerationIncludingGravity, DeviceRotationRate rotationRate, num interval) => _blink.BlinkDeviceMotionEvent.instance.initDeviceMotionEvent_Callback_7_(this, type, bubbles, cancelable, acceleration, accelerationIncludingGravity, rotationRate, interval);

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

// WARNING: Do not edit - generated code.

@DomName('DeviceOrientationEvent')
// http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
@Experimental()
class DeviceOrientationEvent extends Event {
  factory DeviceOrientationEvent(String type,
      {bool canBubble: true, bool cancelable: true, num alpha: 0, num beta: 0,
      num gamma: 0, bool absolute: false}) {
    var e = document._createEvent("DeviceOrientationEvent");
    e._initDeviceOrientationEvent(type, canBubble, cancelable, alpha, beta,
        gamma, absolute);
    return e;
  }
  // To suppress missing implicit constructor warnings.
  factory DeviceOrientationEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('DeviceOrientationEvent.absolute')
  @DocsEditable()
  bool get absolute => _blink.BlinkDeviceOrientationEvent.instance.absolute_Getter_(this);

  @DomName('DeviceOrientationEvent.alpha')
  @DocsEditable()
  double get alpha => _blink.BlinkDeviceOrientationEvent.instance.alpha_Getter_(this);

  @DomName('DeviceOrientationEvent.beta')
  @DocsEditable()
  double get beta => _blink.BlinkDeviceOrientationEvent.instance.beta_Getter_(this);

  @DomName('DeviceOrientationEvent.gamma')
  @DocsEditable()
  double get gamma => _blink.BlinkDeviceOrientationEvent.instance.gamma_Getter_(this);

  @DomName('DeviceOrientationEvent.initDeviceOrientationEvent')
  @DocsEditable()
  void _initDeviceOrientationEvent(String type, bool bubbles, bool cancelable, num alpha, num beta, num gamma, bool absolute) => _blink.BlinkDeviceOrientationEvent.instance.initDeviceOrientationEvent_Callback_7_(this, type, bubbles, cancelable, alpha, beta, gamma, absolute);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


@DocsEditable()
@DomName('DeviceRotationRate')
// http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
@Experimental()
class DeviceRotationRate extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory DeviceRotationRate._() { throw new UnsupportedError("Not supported"); }

  @DomName('DeviceRotationRate.alpha')
  @DocsEditable()
  double get alpha => _blink.BlinkDeviceRotationRate.instance.alpha_Getter_(this);

  @DomName('DeviceRotationRate.beta')
  @DocsEditable()
  double get beta => _blink.BlinkDeviceRotationRate.instance.beta_Getter_(this);

  @DomName('DeviceRotationRate.gamma')
  @DocsEditable()
  double get gamma => _blink.BlinkDeviceRotationRate.instance.gamma_Getter_(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.


@DocsEditable()
@DomName('HTMLDialogElement')
@Unstable()
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 get open => _blink.BlinkHTMLDialogElement.instance.open_Getter_(this);

  @DomName('HTMLDialogElement.open')
  @DocsEditable()
  void set open(bool value) => _blink.BlinkHTMLDialogElement.instance.open_Setter_(this, value);

  @DomName('HTMLDialogElement.returnValue')
  @DocsEditable()
  @Experimental() // untriaged
  String get returnValue => _blink.BlinkHTMLDialogElement.instance.returnValue_Getter_(this);

  @DomName('HTMLDialogElement.returnValue')
  @DocsEditable()
  @Experimental() // untriaged
  void set returnValue(String value) => _blink.BlinkHTMLDialogElement.instance.returnValue_Setter_(this, value);

  @DomName('HTMLDialogElement.close')
  @DocsEditable()
  void close(String returnValue) => _blink.BlinkHTMLDialogElement.instance.close_Callback_1_(this, returnValue);

  @DomName('HTMLDialogElement.show')
  @DocsEditable()
  void show() => _blink.BlinkHTMLDialogElement.instance.show_Callback_0_(this);

  @DomName('HTMLDialogElement.showModal')
  @DocsEditable()
  void showModal() => _blink.BlinkHTMLDialogElement.instance.showModal_Callback_0_(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('DirectoryEntry')
// http://www.w3.org/TR/file-system-api/#the-directoryentry-interface
@Experimental()
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() => _blink.BlinkDirectoryEntry.instance.createReader_Callback_0_(this);

  void __getDirectory(String path, {Map options, _EntryCallback successCallback, _ErrorCallback errorCallback}) {
    if (errorCallback != null) {
      _blink.BlinkDirectoryEntry.instance.getDirectory_Callback_4_(this, path, options, successCallback, errorCallback);
      return;
    }
    if (successCallback != null) {
      _blink.BlinkDirectoryEntry.instance.getDirectory_Callback_3_(this, path, options, successCallback);
      return;
    }
    if (options != null) {
      _blink.BlinkDirectoryEntry.instance.getDirectory_Callback_2_(this, path, options);
      return;
    }
    _blink.BlinkDirectoryEntry.instance.getDirectory_Callback_1_(this, path);
    return;
  }

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

  void __getFile(String path, {Map options, _EntryCallback successCallback, _ErrorCallback errorCallback}) {
    if (errorCallback != null) {
      _blink.BlinkDirectoryEntry.instance.getFile_Callback_4_(this, path, options, successCallback, errorCallback);
      return;
    }
    if (successCallback != null) {
      _blink.BlinkDirectoryEntry.instance.getFile_Callback_3_(this, path, options, successCallback);
      return;
    }
    if (options != null) {
      _blink.BlinkDirectoryEntry.instance.getFile_Callback_2_(this, path, options);
      return;
    }
    _blink.BlinkDirectoryEntry.instance.getFile_Callback_1_(this, path);
    return;
  }

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

  void _removeRecursively(VoidCallback successCallback, [_ErrorCallback errorCallback]) {
    if (errorCallback != null) {
      _blink.BlinkDirectoryEntry.instance.removeRecursively_Callback_2_(this, successCallback, errorCallback);
      return;
    }
    _blink.BlinkDirectoryEntry.instance.removeRecursively_Callback_1_(this, successCallback);
    return;
  }

  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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('DirectoryReader')
// http://www.w3.org/TR/file-system-api/#the-directoryreader-interface
@Experimental()
class DirectoryReader extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory DirectoryReader._() { throw new UnsupportedError("Not supported"); }

  void _readEntries(_EntriesCallback successCallback, [_ErrorCallback errorCallback]) {
    if (errorCallback != null) {
      _blink.BlinkDirectoryReader.instance.readEntries_Callback_2_(this, successCallback, errorCallback);
      return;
    }
    _blink.BlinkDirectoryReader.instance.readEntries_Callback_1_(this, successCallback);
    return;
  }

  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.

// WARNING: Do not edit - generated code.


@DocsEditable()
/**
 * A generic container for content on an HTML page;
 * corresponds to the &lt;div&gt; tag.
 *
 * The [DivElement] is a generic container and does not have any semantic
 * significance. It is functionally similar to [SpanElement].
 *
 * The [DivElement] is a block-level element, as opposed to [SpanElement],
 * which is an inline-level element.
 *
 * Example usage:
 *
 *     DivElement div = new DivElement();
 *     div.text = 'Here's my new DivElem
 *     document.body.elements.add(elem);
 *
 * See also:
 *
 * * [HTML <div> element](http://www.w3.org/TR/html-markup/div.html) from W3C.
 * * [Block-level element](http://www.w3.org/TR/CSS2/visuren.html#block-boxes) from W3C.
 * * [Inline-level element](http://www.w3.org/TR/CSS2/visuren.html#inline-boxes) from W3C.
 */
@DomName('HTMLDivElement')
class DivElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory DivElement._() { throw new UnsupportedError("Not supported"); }

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

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


@DocsEditable()
/**
 * The base class for all documents.
 *
 * Each web page loaded in the browser has its own [Document] object, which is
 * typically an [HtmlDocument].
 *
 * If you aren't comfortable with DOM concepts, see the Dart tutorial
 * [Target 2: Connect Dart & HTML](http://www.dartlang.org/docs/tutorials/connect-dart-html/).
 */
@DomName('Document')
class Document extends Node
{

  // 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
  Element get activeElement => _blink.BlinkDocument.instance.activeElement_Getter_(this);

  @DomName('Document.body')
  @DocsEditable()
  HtmlElement get _body => _blink.BlinkDocument.instance.body_Getter_(this);

  @DomName('Document.body')
  @DocsEditable()
  void set _body(HtmlElement value) => _blink.BlinkDocument.instance.body_Setter_(this, value);

  @DomName('Document.contentType')
  @DocsEditable()
  @Experimental() // untriaged
  String get contentType => _blink.BlinkDocument.instance.contentType_Getter_(this);

  @DomName('Document.cookie')
  @DocsEditable()
  String get cookie => _blink.BlinkDocument.instance.cookie_Getter_(this);

  @DomName('Document.cookie')
  @DocsEditable()
  void set cookie(String value) => _blink.BlinkDocument.instance.cookie_Setter_(this, value);

  @DomName('Document.currentScript')
  @DocsEditable()
  @Experimental() // untriaged
  ScriptElement get currentScript => _blink.BlinkDocument.instance.currentScript_Getter_(this);

  @DomName('Document.defaultView')
  @DocsEditable()
  WindowBase get window => _blink.BlinkDocument.instance.defaultView_Getter_(this);

  @DomName('Document.documentElement')
  @DocsEditable()
  Element get documentElement => _blink.BlinkDocument.instance.documentElement_Getter_(this);

  @DomName('Document.domain')
  @DocsEditable()
  String get domain => _blink.BlinkDocument.instance.domain_Getter_(this);

  @DomName('Document.fonts')
  @DocsEditable()
  @Experimental() // untriaged
  FontFaceSet get fonts => _blink.BlinkDocument.instance.fonts_Getter_(this);

  @DomName('Document.fullscreenElement')
  @DocsEditable()
  @Experimental() // untriaged
  Element get fullscreenElement => _blink.BlinkDocument.instance.fullscreenElement_Getter_(this);

  @DomName('Document.fullscreenEnabled')
  @DocsEditable()
  @Experimental() // untriaged
  bool get fullscreenEnabled => _blink.BlinkDocument.instance.fullscreenEnabled_Getter_(this);

  @DomName('Document.head')
  @DocsEditable()
  HeadElement get _head => _blink.BlinkDocument.instance.head_Getter_(this);

  @DomName('Document.hidden')
  @DocsEditable()
  @Experimental() // untriaged
  bool get hidden => _blink.BlinkDocument.instance.hidden_Getter_(this);

  @DomName('Document.implementation')
  @DocsEditable()
  DomImplementation get implementation => _blink.BlinkDocument.instance.implementation_Getter_(this);

  @DomName('Document.lastModified')
  @DocsEditable()
  String get _lastModified => _blink.BlinkDocument.instance.lastModified_Getter_(this);

  @DomName('Document.pointerLockElement')
  @DocsEditable()
  @Experimental() // untriaged
  Element get pointerLockElement => _blink.BlinkDocument.instance.pointerLockElement_Getter_(this);

  @DomName('Document.preferredStylesheetSet')
  @DocsEditable()
  String get _preferredStylesheetSet => _blink.BlinkDocument.instance.preferredStylesheetSet_Getter_(this);

  @DomName('Document.readyState')
  @DocsEditable()
  String get readyState => _blink.BlinkDocument.instance.readyState_Getter_(this);

  @DomName('Document.referrer')
  @DocsEditable()
  String get _referrer => _blink.BlinkDocument.instance.referrer_Getter_(this);

  @DomName('Document.rootElement')
  @DocsEditable()
  @Experimental() // untriaged
  SvgSvgElement get rootElement => _blink.BlinkDocument.instance.rootElement_Getter_(this);

  @DomName('Document.selectedStylesheetSet')
  @DocsEditable()
  String get _selectedStylesheetSet => _blink.BlinkDocument.instance.selectedStylesheetSet_Getter_(this);

  @DomName('Document.selectedStylesheetSet')
  @DocsEditable()
  void set _selectedStylesheetSet(String value) => _blink.BlinkDocument.instance.selectedStylesheetSet_Setter_(this, value);

  @DomName('Document.styleSheets')
  @DocsEditable()
  List<StyleSheet> get _styleSheets => _blink.BlinkDocument.instance.styleSheets_Getter_(this);

  @DomName('Document.timeline')
  @DocsEditable()
  @Experimental() // untriaged
  AnimationTimeline get timeline => _blink.BlinkDocument.instance.timeline_Getter_(this);

  @DomName('Document.title')
  @DocsEditable()
  String get _title => _blink.BlinkDocument.instance.title_Getter_(this);

  @DomName('Document.title')
  @DocsEditable()
  void set _title(String value) => _blink.BlinkDocument.instance.title_Setter_(this, value);

  @DomName('Document.visibilityState')
  @DocsEditable()
  @Experimental() // untriaged
  String get visibilityState => _blink.BlinkDocument.instance.visibilityState_Getter_(this);

  @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
  Element get _webkitFullscreenElement => _blink.BlinkDocument.instance.webkitFullscreenElement_Getter_(this);

  @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
  bool get _webkitFullscreenEnabled => _blink.BlinkDocument.instance.webkitFullscreenEnabled_Getter_(this);

  @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
  bool get _webkitHidden => _blink.BlinkDocument.instance.webkitHidden_Getter_(this);

  @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
  String get _webkitVisibilityState => _blink.BlinkDocument.instance.webkitVisibilityState_Getter_(this);

  @DomName('Document.adoptNode')
  @DocsEditable()
  Node adoptNode(Node node) => _blink.BlinkDocument.instance.adoptNode_Callback_1_(this, node);

  @DomName('Document.caretRangeFromPoint')
  @DocsEditable()
  // http://www.w3.org/TR/2009/WD-cssom-view-20090804/#dom-documentview-caretrangefrompoint
  @Experimental()
  Range _caretRangeFromPoint(int x, int y) => _blink.BlinkDocument.instance.caretRangeFromPoint_Callback_2_(this, x, y);

  @DomName('Document.createDocumentFragment')
  @DocsEditable()
  DocumentFragment createDocumentFragment() => _blink.BlinkDocument.instance.createDocumentFragment_Callback_0_(this);

  @DomName('Document.createElement')
  @DocsEditable()
  Element _createElement(String localName_OR_tagName, [String typeExtension]) => _blink.BlinkDocument.instance.createElement_Callback_2_(this, localName_OR_tagName, typeExtension);

  @DomName('Document.createElementNS')
  @DocsEditable()
  Element createElementNS(String namespaceURI, String qualifiedName, [String typeExtension]) => _blink.BlinkDocument.instance.createElementNS_Callback_3_(this, namespaceURI, qualifiedName, typeExtension);

  @DomName('Document.createEvent')
  @DocsEditable()
  Event _createEvent(String eventType) => _blink.BlinkDocument.instance.createEvent_Callback_1_(this, eventType);

  NodeIterator _createNodeIterator(Node root, [int whatToShow, NodeFilter filter]) {
    if (whatToShow != null) {
      return _blink.BlinkDocument.instance.createNodeIterator_Callback_3_(this, root, whatToShow, filter);
    }
    return _blink.BlinkDocument.instance.createNodeIterator_Callback_1_(this, root);
  }

  @DomName('Document.createRange')
  @DocsEditable()
  Range createRange() => _blink.BlinkDocument.instance.createRange_Callback_0_(this);

  @DomName('Document.createTextNode')
  @DocsEditable()
  Text _createTextNode(String data) => _blink.BlinkDocument.instance.createTextNode_Callback_1_(this, data);

  @DomName('Document.createTouch')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Touch _createTouch(Window window, EventTarget target, int identifier, num pageX, num pageY, num screenX, num screenY, num webkitRadiusX, num webkitRadiusY, num webkitRotationAngle, num webkitForce) => _blink.BlinkDocument.instance.createTouch_Callback_11_(this, window, target, identifier, pageX, pageY, screenX, screenY, webkitRadiusX, webkitRadiusY, webkitRotationAngle, webkitForce);

  @DomName('Document.createTouchList')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  TouchList _createTouchList(Touch touches) => _blink.BlinkDocument.instance.createTouchList_Callback_1_(this, touches);

  TreeWalker _createTreeWalker(Node root, [int whatToShow, NodeFilter filter]) {
    if (whatToShow != null) {
      return _blink.BlinkDocument.instance.createTreeWalker_Callback_3_(this, root, whatToShow, filter);
    }
    return _blink.BlinkDocument.instance.createTreeWalker_Callback_1_(this, root);
  }

  @DomName('Document.elementFromPoint')
  @DocsEditable()
  Element _elementFromPoint(int x, int y) => _blink.BlinkDocument.instance.elementFromPoint_Callback_2_(this, x, y);

  @DomName('Document.execCommand')
  @DocsEditable()
  bool execCommand(String command, bool userInterface, String value) => _blink.BlinkDocument.instance.execCommand_Callback_3_(this, command, userInterface, value);

  @DomName('Document.exitFullscreen')
  @DocsEditable()
  @Experimental() // untriaged
  void exitFullscreen() => _blink.BlinkDocument.instance.exitFullscreen_Callback_0_(this);

  @DomName('Document.exitPointerLock')
  @DocsEditable()
  @Experimental() // untriaged
  void exitPointerLock() => _blink.BlinkDocument.instance.exitPointerLock_Callback_0_(this);

  @DomName('Document.getCSSCanvasContext')
  @DocsEditable()
  // https://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariCSSRef/Articles/Functions.html
  @Experimental() // non-standard
  Object _getCssCanvasContext(String contextId, String name, int width, int height) => _blink.BlinkDocument.instance.getCSSCanvasContext_Callback_4_(this, contextId, name, width, height);

  @DomName('Document.getElementById')
  @DocsEditable()
  Element getElementById(String elementId) => _blink.BlinkDocument.instance.getElementById_Callback_1_(this, elementId);

  @DomName('Document.getElementsByClassName')
  @DocsEditable()
  List<Node> getElementsByClassName(String classNames) => _blink.BlinkDocument.instance.getElementsByClassName_Callback_1_(this, classNames);

  @DomName('Document.getElementsByName')
  @DocsEditable()
  List<Node> getElementsByName(String elementName) => _blink.BlinkDocument.instance.getElementsByName_Callback_1_(this, elementName);

  @DomName('Document.getElementsByTagName')
  @DocsEditable()
  List<Node> getElementsByTagName(String localName) => _blink.BlinkDocument.instance.getElementsByTagName_Callback_1_(this, localName);

  Node importNode(Node node, [bool deep]) {
    if (deep != null) {
      return _blink.BlinkDocument.instance.importNode_Callback_2_(this, node, deep);
    }
    return _blink.BlinkDocument.instance.importNode_Callback_1_(this, node);
  }

  @DomName('Document.queryCommandEnabled')
  @DocsEditable()
  bool queryCommandEnabled(String command) => _blink.BlinkDocument.instance.queryCommandEnabled_Callback_1_(this, command);

  @DomName('Document.queryCommandIndeterm')
  @DocsEditable()
  bool queryCommandIndeterm(String command) => _blink.BlinkDocument.instance.queryCommandIndeterm_Callback_1_(this, command);

  @DomName('Document.queryCommandState')
  @DocsEditable()
  bool queryCommandState(String command) => _blink.BlinkDocument.instance.queryCommandState_Callback_1_(this, command);

  @DomName('Document.queryCommandSupported')
  @DocsEditable()
  bool queryCommandSupported(String command) => _blink.BlinkDocument.instance.queryCommandSupported_Callback_1_(this, command);

  @DomName('Document.queryCommandValue')
  @DocsEditable()
  String queryCommandValue(String command) => _blink.BlinkDocument.instance.queryCommandValue_Callback_1_(this, command);

  @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() => _blink.BlinkDocument.instance.webkitExitFullscreen_Callback_0_(this);

  @DomName('Document.childElementCount')
  @DocsEditable()
  int get _childElementCount => _blink.BlinkDocument.instance.childElementCount_Getter_(this);

  @DomName('Document.children')
  @DocsEditable()
  List<Node> get _children => _blink.BlinkDocument.instance.children_Getter_(this);

  @DomName('Document.firstElementChild')
  @DocsEditable()
  Element get _firstElementChild => _blink.BlinkDocument.instance.firstElementChild_Getter_(this);

  @DomName('Document.lastElementChild')
  @DocsEditable()
  Element get _lastElementChild => _blink.BlinkDocument.instance.lastElementChild_Getter_(this);

  /**
   * 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) => _blink.BlinkDocument.instance.querySelector_Callback_1_(this, selectors);

  @DomName('Document.querySelectorAll')
  @DocsEditable()
  List<Node> _querySelectorAll(String selectors) => _blink.BlinkDocument.instance.querySelectorAll_Callback_1_(this, selectors);

  /// Stream of `abort` events handled by this [Document].
  @DomName('Document.onabort')
  @DocsEditable()
  Stream<Event> get onAbort => Element.abortEvent.forTarget(this);

  /// Stream of `beforecopy` events handled by this [Document].
  @DomName('Document.onbeforecopy')
  @DocsEditable()
  Stream<Event> get onBeforeCopy => Element.beforeCopyEvent.forTarget(this);

  /// Stream of `beforecut` events handled by this [Document].
  @DomName('Document.onbeforecut')
  @DocsEditable()
  Stream<Event> get onBeforeCut => Element.beforeCutEvent.forTarget(this);

  /// Stream of `beforepaste` events handled by this [Document].
  @DomName('Document.onbeforepaste')
  @DocsEditable()
  Stream<Event> get onBeforePaste => Element.beforePasteEvent.forTarget(this);

  /// Stream of `blur` events handled by this [Document].
  @DomName('Document.onblur')
  @DocsEditable()
  Stream<Event> get onBlur => Element.blurEvent.forTarget(this);

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

  @DomName('Document.oncanplaythrough')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onCanPlayThrough => Element.canPlayThroughEvent.forTarget(this);

  /// Stream of `change` events handled by this [Document].
  @DomName('Document.onchange')
  @DocsEditable()
  Stream<Event> get onChange => Element.changeEvent.forTarget(this);

  /// Stream of `click` events handled by this [Document].
  @DomName('Document.onclick')
  @DocsEditable()
  Stream<MouseEvent> get onClick => Element.clickEvent.forTarget(this);

  /// Stream of `contextmenu` events handled by this [Document].
  @DomName('Document.oncontextmenu')
  @DocsEditable()
  Stream<MouseEvent> get onContextMenu => Element.contextMenuEvent.forTarget(this);

  /// Stream of `copy` events handled by this [Document].
  @DomName('Document.oncopy')
  @DocsEditable()
  Stream<Event> get onCopy => Element.copyEvent.forTarget(this);

  /// Stream of `cut` events handled by this [Document].
  @DomName('Document.oncut')
  @DocsEditable()
  Stream<Event> get onCut => Element.cutEvent.forTarget(this);

  /// Stream of `doubleclick` events handled by this [Document].
  @DomName('Document.ondblclick')
  @DocsEditable()
  Stream<Event> get onDoubleClick => Element.doubleClickEvent.forTarget(this);

  /// Stream of `drag` events handled by this [Document].
  @DomName('Document.ondrag')
  @DocsEditable()
  Stream<MouseEvent> get onDrag => Element.dragEvent.forTarget(this);

  /// Stream of `dragend` events handled by this [Document].
  @DomName('Document.ondragend')
  @DocsEditable()
  Stream<MouseEvent> get onDragEnd => Element.dragEndEvent.forTarget(this);

  /// Stream of `dragenter` events handled by this [Document].
  @DomName('Document.ondragenter')
  @DocsEditable()
  Stream<MouseEvent> get onDragEnter => Element.dragEnterEvent.forTarget(this);

  /// Stream of `dragleave` events handled by this [Document].
  @DomName('Document.ondragleave')
  @DocsEditable()
  Stream<MouseEvent> get onDragLeave => Element.dragLeaveEvent.forTarget(this);

  /// Stream of `dragover` events handled by this [Document].
  @DomName('Document.ondragover')
  @DocsEditable()
  Stream<MouseEvent> get onDragOver => Element.dragOverEvent.forTarget(this);

  /// Stream of `dragstart` events handled by this [Document].
  @DomName('Document.ondragstart')
  @DocsEditable()
  Stream<MouseEvent> get onDragStart => Element.dragStartEvent.forTarget(this);

  /// Stream of `drop` events handled by this [Document].
  @DomName('Document.ondrop')
  @DocsEditable()
  Stream<MouseEvent> get onDrop => Element.dropEvent.forTarget(this);

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

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

  @DomName('Document.onended')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onEnded => Element.endedEvent.forTarget(this);

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

  /// Stream of `focus` events handled by this [Document].
  @DomName('Document.onfocus')
  @DocsEditable()
  Stream<Event> get onFocus => Element.focusEvent.forTarget(this);

  /// Stream of `input` events handled by this [Document].
  @DomName('Document.oninput')
  @DocsEditable()
  Stream<Event> get onInput => Element.inputEvent.forTarget(this);

  /// Stream of `invalid` events handled by this [Document].
  @DomName('Document.oninvalid')
  @DocsEditable()
  Stream<Event> get onInvalid => Element.invalidEvent.forTarget(this);

  /// Stream of `keydown` events handled by this [Document].
  @DomName('Document.onkeydown')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyDown => Element.keyDownEvent.forTarget(this);

  /// Stream of `keypress` events handled by this [Document].
  @DomName('Document.onkeypress')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyPress => Element.keyPressEvent.forTarget(this);

  /// Stream of `keyup` events handled by this [Document].
  @DomName('Document.onkeyup')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyUp => Element.keyUpEvent.forTarget(this);

  /// Stream of `load` events handled by this [Document].
  @DomName('Document.onload')
  @DocsEditable()
  Stream<Event> get onLoad => Element.loadEvent.forTarget(this);

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

  @DomName('Document.onloadedmetadata')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onLoadedMetadata => Element.loadedMetadataEvent.forTarget(this);

  /// Stream of `mousedown` events handled by this [Document].
  @DomName('Document.onmousedown')
  @DocsEditable()
  Stream<MouseEvent> get onMouseDown => Element.mouseDownEvent.forTarget(this);

  /// Stream of `mouseenter` events handled by this [Document].
  @DomName('Document.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseEnter => Element.mouseEnterEvent.forTarget(this);

  /// Stream of `mouseleave` events handled by this [Document].
  @DomName('Document.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseLeave => Element.mouseLeaveEvent.forTarget(this);

  /// Stream of `mousemove` events handled by this [Document].
  @DomName('Document.onmousemove')
  @DocsEditable()
  Stream<MouseEvent> get onMouseMove => Element.mouseMoveEvent.forTarget(this);

  /// Stream of `mouseout` events handled by this [Document].
  @DomName('Document.onmouseout')
  @DocsEditable()
  Stream<MouseEvent> get onMouseOut => Element.mouseOutEvent.forTarget(this);

  /// Stream of `mouseover` events handled by this [Document].
  @DomName('Document.onmouseover')
  @DocsEditable()
  Stream<MouseEvent> get onMouseOver => Element.mouseOverEvent.forTarget(this);

  /// Stream of `mouseup` events handled by this [Document].
  @DomName('Document.onmouseup')
  @DocsEditable()
  Stream<MouseEvent> get onMouseUp => Element.mouseUpEvent.forTarget(this);

  /// Stream of `mousewheel` events handled by this [Document].
  @DomName('Document.onmousewheel')
  @DocsEditable()
  Stream<WheelEvent> get onMouseWheel => Element.mouseWheelEvent.forTarget(this);

  /// Stream of `paste` events handled by this [Document].
  @DomName('Document.onpaste')
  @DocsEditable()
  Stream<Event> get onPaste => Element.pasteEvent.forTarget(this);

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

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

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

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

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

  @DomName('Document.onratechange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onRateChange => Element.rateChangeEvent.forTarget(this);

  /// Stream of `readystatechange` events handled by this [Document].
  @DomName('Document.onreadystatechange')
  @DocsEditable()
  Stream<Event> get onReadyStateChange => readyStateChangeEvent.forTarget(this);

  /// Stream of `reset` events handled by this [Document].
  @DomName('Document.onreset')
  @DocsEditable()
  Stream<Event> get onReset => Element.resetEvent.forTarget(this);

  @DomName('Document.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onResize => Element.resizeEvent.forTarget(this);

  /// Stream of `scroll` events handled by this [Document].
  @DomName('Document.onscroll')
  @DocsEditable()
  Stream<Event> get onScroll => Element.scrollEvent.forTarget(this);

  /// Stream of `search` events handled by this [Document].
  @DomName('Document.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  Stream<Event> get onSearch => Element.searchEvent.forTarget(this);

  /// Stream of `securitypolicyviolation` events handled by this [Document].
  @DomName('Document.onsecuritypolicyviolation')
  @DocsEditable()
  // https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#widl-Document-onsecuritypolicyviolation
  @Experimental()
  Stream<SecurityPolicyViolationEvent> get onSecurityPolicyViolation => securityPolicyViolationEvent.forTarget(this);

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

  @DomName('Document.onseeking')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSeeking => Element.seekingEvent.forTarget(this);

  /// Stream of `select` events handled by this [Document].
  @DomName('Document.onselect')
  @DocsEditable()
  Stream<Event> get onSelect => Element.selectEvent.forTarget(this);

  /// Stream of `selectionchange` events handled by this [Document].
  @DomName('Document.onselectionchange')
  @DocsEditable()
  Stream<Event> get onSelectionChange => selectionChangeEvent.forTarget(this);

  /// Stream of `selectstart` events handled by this [Document].
  @DomName('Document.onselectstart')
  @DocsEditable()
  Stream<Event> get onSelectStart => Element.selectStartEvent.forTarget(this);

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

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

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

  @DomName('Document.ontimeupdate')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onTimeUpdate => Element.timeUpdateEvent.forTarget(this);

  /// Stream of `touchcancel` events handled by this [Document].
  @DomName('Document.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchCancel => Element.touchCancelEvent.forTarget(this);

  /// Stream of `touchend` events handled by this [Document].
  @DomName('Document.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchEnd => Element.touchEndEvent.forTarget(this);

  /// Stream of `touchmove` events handled by this [Document].
  @DomName('Document.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchMove => Element.touchMoveEvent.forTarget(this);

  /// Stream of `touchstart` events handled by this [Document].
  @DomName('Document.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchStart => Element.touchStartEvent.forTarget(this);

  @DomName('Document.onvolumechange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onVolumeChange => Element.volumeChangeEvent.forTarget(this);

  @DomName('Document.onwaiting')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onWaiting => Element.waitingEvent.forTarget(this);

  /// Stream of `fullscreenchange` events handled by this [Document].
  @DomName('Document.onwebkitfullscreenchange')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  Stream<Event> get onFullscreenChange => Element.fullscreenChangeEvent.forTarget(this);

  /// Stream of `fullscreenerror` events handled by this [Document].
  @DomName('Document.onwebkitfullscreenerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  Stream<Event> get onFullscreenError => Element.fullscreenErrorEvent.forTarget(this);

  /**
   * Finds all descendant elements of this document that match the specified
   * group of selectors.
   *
   * Unless your webpage contains multiple documents, the top-level
   * [querySelectorAll]
   * method behaves the same as this method, so you should use it instead to
   * save typing a few characters.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var items = document.querySelectorAll('.itemClassName');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  ElementList querySelectorAll(String selectors) {
    return new _FrozenElementList._wrap(_querySelectorAll(selectors));
  }

  /**
   * Alias for [querySelector]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @Experimental()
  @DomName('Document.querySelector')
  Element query(String relativeSelectors) => querySelector(relativeSelectors);

  /**
   * Alias for [querySelectorAll]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @Experimental()
  @DomName('Document.querySelectorAll')
  ElementList queryAll(String relativeSelectors) =>
      querySelectorAll(relativeSelectors);

  /// Checks if [registerElement] is supported on the current platform.
  bool get supportsRegisterElement {
    return true;
  }

  /// *Deprecated*: use [supportsRegisterElement] instead.
  @deprecated
  bool get supportsRegister => supportsRegisterElement;

  @DomName('Document.createElement')
  Element createElement(String tagName, [String typeExtension]) {
    if (typeExtension != null) {
      return _createElement(tagName, typeExtension);
    } else {
      // Fast-path for Dartium when typeExtension is not needed.
      return _Utils.createElement(this, tagName);
    }
  }

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


@DomName('DocumentFragment')
class DocumentFragment extends Node implements ParentNode {
  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');

  List<Element> _docChildren;

  List<Element> get children {
    if (_docChildren == null) {
      _docChildren = new FilteredElementList(this);
    }
    return _docChildren;
  }

  void set children(List<Element> value) {
    // Copy list first since we don't want liveness during iteration.
    List copy = new List.from(value);
    var children = this.children;
    children.clear();
    children.addAll(copy);
  }

  /**
   * Finds all descendant elements of this document fragment that match the
   * specified group of selectors.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var items = document.querySelectorAll('.itemClassName');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  ElementList querySelectorAll(String selectors) =>
    new _FrozenElementList._wrap(_querySelectorAll(selectors));



  String get innerHtml {
    final e = new Element.tag("div");
    e.append(this.clone(true));
    return e.innerHtml;
  }

  void set innerHtml(String value) {
    this.setInnerHtml(value);
  }

  void setInnerHtml(String html,
    {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {

    this.nodes.clear();
    append(document.body.createFragment(
        html, validator: validator, treeSanitizer: treeSanitizer));
  }

  /**
   * Adds the specified text as a text node after the last child of this
   * document fragment.
   */
  void appendText(String text) {
    this.append(new Text(text));
  }


  /**
   * Parses the specified text as HTML and adds the resulting node after the
   * last child of this document fragment.
   */
  void appendHtml(String text) {
    this.append(new DocumentFragment.html(text));
  }

  /** 
   * Alias for [querySelector]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @Experimental()
  @DomName('DocumentFragment.querySelector')
  Element query(String relativeSelectors) {
    return querySelector(relativeSelectors);
  }

  /** 
   * Alias for [querySelectorAll]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @Experimental()
  @DomName('DocumentFragment.querySelectorAll')
  ElementList queryAll(String relativeSelectors) {
    return querySelectorAll(relativeSelectors);
  }
  // To suppress missing implicit constructor warnings.
  factory DocumentFragment._() { throw new UnsupportedError("Not supported"); }

  @DomName('DocumentFragment.getElementById')
  @DocsEditable()
  @Experimental() // untriaged
  Element getElementById(String elementId) => _blink.BlinkDocumentFragment.instance.getElementById_Callback_1_(this, elementId);

  @DomName('DocumentFragment.childElementCount')
  @DocsEditable()
  int get _childElementCount => _blink.BlinkDocumentFragment.instance.childElementCount_Getter_(this);

  @DomName('DocumentFragment.firstElementChild')
  @DocsEditable()
  Element get _firstElementChild => _blink.BlinkDocumentFragment.instance.firstElementChild_Getter_(this);

  @DomName('DocumentFragment.lastElementChild')
  @DocsEditable()
  Element get _lastElementChild => _blink.BlinkDocumentFragment.instance.lastElementChild_Getter_(this);

  /**
   * 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) => _blink.BlinkDocumentFragment.instance.querySelector_Callback_1_(this, selectors);

  @DomName('DocumentFragment.querySelectorAll')
  @DocsEditable()
  List<Node> _querySelectorAll(String selectors) => _blink.BlinkDocumentFragment.instance.querySelectorAll_Callback_1_(this, 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.

// WARNING: Do not edit - generated code.


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

  @DomName('DOMError.DOMError')
  @DocsEditable()
  factory DomError(String name, [String message]) {
    return _blink.BlinkDOMError.instance.constructorCallback_2_(name, message);
  }

  @DomName('DOMError.message')
  @DocsEditable()
  @Experimental() // untriaged
  String get message => _blink.BlinkDOMError.instance.message_Getter_(this);

  @DomName('DOMError.name')
  @DocsEditable()
  String get name => _blink.BlinkDOMError.instance.name_Getter_(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('DOMException')
@Unstable()
class DomException extends NativeFieldWrapperClass2 {

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

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

  @DomName('DOMException.message')
  @DocsEditable()
  String get message => _blink.BlinkDOMException.instance.message_Getter_(this);

  @DomName('DOMException.name')
  @DocsEditable()
  String get name => _blink.BlinkDOMException.instance.name_Getter_(this);

  @DomName('DOMException.toString')
  @DocsEditable()
  String toString() => _blink.BlinkDOMException.instance.toString_Callback_0_(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.


@DocsEditable()
@DomName('DOMImplementation')
class DomImplementation extends NativeFieldWrapperClass2 {
  // 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) => _blink.BlinkDOMImplementation.instance.createDocument_Callback_3_(this, namespaceURI, qualifiedName, doctype);

  @DomName('DOMImplementation.createDocumentType')
  @DocsEditable()
  _DocumentType createDocumentType(String qualifiedName, String publicId, String systemId) => _blink.BlinkDOMImplementation.instance.createDocumentType_Callback_3_(this, qualifiedName, publicId, systemId);

  @DomName('DOMImplementation.createHTMLDocument')
  @DocsEditable()
  HtmlDocument createHtmlDocument(String title) => _blink.BlinkDOMImplementation.instance.createHTMLDocument_Callback_1_(this, title);

  @DomName('DOMImplementation.hasFeature')
  @DocsEditable()
  bool hasFeature(String feature, String version) => _blink.BlinkDOMImplementation.instance.hasFeature_Callback_2_(this, feature, version);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


@DocsEditable()
@DomName('DOMMatrix')
@Experimental() // untriaged
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 _blink.BlinkDOMMatrix.instance.constructorCallback_0_();
    }
    if ((other is DomMatrixReadOnly || other == null)) {
      return _blink.BlinkDOMMatrix.instance.constructorCallback_1_(other);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('DOMMatrix.a')
  @DocsEditable()
  @Experimental() // untriaged
  num get a => _blink.BlinkDOMMatrix.instance.a_Getter_(this);

  @DomName('DOMMatrix.a')
  @DocsEditable()
  @Experimental() // untriaged
  void set a(num value) => _blink.BlinkDOMMatrix.instance.a_Setter_(this, value);

  @DomName('DOMMatrix.b')
  @DocsEditable()
  @Experimental() // untriaged
  num get b => _blink.BlinkDOMMatrix.instance.b_Getter_(this);

  @DomName('DOMMatrix.b')
  @DocsEditable()
  @Experimental() // untriaged
  void set b(num value) => _blink.BlinkDOMMatrix.instance.b_Setter_(this, value);

  @DomName('DOMMatrix.c')
  @DocsEditable()
  @Experimental() // untriaged
  num get c => _blink.BlinkDOMMatrix.instance.c_Getter_(this);

  @DomName('DOMMatrix.c')
  @DocsEditable()
  @Experimental() // untriaged
  void set c(num value) => _blink.BlinkDOMMatrix.instance.c_Setter_(this, value);

  @DomName('DOMMatrix.d')
  @DocsEditable()
  @Experimental() // untriaged
  num get d => _blink.BlinkDOMMatrix.instance.d_Getter_(this);

  @DomName('DOMMatrix.d')
  @DocsEditable()
  @Experimental() // untriaged
  void set d(num value) => _blink.BlinkDOMMatrix.instance.d_Setter_(this, value);

  @DomName('DOMMatrix.e')
  @DocsEditable()
  @Experimental() // untriaged
  num get e => _blink.BlinkDOMMatrix.instance.e_Getter_(this);

  @DomName('DOMMatrix.e')
  @DocsEditable()
  @Experimental() // untriaged
  void set e(num value) => _blink.BlinkDOMMatrix.instance.e_Setter_(this, value);

  @DomName('DOMMatrix.f')
  @DocsEditable()
  @Experimental() // untriaged
  num get f => _blink.BlinkDOMMatrix.instance.f_Getter_(this);

  @DomName('DOMMatrix.f')
  @DocsEditable()
  @Experimental() // untriaged
  void set f(num value) => _blink.BlinkDOMMatrix.instance.f_Setter_(this, value);

  @DomName('DOMMatrix.m11')
  @DocsEditable()
  @Experimental() // untriaged
  num get m11 => _blink.BlinkDOMMatrix.instance.m11_Getter_(this);

  @DomName('DOMMatrix.m11')
  @DocsEditable()
  @Experimental() // untriaged
  void set m11(num value) => _blink.BlinkDOMMatrix.instance.m11_Setter_(this, value);

  @DomName('DOMMatrix.m12')
  @DocsEditable()
  @Experimental() // untriaged
  num get m12 => _blink.BlinkDOMMatrix.instance.m12_Getter_(this);

  @DomName('DOMMatrix.m12')
  @DocsEditable()
  @Experimental() // untriaged
  void set m12(num value) => _blink.BlinkDOMMatrix.instance.m12_Setter_(this, value);

  @DomName('DOMMatrix.m13')
  @DocsEditable()
  @Experimental() // untriaged
  num get m13 => _blink.BlinkDOMMatrix.instance.m13_Getter_(this);

  @DomName('DOMMatrix.m13')
  @DocsEditable()
  @Experimental() // untriaged
  void set m13(num value) => _blink.BlinkDOMMatrix.instance.m13_Setter_(this, value);

  @DomName('DOMMatrix.m14')
  @DocsEditable()
  @Experimental() // untriaged
  num get m14 => _blink.BlinkDOMMatrix.instance.m14_Getter_(this);

  @DomName('DOMMatrix.m14')
  @DocsEditable()
  @Experimental() // untriaged
  void set m14(num value) => _blink.BlinkDOMMatrix.instance.m14_Setter_(this, value);

  @DomName('DOMMatrix.m21')
  @DocsEditable()
  @Experimental() // untriaged
  num get m21 => _blink.BlinkDOMMatrix.instance.m21_Getter_(this);

  @DomName('DOMMatrix.m21')
  @DocsEditable()
  @Experimental() // untriaged
  void set m21(num value) => _blink.BlinkDOMMatrix.instance.m21_Setter_(this, value);

  @DomName('DOMMatrix.m22')
  @DocsEditable()
  @Experimental() // untriaged
  num get m22 => _blink.BlinkDOMMatrix.instance.m22_Getter_(this);

  @DomName('DOMMatrix.m22')
  @DocsEditable()
  @Experimental() // untriaged
  void set m22(num value) => _blink.BlinkDOMMatrix.instance.m22_Setter_(this, value);

  @DomName('DOMMatrix.m23')
  @DocsEditable()
  @Experimental() // untriaged
  num get m23 => _blink.BlinkDOMMatrix.instance.m23_Getter_(this);

  @DomName('DOMMatrix.m23')
  @DocsEditable()
  @Experimental() // untriaged
  void set m23(num value) => _blink.BlinkDOMMatrix.instance.m23_Setter_(this, value);

  @DomName('DOMMatrix.m24')
  @DocsEditable()
  @Experimental() // untriaged
  num get m24 => _blink.BlinkDOMMatrix.instance.m24_Getter_(this);

  @DomName('DOMMatrix.m24')
  @DocsEditable()
  @Experimental() // untriaged
  void set m24(num value) => _blink.BlinkDOMMatrix.instance.m24_Setter_(this, value);

  @DomName('DOMMatrix.m31')
  @DocsEditable()
  @Experimental() // untriaged
  num get m31 => _blink.BlinkDOMMatrix.instance.m31_Getter_(this);

  @DomName('DOMMatrix.m31')
  @DocsEditable()
  @Experimental() // untriaged
  void set m31(num value) => _blink.BlinkDOMMatrix.instance.m31_Setter_(this, value);

  @DomName('DOMMatrix.m32')
  @DocsEditable()
  @Experimental() // untriaged
  num get m32 => _blink.BlinkDOMMatrix.instance.m32_Getter_(this);

  @DomName('DOMMatrix.m32')
  @DocsEditable()
  @Experimental() // untriaged
  void set m32(num value) => _blink.BlinkDOMMatrix.instance.m32_Setter_(this, value);

  @DomName('DOMMatrix.m33')
  @DocsEditable()
  @Experimental() // untriaged
  num get m33 => _blink.BlinkDOMMatrix.instance.m33_Getter_(this);

  @DomName('DOMMatrix.m33')
  @DocsEditable()
  @Experimental() // untriaged
  void set m33(num value) => _blink.BlinkDOMMatrix.instance.m33_Setter_(this, value);

  @DomName('DOMMatrix.m34')
  @DocsEditable()
  @Experimental() // untriaged
  num get m34 => _blink.BlinkDOMMatrix.instance.m34_Getter_(this);

  @DomName('DOMMatrix.m34')
  @DocsEditable()
  @Experimental() // untriaged
  void set m34(num value) => _blink.BlinkDOMMatrix.instance.m34_Setter_(this, value);

  @DomName('DOMMatrix.m41')
  @DocsEditable()
  @Experimental() // untriaged
  num get m41 => _blink.BlinkDOMMatrix.instance.m41_Getter_(this);

  @DomName('DOMMatrix.m41')
  @DocsEditable()
  @Experimental() // untriaged
  void set m41(num value) => _blink.BlinkDOMMatrix.instance.m41_Setter_(this, value);

  @DomName('DOMMatrix.m42')
  @DocsEditable()
  @Experimental() // untriaged
  num get m42 => _blink.BlinkDOMMatrix.instance.m42_Getter_(this);

  @DomName('DOMMatrix.m42')
  @DocsEditable()
  @Experimental() // untriaged
  void set m42(num value) => _blink.BlinkDOMMatrix.instance.m42_Setter_(this, value);

  @DomName('DOMMatrix.m43')
  @DocsEditable()
  @Experimental() // untriaged
  num get m43 => _blink.BlinkDOMMatrix.instance.m43_Getter_(this);

  @DomName('DOMMatrix.m43')
  @DocsEditable()
  @Experimental() // untriaged
  void set m43(num value) => _blink.BlinkDOMMatrix.instance.m43_Setter_(this, value);

  @DomName('DOMMatrix.m44')
  @DocsEditable()
  @Experimental() // untriaged
  num get m44 => _blink.BlinkDOMMatrix.instance.m44_Getter_(this);

  @DomName('DOMMatrix.m44')
  @DocsEditable()
  @Experimental() // untriaged
  void set m44(num value) => _blink.BlinkDOMMatrix.instance.m44_Setter_(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.

// WARNING: Do not edit - generated code.


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

  @DomName('DOMMatrixReadOnly.a')
  @DocsEditable()
  @Experimental() // untriaged
  double get a => _blink.BlinkDOMMatrixReadOnly.instance.a_Getter_(this);

  @DomName('DOMMatrixReadOnly.b')
  @DocsEditable()
  @Experimental() // untriaged
  double get b => _blink.BlinkDOMMatrixReadOnly.instance.b_Getter_(this);

  @DomName('DOMMatrixReadOnly.c')
  @DocsEditable()
  @Experimental() // untriaged
  double get c => _blink.BlinkDOMMatrixReadOnly.instance.c_Getter_(this);

  @DomName('DOMMatrixReadOnly.d')
  @DocsEditable()
  @Experimental() // untriaged
  double get d => _blink.BlinkDOMMatrixReadOnly.instance.d_Getter_(this);

  @DomName('DOMMatrixReadOnly.e')
  @DocsEditable()
  @Experimental() // untriaged
  double get e => _blink.BlinkDOMMatrixReadOnly.instance.e_Getter_(this);

  @DomName('DOMMatrixReadOnly.f')
  @DocsEditable()
  @Experimental() // untriaged
  double get f => _blink.BlinkDOMMatrixReadOnly.instance.f_Getter_(this);

  @DomName('DOMMatrixReadOnly.is2D')
  @DocsEditable()
  @Experimental() // untriaged
  bool get is2D => _blink.BlinkDOMMatrixReadOnly.instance.is2D_Getter_(this);

  @DomName('DOMMatrixReadOnly.isIdentity')
  @DocsEditable()
  @Experimental() // untriaged
  bool get isIdentity => _blink.BlinkDOMMatrixReadOnly.instance.isIdentity_Getter_(this);

  @DomName('DOMMatrixReadOnly.m11')
  @DocsEditable()
  @Experimental() // untriaged
  double get m11 => _blink.BlinkDOMMatrixReadOnly.instance.m11_Getter_(this);

  @DomName('DOMMatrixReadOnly.m12')
  @DocsEditable()
  @Experimental() // untriaged
  double get m12 => _blink.BlinkDOMMatrixReadOnly.instance.m12_Getter_(this);

  @DomName('DOMMatrixReadOnly.m13')
  @DocsEditable()
  @Experimental() // untriaged
  double get m13 => _blink.BlinkDOMMatrixReadOnly.instance.m13_Getter_(this);

  @DomName('DOMMatrixReadOnly.m14')
  @DocsEditable()
  @Experimental() // untriaged
  double get m14 => _blink.BlinkDOMMatrixReadOnly.instance.m14_Getter_(this);

  @DomName('DOMMatrixReadOnly.m21')
  @DocsEditable()
  @Experimental() // untriaged
  double get m21 => _blink.BlinkDOMMatrixReadOnly.instance.m21_Getter_(this);

  @DomName('DOMMatrixReadOnly.m22')
  @DocsEditable()
  @Experimental() // untriaged
  double get m22 => _blink.BlinkDOMMatrixReadOnly.instance.m22_Getter_(this);

  @DomName('DOMMatrixReadOnly.m23')
  @DocsEditable()
  @Experimental() // untriaged
  double get m23 => _blink.BlinkDOMMatrixReadOnly.instance.m23_Getter_(this);

  @DomName('DOMMatrixReadOnly.m24')
  @DocsEditable()
  @Experimental() // untriaged
  double get m24 => _blink.BlinkDOMMatrixReadOnly.instance.m24_Getter_(this);

  @DomName('DOMMatrixReadOnly.m31')
  @DocsEditable()
  @Experimental() // untriaged
  double get m31 => _blink.BlinkDOMMatrixReadOnly.instance.m31_Getter_(this);

  @DomName('DOMMatrixReadOnly.m32')
  @DocsEditable()
  @Experimental() // untriaged
  double get m32 => _blink.BlinkDOMMatrixReadOnly.instance.m32_Getter_(this);

  @DomName('DOMMatrixReadOnly.m33')
  @DocsEditable()
  @Experimental() // untriaged
  double get m33 => _blink.BlinkDOMMatrixReadOnly.instance.m33_Getter_(this);

  @DomName('DOMMatrixReadOnly.m34')
  @DocsEditable()
  @Experimental() // untriaged
  double get m34 => _blink.BlinkDOMMatrixReadOnly.instance.m34_Getter_(this);

  @DomName('DOMMatrixReadOnly.m41')
  @DocsEditable()
  @Experimental() // untriaged
  double get m41 => _blink.BlinkDOMMatrixReadOnly.instance.m41_Getter_(this);

  @DomName('DOMMatrixReadOnly.m42')
  @DocsEditable()
  @Experimental() // untriaged
  double get m42 => _blink.BlinkDOMMatrixReadOnly.instance.m42_Getter_(this);

  @DomName('DOMMatrixReadOnly.m43')
  @DocsEditable()
  @Experimental() // untriaged
  double get m43 => _blink.BlinkDOMMatrixReadOnly.instance.m43_Getter_(this);

  @DomName('DOMMatrixReadOnly.m44')
  @DocsEditable()
  @Experimental() // untriaged
  double get m44 => _blink.BlinkDOMMatrixReadOnly.instance.m44_Getter_(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.


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

  @DomName('DOMParser.DOMParser')
  @DocsEditable()
  factory DomParser() {
    return _blink.BlinkDOMParser.instance.constructorCallback_0_();
  }

  @DomName('DOMParser.parseFromString')
  @DocsEditable()
  Document parseFromString(String str, String contentType) => _blink.BlinkDOMParser.instance.parseFromString_Callback_2_(this, str, contentType);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

  @DomName('DOMPoint.DOMPoint')
  @DocsEditable()
  factory DomPoint([point_OR_x, num y, num z, num w]) {
    if (point_OR_x == null && y == null && z == null && w == null) {
      return _blink.BlinkDOMPoint.instance.constructorCallback_0_();
    }
    if ((point_OR_x is Map || point_OR_x == null) && y == null && z == null && w == null) {
      return _blink.BlinkDOMPoint.instance.constructorCallback_1_(point_OR_x);
    }
    if ((y is num || y == null) && (point_OR_x is num || point_OR_x == null) && z == null && w == null) {
      return _blink.BlinkDOMPoint.instance.constructorCallback_2_(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 _blink.BlinkDOMPoint.instance.constructorCallback_3_(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 _blink.BlinkDOMPoint.instance.constructorCallback_4_(point_OR_x, y, z, w);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('DOMPoint.w')
  @DocsEditable()
  @Experimental() // untriaged
  num get w => _blink.BlinkDOMPoint.instance.w_Getter_(this);

  @DomName('DOMPoint.w')
  @DocsEditable()
  @Experimental() // untriaged
  void set w(num value) => _blink.BlinkDOMPoint.instance.w_Setter_(this, value);

  @DomName('DOMPoint.x')
  @DocsEditable()
  @Experimental() // untriaged
  num get x => _blink.BlinkDOMPoint.instance.x_Getter_(this);

  @DomName('DOMPoint.x')
  @DocsEditable()
  @Experimental() // untriaged
  void set x(num value) => _blink.BlinkDOMPoint.instance.x_Setter_(this, value);

  @DomName('DOMPoint.y')
  @DocsEditable()
  @Experimental() // untriaged
  num get y => _blink.BlinkDOMPoint.instance.y_Getter_(this);

  @DomName('DOMPoint.y')
  @DocsEditable()
  @Experimental() // untriaged
  void set y(num value) => _blink.BlinkDOMPoint.instance.y_Setter_(this, value);

  @DomName('DOMPoint.z')
  @DocsEditable()
  @Experimental() // untriaged
  num get z => _blink.BlinkDOMPoint.instance.z_Getter_(this);

  @DomName('DOMPoint.z')
  @DocsEditable()
  @Experimental() // untriaged
  void set z(num value) => _blink.BlinkDOMPoint.instance.z_Setter_(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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('DOMPointReadOnly')
@Experimental() // untriaged
class DomPointReadOnly extends NativeFieldWrapperClass2 {
  // 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 _blink.BlinkDOMPointReadOnly.instance.constructorCallback_4_(x, y, z, w);
  }

  @DomName('DOMPointReadOnly.w')
  @DocsEditable()
  @Experimental() // untriaged
  double get w => _blink.BlinkDOMPointReadOnly.instance.w_Getter_(this);

  @DomName('DOMPointReadOnly.x')
  @DocsEditable()
  @Experimental() // untriaged
  double get x => _blink.BlinkDOMPointReadOnly.instance.x_Getter_(this);

  @DomName('DOMPointReadOnly.y')
  @DocsEditable()
  @Experimental() // untriaged
  double get y => _blink.BlinkDOMPointReadOnly.instance.y_Getter_(this);

  @DomName('DOMPointReadOnly.z')
  @DocsEditable()
  @Experimental() // untriaged
  double get z => _blink.BlinkDOMPointReadOnly.instance.z_Getter_(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
class DomRectReadOnly extends NativeFieldWrapperClass2 implements Rectangle {

  // NOTE! All code below should be common with RectangleBase.
   String toString() {
    return 'Rectangle ($left, $top) $width x $height';
  }

  bool operator ==(other) {
    if (other is !Rectangle) return false;
    return left == other.left && top == other.top && width == other.width &&
        height == other.height;
  }

  int get hashCode => _JenkinsSmiHash.hash4(left.hashCode, top.hashCode,
      width.hashCode, height.hashCode);

  /**
   * Computes the intersection of `this` and [other].
   *
   * The intersection of two axis-aligned rectangles, if any, is always another
   * axis-aligned rectangle.
   *
   * Returns the intersection of this and `other`, or null if they don't
   * intersect.
   */
  Rectangle intersection(Rectangle other) {
    var x0 = max(left, other.left);
    var x1 = min(left + width, other.left + other.width);

    if (x0 <= x1) {
      var y0 = max(top, other.top);
      var y1 = min(top + height, other.top + other.height);

      if (y0 <= y1) {
        return new Rectangle(x0, y0, x1 - x0, y1 - y0);
      }
    }
    return null;
  }


  /**
   * Returns true if `this` intersects [other].
   */
  bool intersects(Rectangle<num> other) {
    return (left <= other.left + other.width &&
        other.left <= left + width &&
        top <= other.top + other.height &&
        other.top <= top + height);
  }

  /**
   * Returns a new rectangle which completely contains `this` and [other].
   */
  Rectangle boundingBox(Rectangle other) {
    var right = max(this.left + this.width, other.left + other.width);
    var bottom = max(this.top + this.height, other.top + other.height);

    var left = min(this.left, other.left);
    var top = min(this.top, other.top);

    return new Rectangle(left, top, right - left, bottom - top);
  }

  /**
   * Tests whether `this` entirely contains [another].
   */
  bool containsRectangle(Rectangle<num> another) {
    return left <= another.left &&
           left + width >= another.left + another.width &&
           top <= another.top &&
           top + height >= another.top + another.height;
  }

  /**
   * Tests whether [another] is inside or along the edges of `this`.
   */
  bool containsPoint(Point<num> another) {
    return another.x >= left &&
           another.x <= left + width &&
           another.y >= top &&
           another.y <= top + height;
  }

  Point get topLeft => new Point(this.left, this.top);
  Point get topRight => new Point(this.left + this.width, this.top);
  Point get bottomRight => new Point(this.left + this.width,
      this.top + this.height);
  Point get bottomLeft => new Point(this.left,
      this.top + this.height);

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

  @DomName('DOMRectReadOnly.DOMRectReadOnly')
  @DocsEditable()
  factory DomRectReadOnly(num x, num y, num width, num height) {
    return _blink.BlinkDOMRectReadOnly.instance.constructorCallback_4_(x, y, width, height);
  }

  @DomName('DOMRectReadOnly.bottom')
  @DocsEditable()
  @Experimental() // untriaged
  double get bottom => _blink.BlinkDOMRectReadOnly.instance.bottom_Getter_(this);

  @DomName('DOMRectReadOnly.height')
  @DocsEditable()
  @Experimental() // untriaged
  double get height => _blink.BlinkDOMRectReadOnly.instance.height_Getter_(this);

  @DomName('DOMRectReadOnly.left')
  @DocsEditable()
  @Experimental() // untriaged
  double get left => _blink.BlinkDOMRectReadOnly.instance.left_Getter_(this);

  @DomName('DOMRectReadOnly.right')
  @DocsEditable()
  @Experimental() // untriaged
  double get right => _blink.BlinkDOMRectReadOnly.instance.right_Getter_(this);

  @DomName('DOMRectReadOnly.top')
  @DocsEditable()
  @Experimental() // untriaged
  double get top => _blink.BlinkDOMRectReadOnly.instance.top_Getter_(this);

  @DomName('DOMRectReadOnly.width')
  @DocsEditable()
  @Experimental() // untriaged
  double get width => _blink.BlinkDOMRectReadOnly.instance.width_Getter_(this);

  @DomName('DOMRectReadOnly.x')
  @DocsEditable()
  @Experimental() // untriaged
  double get x => _blink.BlinkDOMRectReadOnly.instance.x_Getter_(this);

  @DomName('DOMRectReadOnly.y')
  @DocsEditable()
  @Experimental() // untriaged
  double get y => _blink.BlinkDOMRectReadOnly.instance.y_Getter_(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.


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

  @DomName('DOMSettableTokenList.value')
  @DocsEditable()
  String get value => _blink.BlinkDOMSettableTokenList.instance.value_Getter_(this);

  @DomName('DOMSettableTokenList.value')
  @DocsEditable()
  void set value(String value) => _blink.BlinkDOMSettableTokenList.instance.value_Setter_(this, value);

  @DomName('DOMSettableTokenList.__getter__')
  @DocsEditable()
  String __getter__(int index) => _blink.BlinkDOMSettableTokenList.instance.$__getter___Callback_1_(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.


@DocsEditable()
@DomName('DOMStringList')
class DomStringList extends NativeFieldWrapperClass2 with ListMixin<String>, ImmutableListMixin<String> implements List<String> {
  // To suppress missing implicit constructor warnings.
  factory DomStringList._() { throw new UnsupportedError("Not supported"); }

  @DomName('DOMStringList.length')
  @DocsEditable()
  int get length => _blink.BlinkDOMStringList.instance.length_Getter_(this);

  String operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return _blink.BlinkDOMStringList.instance.item_Callback_1_(this, index);
  }

  String _nativeIndexedGetter(int index) => _blink.BlinkDOMStringList.instance.item_Callback_1_(this, index);

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


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

  String get first {
    if (this.length > 0) {
      return _nativeIndexedGetter(0);
    }
    throw new StateError("No elements");
  }

  String get last {
    int len = this.length;
    if (len > 0) {
      return _nativeIndexedGetter(len - 1);
    }
    throw new StateError("No elements");
  }

  String get single {
    int len = this.length;
    if (len == 1) {
      return _nativeIndexedGetter(0);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

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

  @DomName('DOMStringList.contains')
  @DocsEditable()
  bool contains(String string) => _blink.BlinkDOMStringList.instance.contains_Callback_1_(this, string);

  @DomName('DOMStringList.item')
  @DocsEditable()
  String item(int index) => _blink.BlinkDOMStringList.instance.item_Callback_1_(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.


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

  bool __delete__(index_OR_name) {
    if ((index_OR_name is int || index_OR_name == null)) {
      return _blink.BlinkDOMStringMap.instance.$__delete___Callback_1_(this, index_OR_name);
    }
    if ((index_OR_name is String || index_OR_name == null)) {
      return _blink.BlinkDOMStringMap.instance.$__delete___Callback_1_(this, index_OR_name);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  String __getter__(index_OR_name) {
    if ((index_OR_name is int || index_OR_name == null)) {
      return _blink.BlinkDOMStringMap.instance.$__getter___Callback_1_(this, index_OR_name);
    }
    if ((index_OR_name is String || index_OR_name == null)) {
      return _blink.BlinkDOMStringMap.instance.$__getter___Callback_1_(this, index_OR_name);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  void __setter__(index_OR_name, String value) {
    if ((value is String || value == null) && (index_OR_name is int || index_OR_name == null)) {
      _blink.BlinkDOMStringMap.instance.$__setter___Callback_2_(this, index_OR_name, value);
      return;
    }
    if ((value is String || value == null) && (index_OR_name is String || index_OR_name == null)) {
      _blink.BlinkDOMStringMap.instance.$__setter___Callback_2_(this, index_OR_name, value);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

  @DomName('DOMTokenList.length')
  @DocsEditable()
  int get length => _blink.BlinkDOMTokenList.instance.length_Getter_(this);

  @DomName('DOMTokenList.add')
  @DocsEditable()
  @Experimental() // untriaged
  void add(String tokens) => _blink.BlinkDOMTokenList.instance.add_Callback_1_(this, tokens);

  @DomName('DOMTokenList.contains')
  @DocsEditable()
  bool contains(String token) => _blink.BlinkDOMTokenList.instance.contains_Callback_1_(this, token);

  @DomName('DOMTokenList.item')
  @DocsEditable()
  String item(int index) => _blink.BlinkDOMTokenList.instance.item_Callback_1_(this, index);

  @DomName('DOMTokenList.remove')
  @DocsEditable()
  @Experimental() // untriaged
  void remove(String tokens) => _blink.BlinkDOMTokenList.instance.remove_Callback_1_(this, tokens);

  bool toggle(String token, [bool force]) {
    if (force != null) {
      return _blink.BlinkDOMTokenList.instance.toggle_Callback_2_(this, token, force);
    }
    return _blink.BlinkDOMTokenList.instance.toggle_Callback_1_(this, token);
  }

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


class _ChildrenElementList extends ListBase<Element>
    implements NodeListWrapper {
  // Raw Element.
  final Element _element;
  final HtmlCollection _childElements;

  _ChildrenElementList._wrap(Element element)
    : _childElements = element._children,
      _element = element;

  bool contains(Object element) => _childElements.contains(element);


  bool get isEmpty {
    return _element._firstElementChild == null;
  }

  int get length {
    return _childElements.length;
  }

  Element operator [](int index) {
    return _childElements[index];
  }

  void operator []=(int index, Element value) {
    _element._replaceChild(value, _childElements[index]);
  }

  void set length(int newLength) {
    // TODO(jacobr): remove children when length is reduced.
    throw new UnsupportedError('Cannot resize element lists');
  }

  Element add(Element value) {
    _element.append(value);
    return value;
  }

  Iterator<Element> get iterator => toList().iterator;

  void addAll(Iterable<Element> iterable) {
    if (iterable is _ChildNodeListLazy) {
      iterable = new List.from(iterable);
    }

    for (Element element in iterable) {
      _element.append(element);
    }
  }

  void sort([int compare(Element a, Element b)]) {
    throw new UnsupportedError('Cannot sort element lists');
  }

  void shuffle([Random random]) {
    throw new UnsupportedError('Cannot shuffle element lists');
  }

  void removeWhere(bool test(Element element)) {
    _filter(test, false);
  }

  void retainWhere(bool test(Element element)) {
    _filter(test, true);
  }

  void _filter(bool test(var element), bool retainMatching) {
    var removed;
    if (retainMatching) {
      removed = _element.children.where((e) => !test(e));
    } else {
      removed = _element.children.where(test);
    }
    for (var e in removed) e.remove();
  }

  void setRange(int start, int end, Iterable<Element> iterable,
                [int skipCount = 0]) {
    throw new UnimplementedError();
  }

  void replaceRange(int start, int end, Iterable<Element> iterable) {
    throw new UnimplementedError();
  }

  void fillRange(int start, int end, [Element fillValue]) {
    throw new UnimplementedError();
  }

  bool remove(Object object) {
    if (object is Element) {
      Element element = object;
      if (identical(element.parentNode, _element)) {
        _element._removeChild(element);
        return true;
      }
    }
    return false;
  }

  void insert(int index, Element element) {
    if (index < 0 || index > length) {
      throw new RangeError.range(index, 0, length);
    }
    if (index == length) {
      _element.append(element);
    } else {
      _element.insertBefore(element, this[index]);
    }
  }

  void setAll(int index, Iterable<Element> iterable) {
    throw new UnimplementedError();
  }

  void clear() {
    _element._clearChildren();
  }

  Element removeAt(int index) {
    final result = this[index];
    if (result != null) {
      _element._removeChild(result);
    }
    return result;
  }

  Element removeLast() {
    final result = this.last;
    if (result != null) {
      _element._removeChild(result);
    }
    return result;
  }

  Element get first {
    Element result = _element._firstElementChild;
    if (result == null) throw new StateError("No elements");
    return result;
  }


  Element get last {
    Element result = _element._lastElementChild;
    if (result == null) throw new StateError("No elements");
    return result;
  }

  Element get single {
    if (length > 1) throw new StateError("More than one element");
    return first;
  }

  List<Node> get rawList => _childElements;
}

/**
 * An immutable list containing HTML elements. This list contains some
 * additional methods when compared to regular lists for ease of CSS
 * manipulation on a group of elements.
 */
abstract class ElementList<T extends Element> extends ListBase<T> {
  /**
   * The union of all CSS classes applied to the elements in this list.
   *
   * This set makes it easy to add, remove or toggle (add if not present, remove
   * if present) the classes applied to a collection of elements.
   *
   *     htmlList.classes.add('selected');
   *     htmlList.classes.toggle('isOnline');
   *     htmlList.classes.remove('selected');
   */
  CssClassSet get classes;

  /** Replace the classes with `value` for every element in this list. */
  set classes(Iterable<String> value);

  /**
   * Access the union of all [CssStyleDeclaration]s that are associated with an
   * [ElementList].
   *
   * Grouping the style objects all together provides easy editing of specific
   * properties of a collection of elements. Setting a specific property value
   * will set that property in all [Element]s in the [ElementList]. Getting a
   * specific property value will return the value of the property of the first
   * element in the [ElementList].
   */
  CssStyleDeclarationBase get style;

  /**
   * Access dimensions and position of the Elements in this list.
   *
   * Setting the height or width properties will set the height or width
   * property for all elements in the list. This returns a rectangle with the
   * dimenions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Getting the height or width returns the height or width of the
   * first Element in this list.
   *
   * Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not.
   */
  @Experimental()
  CssRect get contentEdge;

  /**
   * Access dimensions and position of the first Element's content + padding box
   * in this list.
   *
   * This returns a rectangle with the dimenions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's `innerHeight` value for an element. This
   * is also a rectangle equalling the dimensions of clientHeight and
   * clientWidth.
   */
  @Experimental()
  CssRect get paddingEdge;

  /**
   * Access dimensions and position of the first Element's content + padding +
   * border box in this list.
   *
   * This returns a rectangle with the dimenions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's `outerHeight` value for an element.
   */
  @Experimental()
  CssRect get borderEdge;

  /**
   * Access dimensions and position of the first Element's content + padding +
   * border + margin box in this list.
   *
   * This returns a rectangle with the dimenions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's `outerHeight` value for an element.
   */
  @Experimental()
  CssRect get marginEdge;

  /// Stream of `abort` events handled by this [Element].
  @DomName('Element.onabort')
  @DocsEditable()
  ElementStream<Event> get onAbort;

  /// Stream of `beforecopy` events handled by this [Element].
  @DomName('Element.onbeforecopy')
  @DocsEditable()
  ElementStream<Event> get onBeforeCopy;

  /// Stream of `beforecut` events handled by this [Element].
  @DomName('Element.onbeforecut')
  @DocsEditable()
  ElementStream<Event> get onBeforeCut;

  /// Stream of `beforepaste` events handled by this [Element].
  @DomName('Element.onbeforepaste')
  @DocsEditable()
  ElementStream<Event> get onBeforePaste;

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

  @DomName('Element.oncanplay')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onCanPlay;

  @DomName('Element.oncanplaythrough')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onCanPlayThrough;

  /// Stream of `change` events handled by this [Element].
  @DomName('Element.onchange')
  @DocsEditable()
  ElementStream<Event> get onChange;

  /// Stream of `click` events handled by this [Element].
  @DomName('Element.onclick')
  @DocsEditable()
  ElementStream<MouseEvent> get onClick;

  /// Stream of `contextmenu` events handled by this [Element].
  @DomName('Element.oncontextmenu')
  @DocsEditable()
  ElementStream<MouseEvent> get onContextMenu;

  /// Stream of `copy` events handled by this [Element].
  @DomName('Element.oncopy')
  @DocsEditable()
  ElementStream<Event> get onCopy;

  /// Stream of `cut` events handled by this [Element].
  @DomName('Element.oncut')
  @DocsEditable()
  ElementStream<Event> get onCut;

  /// Stream of `doubleclick` events handled by this [Element].
  @DomName('Element.ondblclick')
  @DocsEditable()
  ElementStream<Event> get onDoubleClick;

  /**
   * A stream of `drag` events fired when this element currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondrag')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrag;

  /**
   * A stream of `dragend` events fired when this element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragend')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnd;

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragenter')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnter;

  /**
   * A stream of `dragleave` events fired when an object being dragged over this
   * element leaves this element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragleave')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragLeave;

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragover')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragOver;

  /**
   * A stream of `dragstart` events fired when this element starts being
   * dragged.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragstart')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragStart;

  /**
   * A stream of `drop` events fired when a dragged object is dropped on this
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondrop')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrop;

  @DomName('Element.ondurationchange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onDurationChange;

  @DomName('Element.onemptied')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEmptied;

  @DomName('Element.onended')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEnded;

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

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

  /// Stream of `input` events handled by this [Element].
  @DomName('Element.oninput')
  @DocsEditable()
  ElementStream<Event> get onInput;

  /// Stream of `invalid` events handled by this [Element].
  @DomName('Element.oninvalid')
  @DocsEditable()
  ElementStream<Event> get onInvalid;

  /// Stream of `keydown` events handled by this [Element].
  @DomName('Element.onkeydown')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyDown;

  /// Stream of `keypress` events handled by this [Element].
  @DomName('Element.onkeypress')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyPress;

  /// Stream of `keyup` events handled by this [Element].
  @DomName('Element.onkeyup')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyUp;

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

  @DomName('Element.onloadeddata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedData;

  @DomName('Element.onloadedmetadata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedMetadata;

  /// Stream of `mousedown` events handled by this [Element].
  @DomName('Element.onmousedown')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseDown;

  /// Stream of `mouseenter` events handled by this [Element].
  @DomName('Element.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseEnter;

  /// Stream of `mouseleave` events handled by this [Element].
  @DomName('Element.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseLeave;

  /// Stream of `mousemove` events handled by this [Element].
  @DomName('Element.onmousemove')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseMove;

  /// Stream of `mouseout` events handled by this [Element].
  @DomName('Element.onmouseout')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOut;

  /// Stream of `mouseover` events handled by this [Element].
  @DomName('Element.onmouseover')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOver;

  /// Stream of `mouseup` events handled by this [Element].
  @DomName('Element.onmouseup')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseUp;

  /// Stream of `mousewheel` events handled by this [Element].
  @DomName('Element.onmousewheel')
  @DocsEditable()
  // http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents
  @Experimental() // non-standard
  ElementStream<WheelEvent> get onMouseWheel;

  /// Stream of `paste` events handled by this [Element].
  @DomName('Element.onpaste')
  @DocsEditable()
  ElementStream<Event> get onPaste;

  @DomName('Element.onpause')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPause;

  @DomName('Element.onplay')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPlay;

  @DomName('Element.onplaying')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPlaying;

  @DomName('Element.onratechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onRateChange;

  /// Stream of `reset` events handled by this [Element].
  @DomName('Element.onreset')
  @DocsEditable()
  ElementStream<Event> get onReset;

  @DomName('Element.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onResize;

  /// Stream of `scroll` events handled by this [Element].
  @DomName('Element.onscroll')
  @DocsEditable()
  ElementStream<Event> get onScroll;

  /// Stream of `search` events handled by this [Element].
  @DomName('Element.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  ElementStream<Event> get onSearch;

  @DomName('Element.onseeked')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeked;

  @DomName('Element.onseeking')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeking;

  /// Stream of `select` events handled by this [Element].
  @DomName('Element.onselect')
  @DocsEditable()
  ElementStream<Event> get onSelect;

  /// Stream of `selectstart` events handled by this [Element].
  @DomName('Element.onselectstart')
  @DocsEditable()
  @Experimental() // nonstandard
  ElementStream<Event> get onSelectStart;

  @DomName('Element.onstalled')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onStalled;

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

  @DomName('Element.onsuspend')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSuspend;

  @DomName('Element.ontimeupdate')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onTimeUpdate;

  /// Stream of `touchcancel` events handled by this [Element].
  @DomName('Element.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchCancel;

  /// Stream of `touchend` events handled by this [Element].
  @DomName('Element.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnd;

  /// Stream of `touchenter` events handled by this [Element].
  @DomName('Element.ontouchenter')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnter;

  /// Stream of `touchleave` events handled by this [Element].
  @DomName('Element.ontouchleave')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchLeave;

  /// Stream of `touchmove` events handled by this [Element].
  @DomName('Element.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchMove;

  /// Stream of `touchstart` events handled by this [Element].
  @DomName('Element.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchStart;

  /// Stream of `transitionend` events handled by this [Element].
  @DomName('Element.ontransitionend')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  ElementStream<TransitionEvent> get onTransitionEnd;

  @DomName('Element.onvolumechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onVolumeChange;

  @DomName('Element.onwaiting')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onWaiting;

  /// Stream of `fullscreenchange` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenchange')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenChange;

  /// Stream of `fullscreenerror` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenError;

}

// Wrapper over an immutable NodeList to make it implement ElementList.
//
// Clients are {`Document`, `DocumentFragment`}.`querySelectorAll` which are
// declared to return `ElementList`.  This provides all the static analysis
// benefit so there is no need for this class have a constrained type parameter.
//
class _FrozenElementList extends ListBase
    implements ElementList, NodeListWrapper {
  final List<Node> _nodeList;

  _FrozenElementList._wrap(this._nodeList);

  int get length => _nodeList.length;

  Element operator [](int index) => _nodeList[index];

  void operator []=(int index, Element value) {
    throw new UnsupportedError('Cannot modify list');
  }

  void set length(int newLength) {
    throw new UnsupportedError('Cannot modify list');
  }

  void sort([Comparator<Element> compare]) {
    throw new UnsupportedError('Cannot sort list');
  }

  void shuffle([Random random]) {
    throw new UnsupportedError('Cannot shuffle list');
  }

  Element get first => _nodeList.first;

  Element get last => _nodeList.last;

  Element get single => _nodeList.single;

  CssClassSet get classes => new _MultiElementCssClassSet(this);

  CssStyleDeclarationBase get style =>
      new _CssStyleDeclarationSet(this);

  void set classes(Iterable<String> value) {
    _nodeList.forEach((e) => e.classes = value);
  }

  CssRect get contentEdge => new _ContentCssListRect(this);

  CssRect get paddingEdge => this.first.paddingEdge;

  CssRect get borderEdge => this.first.borderEdge;

  CssRect get marginEdge => this.first.marginEdge;

  List<Node> get rawList => _nodeList;


  /// Stream of `abort` events handled by this [Element].
  @DomName('Element.onabort')
  @DocsEditable()
  ElementStream<Event> get onAbort => Element.abortEvent._forElementList(this);

  /// Stream of `beforecopy` events handled by this [Element].
  @DomName('Element.onbeforecopy')
  @DocsEditable()
  ElementStream<Event> get onBeforeCopy => Element.beforeCopyEvent._forElementList(this);

  /// Stream of `beforecut` events handled by this [Element].
  @DomName('Element.onbeforecut')
  @DocsEditable()
  ElementStream<Event> get onBeforeCut => Element.beforeCutEvent._forElementList(this);

  /// Stream of `beforepaste` events handled by this [Element].
  @DomName('Element.onbeforepaste')
  @DocsEditable()
  ElementStream<Event> get onBeforePaste => Element.beforePasteEvent._forElementList(this);

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

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

  @DomName('Element.oncanplaythrough')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onCanPlayThrough => Element.canPlayThroughEvent._forElementList(this);

  /// Stream of `change` events handled by this [Element].
  @DomName('Element.onchange')
  @DocsEditable()
  ElementStream<Event> get onChange => Element.changeEvent._forElementList(this);

  /// Stream of `click` events handled by this [Element].
  @DomName('Element.onclick')
  @DocsEditable()
  ElementStream<MouseEvent> get onClick => Element.clickEvent._forElementList(this);

  /// Stream of `contextmenu` events handled by this [Element].
  @DomName('Element.oncontextmenu')
  @DocsEditable()
  ElementStream<MouseEvent> get onContextMenu => Element.contextMenuEvent._forElementList(this);

  /// Stream of `copy` events handled by this [Element].
  @DomName('Element.oncopy')
  @DocsEditable()
  ElementStream<Event> get onCopy => Element.copyEvent._forElementList(this);

  /// Stream of `cut` events handled by this [Element].
  @DomName('Element.oncut')
  @DocsEditable()
  ElementStream<Event> get onCut => Element.cutEvent._forElementList(this);

  /// Stream of `doubleclick` events handled by this [Element].
  @DomName('Element.ondblclick')
  @DocsEditable()
  ElementStream<Event> get onDoubleClick => Element.doubleClickEvent._forElementList(this);

  /**
   * A stream of `drag` events fired when this element currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondrag')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrag => Element.dragEvent._forElementList(this);

  /**
   * A stream of `dragend` events fired when this element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragend')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnd => Element.dragEndEvent._forElementList(this);

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragenter')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnter => Element.dragEnterEvent._forElementList(this);

  /**
   * A stream of `dragleave` events fired when an object being dragged over this
   * element leaves this element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragleave')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragLeave => Element.dragLeaveEvent._forElementList(this);

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragover')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragOver => Element.dragOverEvent._forElementList(this);

  /**
   * A stream of `dragstart` events fired when this element starts being
   * dragged.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragstart')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragStart => Element.dragStartEvent._forElementList(this);

  /**
   * A stream of `drop` events fired when a dragged object is dropped on this
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondrop')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrop => Element.dropEvent._forElementList(this);

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

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

  @DomName('Element.onended')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEnded => Element.endedEvent._forElementList(this);

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

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

  /// Stream of `input` events handled by this [Element].
  @DomName('Element.oninput')
  @DocsEditable()
  ElementStream<Event> get onInput => Element.inputEvent._forElementList(this);

  /// Stream of `invalid` events handled by this [Element].
  @DomName('Element.oninvalid')
  @DocsEditable()
  ElementStream<Event> get onInvalid => Element.invalidEvent._forElementList(this);

  /// Stream of `keydown` events handled by this [Element].
  @DomName('Element.onkeydown')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyDown => Element.keyDownEvent._forElementList(this);

  /// Stream of `keypress` events handled by this [Element].
  @DomName('Element.onkeypress')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyPress => Element.keyPressEvent._forElementList(this);

  /// Stream of `keyup` events handled by this [Element].
  @DomName('Element.onkeyup')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyUp => Element.keyUpEvent._forElementList(this);

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

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

  @DomName('Element.onloadedmetadata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedMetadata => Element.loadedMetadataEvent._forElementList(this);

  /// Stream of `mousedown` events handled by this [Element].
  @DomName('Element.onmousedown')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseDown => Element.mouseDownEvent._forElementList(this);

  /// Stream of `mouseenter` events handled by this [Element].
  @DomName('Element.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseEnter => Element.mouseEnterEvent._forElementList(this);

  /// Stream of `mouseleave` events handled by this [Element].
  @DomName('Element.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseLeave => Element.mouseLeaveEvent._forElementList(this);

  /// Stream of `mousemove` events handled by this [Element].
  @DomName('Element.onmousemove')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseMove => Element.mouseMoveEvent._forElementList(this);

  /// Stream of `mouseout` events handled by this [Element].
  @DomName('Element.onmouseout')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOut => Element.mouseOutEvent._forElementList(this);

  /// Stream of `mouseover` events handled by this [Element].
  @DomName('Element.onmouseover')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOver => Element.mouseOverEvent._forElementList(this);

  /// Stream of `mouseup` events handled by this [Element].
  @DomName('Element.onmouseup')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseUp => Element.mouseUpEvent._forElementList(this);

  /// Stream of `mousewheel` events handled by this [Element].
  @DomName('Element.onmousewheel')
  @DocsEditable()
  // http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents
  @Experimental() // non-standard
  ElementStream<WheelEvent> get onMouseWheel => Element.mouseWheelEvent._forElementList(this);

  /// Stream of `paste` events handled by this [Element].
  @DomName('Element.onpaste')
  @DocsEditable()
  ElementStream<Event> get onPaste => Element.pasteEvent._forElementList(this);

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

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

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

  @DomName('Element.onratechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onRateChange => Element.rateChangeEvent._forElementList(this);

  /// Stream of `reset` events handled by this [Element].
  @DomName('Element.onreset')
  @DocsEditable()
  ElementStream<Event> get onReset => Element.resetEvent._forElementList(this);

  @DomName('Element.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onResize => Element.resizeEvent._forElementList(this);

  /// Stream of `scroll` events handled by this [Element].
  @DomName('Element.onscroll')
  @DocsEditable()
  ElementStream<Event> get onScroll => Element.scrollEvent._forElementList(this);

  /// Stream of `search` events handled by this [Element].
  @DomName('Element.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  ElementStream<Event> get onSearch => Element.searchEvent._forElementList(this);

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

  @DomName('Element.onseeking')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeking => Element.seekingEvent._forElementList(this);

  /// Stream of `select` events handled by this [Element].
  @DomName('Element.onselect')
  @DocsEditable()
  ElementStream<Event> get onSelect => Element.selectEvent._forElementList(this);

  /// Stream of `selectstart` events handled by this [Element].
  @DomName('Element.onselectstart')
  @DocsEditable()
  @Experimental() // nonstandard
  ElementStream<Event> get onSelectStart => Element.selectStartEvent._forElementList(this);

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

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

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

  @DomName('Element.ontimeupdate')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onTimeUpdate => Element.timeUpdateEvent._forElementList(this);

  /// Stream of `touchcancel` events handled by this [Element].
  @DomName('Element.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchCancel => Element.touchCancelEvent._forElementList(this);

  /// Stream of `touchend` events handled by this [Element].
  @DomName('Element.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnd => Element.touchEndEvent._forElementList(this);

  /// Stream of `touchenter` events handled by this [Element].
  @DomName('Element.ontouchenter')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnter => Element.touchEnterEvent._forElementList(this);

  /// Stream of `touchleave` events handled by this [Element].
  @DomName('Element.ontouchleave')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchLeave => Element.touchLeaveEvent._forElementList(this);

  /// Stream of `touchmove` events handled by this [Element].
  @DomName('Element.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchMove => Element.touchMoveEvent._forElementList(this);

  /// Stream of `touchstart` events handled by this [Element].
  @DomName('Element.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchStart => Element.touchStartEvent._forElementList(this);

  /// Stream of `transitionend` events handled by this [Element].
  @DomName('Element.ontransitionend')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  ElementStream<TransitionEvent> get onTransitionEnd => Element.transitionEndEvent._forElementList(this);

  @DomName('Element.onvolumechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onVolumeChange => Element.volumeChangeEvent._forElementList(this);

  @DomName('Element.onwaiting')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onWaiting => Element.waitingEvent._forElementList(this);

  /// Stream of `fullscreenchange` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenchange')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenChange => Element.fullscreenChangeEvent._forElementList(this);

  /// Stream of `fullscreenerror` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenError => Element.fullscreenErrorEvent._forElementList(this);

}

@DocsEditable()
/**
 * An abstract class, which all HTML elements extend.
 */
@DomName('Element')
abstract class Element extends Node implements GlobalEventHandlers, ParentNode, ChildNode {

  /**
   * Creates an HTML element from a valid fragment of HTML.
   *
   *     var element = new Element.html('<div class="foo">content</div>');
   *
   * The HTML fragment should contain only one single root element, any
   * leading or trailing text nodes will be removed.
   *
   * The HTML fragment is parsed as if it occurred within the context of a
   * `<body>` tag, this means that special elements such as `<caption>` which
   * must be parsed within the scope of a `<table>` element will be dropped. Use
   * [createFragment] to parse contextual HTML fragments.
   *
   * Unless a validator is provided this will perform the default validation
   * and remove all scriptable elements and attributes.
   *
   * See also:
   *
   * * [NodeValidator]
   *
   */
  factory Element.html(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    var fragment = document.body.createFragment(html, validator: validator,
        treeSanitizer: treeSanitizer);

    return fragment.nodes.where((e) => e is Element).single;
  }

  /**
   * Custom element creation constructor.
   *
   * This constructor is used by the DOM when a custom element has been
   * created. It can only be invoked by subclasses of Element from
   * that classes created constructor.
   *
   *     class CustomElement extends Element {
   *       factory CustomElement() => new Element.tag('x-custom');
   *
   *       CustomElement.created() : super.created() {
   *          // Perform any element initialization.
   *       }
   *     }
   *     document.registerElement('x-custom', CustomElement);
   */
  Element.created() : super._created() {
    // Validate that this is a custom element & perform any additional
    // initialization.
    _initializeCustomElement(this);
  }

  /**
   * Creates the HTML element specified by the tag name.
   *
   * This is similar to [Document.createElement].
   * [tag] should be a valid HTML tag name. If [tag] is an unknown tag then
   * this will create an [UnknownElement].
   *
   *     var divElement = new Element.tag('div');
   *     print(divElement is DivElement); // 'true'
   *     var myElement = new Element.tag('unknownTag');
   *     print(myElement is UnknownElement); // 'true'
   *
   * For standard elements it is more preferable to use the type constructors:
   *     var element = new DivElement();
   *
   * See also:
   *
   * * [isTagSupported]
   */
  factory Element.tag(String tag, [String typeExtention]) =>
      _ElementFactoryProvider.createElement_tag(tag, typeExtention);

  /// Creates a new `<a>` element.
  ///
  /// This is identical to calling `new Element.tag('a')`.
  factory Element.a() => new Element.tag('a');

  /// Creates a new `<article>` element.
  ///
  /// This is identical to calling `new Element.tag('article')`.
  factory Element.article() => new Element.tag('article');

  /// Creates a new `<aside>` element.
  ///
  /// This is identical to calling `new Element.tag('aside')`.
  factory Element.aside() => new Element.tag('aside');

  /// Creates a new `<audio>` element.
  ///
  /// This is identical to calling `new Element.tag('audio')`.
  factory Element.audio() => new Element.tag('audio');

  /// Creates a new `<br>` element.
  ///
  /// This is identical to calling `new Element.tag('br')`.
  factory Element.br() => new Element.tag('br');

  /// Creates a new `<canvas>` element.
  ///
  /// This is identical to calling `new Element.tag('canvas')`.
  factory Element.canvas() => new Element.tag('canvas');

  /// Creates a new `<div>` element.
  ///
  /// This is identical to calling `new Element.tag('div')`.
  factory Element.div() => new Element.tag('div');

  /// Creates a new `<footer>` element.
  ///
  /// This is identical to calling `new Element.tag('footer')`.
  factory Element.footer() => new Element.tag('footer');

  /// Creates a new `<header>` element.
  ///
  /// This is identical to calling `new Element.tag('header')`.
  factory Element.header() => new Element.tag('header');

  /// Creates a new `<hr>` element.
  ///
  /// This is identical to calling `new Element.tag('hr')`.
  factory Element.hr() => new Element.tag('hr');

  /// Creates a new `<iframe>` element.
  ///
  /// This is identical to calling `new Element.tag('iframe')`.
  factory Element.iframe() => new Element.tag('iframe');

  /// Creates a new `<img>` element.
  ///
  /// This is identical to calling `new Element.tag('img')`.
  factory Element.img() => new Element.tag('img');

  /// Creates a new `<li>` element.
  ///
  /// This is identical to calling `new Element.tag('li')`.
  factory Element.li() => new Element.tag('li');

  /// Creates a new `<nav>` element.
  ///
  /// This is identical to calling `new Element.tag('nav')`.
  factory Element.nav() => new Element.tag('nav');

  /// Creates a new `<ol>` element.
  ///
  /// This is identical to calling `new Element.tag('ol')`.
  factory Element.ol() => new Element.tag('ol');

  /// Creates a new `<option>` element.
  ///
  /// This is identical to calling `new Element.tag('option')`.
  factory Element.option() => new Element.tag('option');

  /// Creates a new `<p>` element.
  ///
  /// This is identical to calling `new Element.tag('p')`.
  factory Element.p() => new Element.tag('p');

  /// Creates a new `<pre>` element.
  ///
  /// This is identical to calling `new Element.tag('pre')`.
  factory Element.pre() => new Element.tag('pre');

  /// Creates a new `<section>` element.
  ///
  /// This is identical to calling `new Element.tag('section')`.
  factory Element.section() => new Element.tag('section');

  /// Creates a new `<select>` element.
  ///
  /// This is identical to calling `new Element.tag('select')`.
  factory Element.select() => new Element.tag('select');

  /// Creates a new `<span>` element.
  ///
  /// This is identical to calling `new Element.tag('span')`.
  factory Element.span() => new Element.tag('span');

  /// Creates a new `<svg>` element.
  ///
  /// This is identical to calling `new Element.tag('svg')`.
  factory Element.svg() => new Element.tag('svg');

  /// Creates a new `<table>` element.
  ///
  /// This is identical to calling `new Element.tag('table')`.
  factory Element.table() => new Element.tag('table');

  /// Creates a new `<td>` element.
  ///
  /// This is identical to calling `new Element.tag('td')`.
  factory Element.td() => new Element.tag('td');

  /// Creates a new `<textarea>` element.
  ///
  /// This is identical to calling `new Element.tag('textarea')`.
  factory Element.textarea() => new Element.tag('textarea');

  /// Creates a new `<th>` element.
  ///
  /// This is identical to calling `new Element.tag('th')`.
  factory Element.th() => new Element.tag('th');

  /// Creates a new `<tr>` element.
  ///
  /// This is identical to calling `new Element.tag('tr')`.
  factory Element.tr() => new Element.tag('tr');

  /// Creates a new `<ul>` element.
  ///
  /// This is identical to calling `new Element.tag('ul')`.
  factory Element.ul() => new Element.tag('ul');

  /// Creates a new `<video>` element.
  ///
  /// This is identical to calling `new Element.tag('video')`.
  factory Element.video() => new Element.tag('video');

  /**
   * All attributes on this element.
   *
   * Any modifications to the attribute map will automatically be applied to
   * this element.
   *
   * This only includes attributes which are not in a namespace
   * (such as 'xlink:href'), additional attributes can be accessed via
   * [getNamespacedAttributes].
   */
  Map<String, String> get attributes => new _ElementAttributeMap(this);

  void set attributes(Map<String, String> value) {
    Map<String, String> attributes = this.attributes;
    attributes.clear();
    for (String key in value.keys) {
      attributes[key] = value[key];
    }
  }

  /**
   * List of the direct children of this element.
   *
   * This collection can be used to add and remove elements from the document.
   *
   *     var item = new DivElement();
   *     item.text = 'Something';
   *     document.body.children.add(item) // Item is now displayed on the page.
   *     for (var element in document.body.children) {
   *       element.style.background = 'red'; // Turns every child of body red.
   *     }
   */
  List<Element> get children => new _ChildrenElementList._wrap(this);

  void set children(List<Element> value) {
    // Copy list first since we don't want liveness during iteration.
    List copy = new List.from(value);
    var children = this.children;
    children.clear();
    children.addAll(copy);
  }

  /**
   * Finds all descendent elements of this element that match the specified
   * group of selectors.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var items = element.querySelectorAll('.itemClassName');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  @DomName('Element.querySelectorAll')
  ElementList querySelectorAll(String selectors) =>
    new _FrozenElementList._wrap(_querySelectorAll(selectors));

  /**
   * Alias for [querySelector]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @DomName('Element.querySelector')
  @Experimental()
  Element query(String relativeSelectors) => querySelector(relativeSelectors);

  /**
   * Alias for [querySelectorAll]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @DomName('Element.querySelectorAll')
  @Experimental()
  ElementList queryAll(String relativeSelectors) =>
      querySelectorAll(relativeSelectors);

  /**
   * The set of CSS classes applied to this element.
   *
   * This set makes it easy to add, remove or toggle the classes applied to
   * this element.
   *
   *     element.classes.add('selected');
   *     element.classes.toggle('isOnline');
   *     element.classes.remove('selected');
   */
  CssClassSet get classes => new _ElementCssClassSet(this);

  void set classes(Iterable<String> value) {
    CssClassSet classSet = classes;
    classSet.clear();
    classSet.addAll(value);
  }

  /**
   * Allows access to all custom data attributes (data-*) set on this element.
   *
   * The keys for the map must follow these rules:
   *
   * * The name must not begin with 'xml'.
   * * The name cannot contain a semi-colon (';').
   * * The name cannot contain any capital letters.
   *
   * Any keys from markup will be converted to camel-cased keys in the map.
   *
   * For example, HTML specified as:
   *
   *     <div data-my-random-value='value'></div>
   *
   * Would be accessed in Dart as:
   *
   *     var value = element.dataset['myRandomValue'];
   *
   * See also:
   *
   * * [Custom data attributes](http://www.w3.org/TR/html5/global-attributes.html#custom-data-attribute)
   */
  Map<String, String> get dataset =>
    new _DataAttributeMap(attributes);

  void set dataset(Map<String, String> value) {
    final data = this.dataset;
    data.clear();
    for (String key in value.keys) {
      data[key] = value[key];
    }
  }

  /**
   * Gets a map for manipulating the attributes of a particular namespace.
   *
   * This is primarily useful for SVG attributes such as xref:link.
   */
  Map<String, String> getNamespacedAttributes(String namespace) {
    return new _NamespacedAttributeMap(this, namespace);
  }

  /**
   * The set of all CSS values applied to this element, including inherited
   * and default values.
   *
   * The computedStyle contains values that are inherited from other
   * sources, such as parent elements or stylesheets. This differs from the
   * [style] property, which contains only the values specified directly on this
   * element.
   *
   * PseudoElement can be values such as `::after`, `::before`, `::marker`,
   * `::line-marker`.
   *
   * See also:
   *
   * * [CSS Inheritance and Cascade](http://docs.webplatform.org/wiki/tutorials/inheritance_and_cascade)
   * * [Pseudo-elements](http://docs.webplatform.org/wiki/css/selectors/pseudo-elements)
   */
  CssStyleDeclaration getComputedStyle([String pseudoElement]) {
    if (pseudoElement == null) {
      pseudoElement = '';
    }
    // TODO(jacobr): last param should be null, see b/5045788
    return window._getComputedStyle(this, pseudoElement);
  }

  /**
   * Gets the position of this element relative to the client area of the page.
   */
  Rectangle get client => new Rectangle(clientLeft, clientTop, clientWidth,
      clientHeight);

  /**
   * Gets the offset of this element relative to its offsetParent.
   */
  Rectangle get offset => new Rectangle(offsetLeft, offsetTop, offsetWidth,
      offsetHeight);

  /**
   * Adds the specified text after the last child of this element.
   */
  void appendText(String text) {
    this.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) {
    this.insertAdjacentHtml('beforeend', text);
  }

  /**
   * Checks to see if the tag name is supported by the current platform.
   *
   * The tag should be a valid HTML tag name.
   */
  static bool isTagSupported(String tag) {
    var e = _ElementFactoryProvider.createElement_tag(tag, null);
    return e is Element && !(e is UnknownElement);
  }

  /**
   * Called by the DOM when this element has been inserted into the live
   * document.
   *
   * More information can be found in the
   * [Custom Elements](http://w3c.github.io/webcomponents/spec/custom/#dfn-attached-callback)
   * draft specification.
   */
  @Experimental()
  void attached() {
    // For the deprecation period, call the old callback.
    enteredView();
  }

  /**
   * Called by the DOM when this element has been removed from the live
   * document.
   *
   * More information can be found in the
   * [Custom Elements](http://w3c.github.io/webcomponents/spec/custom/#dfn-detached-callback)
   * draft specification.
   */
  @Experimental()
  void detached() {
    // For the deprecation period, call the old callback.
    leftView();
  }

  /** *Deprecated*: override [attached] instead. */
  @Experimental()
  @deprecated
  void enteredView() {}

  /** *Deprecated*: override [detached] instead. */
  @Experimental()
  @deprecated
  void leftView() {}

  /**
   * Called by the DOM whenever an attribute on this has been changed.
   */
  void attributeChanged(String name, String oldValue, String newValue) {}

  // Hooks to support custom WebComponents.

  Element _xtag;

  /**
   * Experimental support for [web components][wc]. This field stores a
   * reference to the component implementation. It was inspired by Mozilla's
   * [x-tags][] project. Please note: in the future it may be possible to
   * `extend Element` from your class, in which case this field will be
   * deprecated.
   *
   * If xtag has not been set, it will simply return `this` [Element].
   *
   * [wc]: http://dvcs.w3.org/hg/webcomponents/raw-file/tip/explainer/index.html
   * [x-tags]: http://x-tags.org/
   */
  // Note: return type is `dynamic` for convenience to suppress warnings when
  // members of the component are used. The actual type is a subtype of Element.
  get xtag => _xtag != null ? _xtag : this;

  void set xtag(Element value) {
    _xtag = value;
  }

  @DomName('Element.localName')
  @DocsEditable()
  String get localName => _localName;

  /**
   * A URI that identifies the XML namespace of this element.
   *
   * `null` if no namespace URI is specified.
   *
   * ## Other resources
   *
   * * [Node.namespaceURI]
   * (http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-NodeNSname) from W3C.
   */
  @DomName('Element.namespaceUri')
  String get namespaceUri => _namespaceUri;

  /**
   * The string representation of this element.
   *
   * This is equivalent to reading the [localName] property.
   */
  String toString() => localName;

  /**
   * Scrolls this element into view.
   *
   * Only one of of the alignment options may be specified at a time.
   *
   * If no options are specified then this will attempt to scroll the minimum
   * amount needed to bring the element into view.
   *
   * Note that alignCenter is currently only supported on WebKit platforms. If
   * alignCenter is specified but not supported then this will fall back to
   * alignTop.
   *
   * See also:
   *
   * * [scrollIntoView](http://docs.webplatform.org/wiki/dom/methods/scrollIntoView)
   * * [scrollIntoViewIfNeeded](http://docs.webplatform.org/wiki/dom/methods/scrollIntoViewIfNeeded)
   */
  void scrollIntoView([ScrollAlignment alignment]) {
    var hasScrollIntoViewIfNeeded = true;
    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();
    }
  }


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


  /**
   * Access this element's content position.
   *
   * This returns a rectangle with the dimenions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not.
   *
   * _Important_ _note_: use of this method _will_ perform CSS calculations that
   * can trigger a browser reflow. Therefore, use of this property _during_ an
   * animation frame is discouraged. See also:
   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
   */
  @Experimental()
  CssRect get contentEdge => new _ContentCssRect(this);

  /**
   * Access the dimensions and position of this element's content + padding box.
   *
   * This returns a rectangle with the dimenions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's
   * [innerHeight](http://api.jquery.com/innerHeight/) value for an element.
   * This is also a rectangle equalling the dimensions of clientHeight and
   * clientWidth.
   *
   * _Important_ _note_: use of this method _will_ perform CSS calculations that
   * can trigger a browser reflow. Therefore, use of this property _during_ an
   * animation frame is discouraged. See also:
   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
   */
  @Experimental()
  CssRect get paddingEdge => new _PaddingCssRect(this);

  /**
   * Access the dimensions and position of this element's content + padding +
   * border box.
   *
   * This returns a rectangle with the dimenions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's
   * [outerHeight](http://api.jquery.com/outerHeight/) value for an element.
   *
   * _Important_ _note_: use of this method _will_ perform CSS calculations that
   * can trigger a browser reflow. Therefore, use of this property _during_ an
   * animation frame is discouraged. See also:
   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
   */
  @Experimental()
  CssRect get borderEdge => new _BorderCssRect(this);

  /**
   * Access the dimensions and position of this element's content + padding +
   * border + margin box.
   *
   * This returns a rectangle with the dimenions actually available for content
   * in this element, in pixels, regardless of this element's box-sizing
   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
   * will return the same numerical height if the element is hidden or not. This
   * can be used to retrieve jQuery's
   * [outerHeight](http://api.jquery.com/outerHeight/) value for an element.
   *
   * _Important_ _note_: use of this method will perform CSS calculations that
   * can trigger a browser reflow. Therefore, use of this property _during_ an
   * animation frame is discouraged. See also:
   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
   */
  @Experimental()
  CssRect get marginEdge => new _MarginCssRect(this);

  /**
   * Provides the coordinates of the element relative to the top of the
   * document.
   *
   * This method is the Dart equivalent to jQuery's
   * [offset](http://api.jquery.com/offset/) method.
   */
  @Experimental()
  Point get documentOffset => offsetTo(document.documentElement);

  /**
   * Provides the offset of this element's [borderEdge] relative to the
   * specified [parent].
   *
   * This is the Dart equivalent of jQuery's
   * [position](http://api.jquery.com/position/) method. Unlike jQuery's
   * position, however, [parent] can be any parent element of `this`,
   * rather than only `this`'s immediate [offsetParent]. If the specified
   * element is _not_ an offset parent or transitive offset parent to this
   * element, an [ArgumentError] is thrown.
   */
  @Experimental()
  Point offsetTo(Element parent) {
    return Element._offsetToHelper(this, parent);
  }

  static Point _offsetToHelper(Element current, Element parent) {
    // We're hopping from _offsetParent_ to offsetParent (not just parent), so
    // offsetParent, "tops out" at BODY. But people could conceivably pass in
    // the document.documentElement and I want it to return an absolute offset,
    // so we have the special case checking for HTML.
    bool foundAsParent = identical(current, parent) || parent.tagName == 'HTML';
    if (current == null || identical(current, parent)) {
      if (foundAsParent) return new Point(0, 0);
      throw new ArgumentError("Specified element is not a transitive offset "
          "parent of this element.");
    }
    Element parentOffset = current.offsetParent;
    Point p = Element._offsetToHelper(parentOffset, parent);
    return new Point(p.x + current.offsetLeft, p.y + current.offsetTop);
  }

  static HtmlDocument _parseDocument;
  static Range _parseRange;
  static NodeValidatorBuilder _defaultValidator;
  static _ValidatingTreeSanitizer _defaultSanitizer;

  /**
   * Create a DocumentFragment from the HTML fragment and ensure that it follows
   * the sanitization rules specified by the validator or treeSanitizer.
   *
   * If the default validation behavior is too restrictive then a new
   * NodeValidator should be created, either extending or wrapping a default
   * validator and overriding the validation APIs.
   *
   * The treeSanitizer is used to walk the generated node tree and sanitize it.
   * A custom treeSanitizer can also be provided to perform special validation
   * rules but since the API is more complex to implement this is discouraged.
   *
   * The returned tree is guaranteed to only contain nodes and attributes which
   * are allowed by the provided validator.
   *
   * See also:
   *
   * * [NodeValidator]
   * * [NodeTreeSanitizer]
   */
  DocumentFragment createFragment(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    if (treeSanitizer == null) {
      if (validator == null) {
        if (_defaultValidator == null) {
          _defaultValidator = new NodeValidatorBuilder.common();
        }
        validator = _defaultValidator;
      }
      if (_defaultSanitizer == null) {
        _defaultSanitizer = new _ValidatingTreeSanitizer(validator);
      } else {
        _defaultSanitizer.validator = validator;
      }
      treeSanitizer = _defaultSanitizer;
    } else if (validator != null) {
      throw new ArgumentError(
          'validator can only be passed if treeSanitizer is null');
    }

    if (_parseDocument == null) {
      _parseDocument = document.implementation.createHtmlDocument('');
      _parseRange = _parseDocument.createRange();

      // Workaround for Chrome bug 229142- URIs are not resolved in new doc.
      var base = _parseDocument.createElement('base');
      base.href = document.baseUri;
      _parseDocument.head.append(base);
    }
    var contextElement;
    if (this is BodyElement) {
      contextElement = _parseDocument.body;
    } else {
      contextElement = _parseDocument.createElement(tagName);
      _parseDocument.body.append(contextElement);
    }
    var fragment;
    if (Range.supportsCreateContextualFragment) {
      _parseRange.selectNodeContents(contextElement);
      fragment = _parseRange.createContextualFragment(html);
    } else {
      contextElement._innerHtml = html;

      fragment = _parseDocument.createDocumentFragment();
      while (contextElement.firstChild != null) {
        fragment.append(contextElement.firstChild);
      }
    }
    if (contextElement != _parseDocument.body) {
      contextElement.remove();
    }

    treeSanitizer.sanitizeTree(fragment);
    // Copy the fragment over to the main document (fix for 14184)
    document.adoptNode(fragment);

    return fragment;
  }

  /**
   * Parses the HTML fragment and sets it as the contents of this element.
   *
   * This uses the default sanitization behavior to sanitize the HTML fragment,
   * use [setInnerHtml] to override the default behavior.
   */
  void set innerHtml(String html) {
    this.setInnerHtml(html);
  }

  /**
   * Parses the HTML fragment and sets it as the contents of this element.
   * This ensures that the generated content follows the sanitization rules
   * specified by the validator or treeSanitizer.
   *
   * If the default validation behavior is too restrictive then a new
   * NodeValidator should be created, either extending or wrapping a default
   * validator and overriding the validation APIs.
   *
   * The treeSanitizer is used to walk the generated node tree and sanitize it.
   * A custom treeSanitizer can also be provided to perform special validation
   * rules but since the API is more complex to implement this is discouraged.
   *
   * The resulting tree is guaranteed to only contain nodes and attributes which
   * are allowed by the provided validator.
   *
   * See also:
   *
   * * [NodeValidator]
   * * [NodeTreeSanitizer]
   */
  void setInnerHtml(String html,
    {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    text = null;
    append(createFragment(
        html, validator: validator, treeSanitizer: treeSanitizer));
  }
  String get innerHtml => _innerHtml;

  /**
   * This is an ease-of-use accessor for event streams which should only be
   * used when an explicit accessor is not available.
   */
  ElementEvents get on => new ElementEvents(this);

  @DomName('Element.offsetHeight')
  @DocsEditable()
  int get offsetHeight => _blink.BlinkElement.offsetHeight_Getter(this).round();

  @DomName('Element.offsetLeft')
  @DocsEditable()
  int get offsetLeft => _blink.BlinkElement.offsetLeft_Getter(this).round();

  @DomName('Element.offsetTop')
  @DocsEditable()
  int get offsetTop => _blink.BlinkElement.offsetTop_Getter(this).round();

  @DomName('Element.offsetWidth')
  @DocsEditable()
  int get offsetWidth => _blink.BlinkElement.offsetWidth_Getter(this).round();

  @DomName('Element.clientHeight')
  @DocsEditable()
  int get clientHeight => _blink.BlinkElement.clientHeight_Getter(this).round();

  @DomName('Element.clientLeft')
  @DocsEditable()
  int get clientLeft => _blink.BlinkElement.clientLeft_Getter(this).round();

  @DomName('Element.clientTop')
  @DocsEditable()
  int get clientTop => _blink.BlinkElement.clientTop_Getter(this).round();

  @DomName('Element.clientWidth')
  @DocsEditable()
  int get clientWidth => _blink.BlinkElement.clientWidth_Getter(this).round();

  @DomName('Element.scrollHeight')
  @DocsEditable()
  int get scrollHeight => _blink.BlinkElement.scrollHeight_Getter(this).round();

  @DomName('Element.scrollLeft')
  @DocsEditable()
  int get scrollLeft => _blink.BlinkElement.scrollLeft_Getter(this).round();

  @DomName('Element.scrollLeft')
  @DocsEditable()
  void set scrollLeft(int value) => _blink.BlinkElement.scrollLeft_Setter(this, value.round());

  @DomName('Element.scrollTop')
  @DocsEditable()
  int get scrollTop => _blink.BlinkElement.scrollTop_Getter(this).round();

  @DomName('Element.scrollTop')
  @DocsEditable()
  void set scrollTop(int value) => _blink.BlinkElement.scrollTop_Setter(this, value.round());

  @DomName('Element.scrollWidth')
  @DocsEditable()
  int get scrollWidth => _blink.BlinkElement.scrollWidth_Getter(this).round();

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

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

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

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

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

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

  @DomName('Element.canplayEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> canPlayEvent = const EventStreamProvider<Event>('canplay');

  @DomName('Element.canplaythroughEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> canPlayThroughEvent = const EventStreamProvider<Event>('canplaythrough');

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

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

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

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

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

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

  /**
   * A stream of `drag` events fired when an element is currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dragEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragEvent = const EventStreamProvider<MouseEvent>('drag');

  /**
   * A stream of `dragend` events fired when an element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dragendEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragEndEvent = const EventStreamProvider<MouseEvent>('dragend');

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over an element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dragenterEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragEnterEvent = const EventStreamProvider<MouseEvent>('dragenter');

  /**
   * A stream of `dragleave` events fired when an object being dragged over an
   * element leaves the element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dragleaveEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragLeaveEvent = const EventStreamProvider<MouseEvent>('dragleave');

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over an element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dragoverEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragOverEvent = const EventStreamProvider<MouseEvent>('dragover');

  /**
   * A stream of `dragstart` events for a dragged element whose drag has begun.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dragstartEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragStartEvent = const EventStreamProvider<MouseEvent>('dragstart');

  /**
   * A stream of `drop` events fired when a dragged object is dropped on an
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dropEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dropEvent = const EventStreamProvider<MouseEvent>('drop');

  @DomName('Element.durationchangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> durationChangeEvent = const EventStreamProvider<Event>('durationchange');

  @DomName('Element.emptiedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> emptiedEvent = const EventStreamProvider<Event>('emptied');

  @DomName('Element.endedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');

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

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

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

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

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

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

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

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

  @DomName('Element.loadeddataEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadedDataEvent = const EventStreamProvider<Event>('loadeddata');

  @DomName('Element.loadedmetadataEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadedMetadataEvent = const EventStreamProvider<Event>('loadedmetadata');

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

  /**
   * Static factory designed to expose `mouseenter` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mouseenterEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseEnterEvent = const EventStreamProvider<MouseEvent>('mouseenter');

  /**
   * Static factory designed to expose `mouseleave` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mouseleaveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseLeaveEvent = const EventStreamProvider<MouseEvent>('mouseleave');

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

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

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

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

  @DomName('Element.mousewheelEvent')
  @DocsEditable()
  // http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents
  @Experimental() // non-standard
  static const EventStreamProvider<WheelEvent> mouseWheelEvent = const EventStreamProvider<WheelEvent>('mousewheel');

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

  @DomName('Element.pauseEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> pauseEvent = const EventStreamProvider<Event>('pause');

  @DomName('Element.playEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> playEvent = const EventStreamProvider<Event>('play');

  @DomName('Element.playingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> playingEvent = const EventStreamProvider<Event>('playing');

  @DomName('Element.ratechangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> rateChangeEvent = const EventStreamProvider<Event>('ratechange');

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

  @DomName('Element.resizeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> resizeEvent = const EventStreamProvider<Event>('resize');

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

  /**
   * Static factory designed to expose `search` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.searchEvent')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  static const EventStreamProvider<Event> searchEvent = const EventStreamProvider<Event>('search');

  @DomName('Element.seekedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> seekedEvent = const EventStreamProvider<Event>('seeked');

  @DomName('Element.seekingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> seekingEvent = const EventStreamProvider<Event>('seeking');

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

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

  @DomName('Element.stalledEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> stalledEvent = const EventStreamProvider<Event>('stalled');

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

  @DomName('Element.suspendEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> suspendEvent = const EventStreamProvider<Event>('suspend');

  @DomName('Element.timeupdateEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> timeUpdateEvent = const EventStreamProvider<Event>('timeupdate');

  /**
   * Static factory designed to expose `touchcancel` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchcancelEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchCancelEvent = const EventStreamProvider<TouchEvent>('touchcancel');

  /**
   * Static factory designed to expose `touchend` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchendEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchEndEvent = const EventStreamProvider<TouchEvent>('touchend');

  /**
   * Static factory designed to expose `touchenter` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchenterEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchEnterEvent = const EventStreamProvider<TouchEvent>('touchenter');

  /**
   * Static factory designed to expose `touchleave` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchleaveEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchLeaveEvent = const EventStreamProvider<TouchEvent>('touchleave');

  /**
   * Static factory designed to expose `touchmove` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchmoveEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchMoveEvent = const EventStreamProvider<TouchEvent>('touchmove');

  /**
   * Static factory designed to expose `touchstart` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchstartEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchStartEvent = const EventStreamProvider<TouchEvent>('touchstart');

  @DomName('Element.transitionendEvent')
  @DocsEditable()
  static const EventStreamProvider<TransitionEvent> transitionEndEvent = const EventStreamProvider<TransitionEvent>('transitionend');

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

  String contentEditable;

  String dir;

  bool draggable;

  bool hidden;

  bool get isContentEditable;

  String lang;

  bool spellcheck;

  int tabIndex;

  String title;

  bool translate;

  String dropzone;

  void click();

  @DomName('Element.attributes')
  @DocsEditable()
  _NamedNodeMap get _attributes => _blink.BlinkElement.instance.attributes_Getter_(this);

  @DomName('Element.className')
  @DocsEditable()
  String get className => _blink.BlinkElement.instance.className_Getter_(this);

  @DomName('Element.className')
  @DocsEditable()
  void set className(String value) => _blink.BlinkElement.instance.className_Setter_(this, value);

  @DomName('Element.clientHeight')
  @DocsEditable()
  int get _clientHeight => _blink.BlinkElement.instance.clientHeight_Getter_(this);

  @DomName('Element.clientLeft')
  @DocsEditable()
  int get _clientLeft => _blink.BlinkElement.instance.clientLeft_Getter_(this);

  @DomName('Element.clientTop')
  @DocsEditable()
  int get _clientTop => _blink.BlinkElement.instance.clientTop_Getter_(this);

  @DomName('Element.clientWidth')
  @DocsEditable()
  int get _clientWidth => _blink.BlinkElement.instance.clientWidth_Getter_(this);

  @DomName('Element.id')
  @DocsEditable()
  String get id => _blink.BlinkElement.instance.id_Getter_(this);

  @DomName('Element.id')
  @DocsEditable()
  void set id(String value) => _blink.BlinkElement.instance.id_Setter_(this, value);

  @DomName('Element.innerHTML')
  @DocsEditable()
  String get _innerHtml => _blink.BlinkElement.instance.innerHTML_Getter_(this);

  @DomName('Element.innerHTML')
  @DocsEditable()
  void set _innerHtml(String value) => _blink.BlinkElement.instance.innerHTML_Setter_(this, value);

  @DomName('Element.localName')
  @DocsEditable()
  @Experimental() // untriaged
  String get _localName => _blink.BlinkElement.instance.localName_Getter_(this);

  @DomName('Element.namespaceURI')
  @DocsEditable()
  @Experimental() // untriaged
  String get _namespaceUri => _blink.BlinkElement.instance.namespaceURI_Getter_(this);

  @DomName('Element.offsetHeight')
  @DocsEditable()
  int get _offsetHeight => _blink.BlinkElement.instance.offsetHeight_Getter_(this);

  @DomName('Element.offsetLeft')
  @DocsEditable()
  int get _offsetLeft => _blink.BlinkElement.instance.offsetLeft_Getter_(this);

  @DomName('Element.offsetParent')
  @DocsEditable()
  Element get offsetParent => _blink.BlinkElement.instance.offsetParent_Getter_(this);

  @DomName('Element.offsetTop')
  @DocsEditable()
  int get _offsetTop => _blink.BlinkElement.instance.offsetTop_Getter_(this);

  @DomName('Element.offsetWidth')
  @DocsEditable()
  int get _offsetWidth => _blink.BlinkElement.instance.offsetWidth_Getter_(this);

  @DomName('Element.outerHTML')
  @DocsEditable()
  String get outerHtml => _blink.BlinkElement.instance.outerHTML_Getter_(this);

  @DomName('Element.scrollHeight')
  @DocsEditable()
  int get _scrollHeight => _blink.BlinkElement.instance.scrollHeight_Getter_(this);

  @DomName('Element.scrollLeft')
  @DocsEditable()
  int get _scrollLeft => _blink.BlinkElement.instance.scrollLeft_Getter_(this);

  @DomName('Element.scrollLeft')
  @DocsEditable()
  void set _scrollLeft(int value) => _blink.BlinkElement.instance.scrollLeft_Setter_(this, value);

  @DomName('Element.scrollTop')
  @DocsEditable()
  int get _scrollTop => _blink.BlinkElement.instance.scrollTop_Getter_(this);

  @DomName('Element.scrollTop')
  @DocsEditable()
  void set _scrollTop(int value) => _blink.BlinkElement.instance.scrollTop_Setter_(this, value);

  @DomName('Element.scrollWidth')
  @DocsEditable()
  int get _scrollWidth => _blink.BlinkElement.instance.scrollWidth_Getter_(this);

  @DomName('Element.shadowRoot')
  @DocsEditable()
  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#api-shadow-aware-create-shadow-root
  @Experimental()
  ShadowRoot get shadowRoot => _blink.BlinkElement.instance.shadowRoot_Getter_(this);

  @DomName('Element.style')
  @DocsEditable()
  CssStyleDeclaration get style => _blink.BlinkElement.instance.style_Getter_(this);

  @DomName('Element.tagName')
  @DocsEditable()
  String get tagName => _blink.BlinkElement.instance.tagName_Getter_(this);

  @DomName('Element.animate')
  @DocsEditable()
  @Experimental() // untriaged
  AnimationPlayer animate(Object effect, [Object timing]) => _blink.BlinkElement.instance.animate_Callback_2_(this, effect, timing);

  @DomName('Element.blur')
  @DocsEditable()
  void blur() => _blink.BlinkElement.instance.blur_Callback_0_(this);

  @DomName('Element.createShadowRoot')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME, '25')
  @Experimental()
  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#api-shadow-aware-create-shadow-root
  ShadowRoot createShadowRoot() => _blink.BlinkElement.instance.createShadowRoot_Callback_0_(this);

  @DomName('Element.focus')
  @DocsEditable()
  void focus() => _blink.BlinkElement.instance.focus_Callback_0_(this);

  @DomName('Element.getAnimationPlayers')
  @DocsEditable()
  @Experimental() // untriaged
  List<AnimationPlayer> getAnimationPlayers() => _blink.BlinkElement.instance.getAnimationPlayers_Callback_0_(this);

  @DomName('Element.getAttribute')
  @DocsEditable()
  @Experimental() // untriaged
  String getAttribute(String name) => _blink.BlinkElement.instance.getAttribute_Callback_1_(this, name);

  @DomName('Element.getAttributeNS')
  @DocsEditable()
  @Experimental() // untriaged
  String getAttributeNS(String namespaceURI, String localName) => _blink.BlinkElement.instance.getAttributeNS_Callback_2_(this, namespaceURI, localName);

  /**
   * Returns the smallest bounding rectangle that encompasses this element's
   * padding, scrollbar, and border.
   *
   * ## Other resources
   *
   * * [Element.getBoundingClientRect]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect)
   * from MDN.
   * * [The getBoundingClientRect() method]
   * (http://www.w3.org/TR/cssom-view/#the-getclientrects-and-getboundingclientrect-methods)
   * from W3C.
   */
  @DomName('Element.getBoundingClientRect')
  @DocsEditable()
  Rectangle getBoundingClientRect() => _blink.BlinkElement.instance.getBoundingClientRect_Callback_0_(this);

  /**
   * 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()
  List<Rectangle> getClientRects() => _blink.BlinkElement.instance.getClientRects_Callback_0_(this);

  /**
   * 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
  List<Node> getDestinationInsertionPoints() => _blink.BlinkElement.instance.getDestinationInsertionPoints_Callback_0_(this);

  /**
   * 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()
  List<Node> getElementsByClassName(String classNames) => _blink.BlinkElement.instance.getElementsByClassName_Callback_1_(this, classNames);

  @DomName('Element.getElementsByTagName')
  @DocsEditable()
  List<Node> _getElementsByTagName(String name) => _blink.BlinkElement.instance.getElementsByTagName_Callback_1_(this, name);

  @DomName('Element.hasAttribute')
  @DocsEditable()
  bool _hasAttribute(String name) => _blink.BlinkElement.instance.hasAttribute_Callback_1_(this, name);

  @DomName('Element.hasAttributeNS')
  @DocsEditable()
  bool _hasAttributeNS(String namespaceURI, String localName) => _blink.BlinkElement.instance.hasAttributeNS_Callback_2_(this, namespaceURI, localName);

  @DomName('Element.insertAdjacentElement')
  @DocsEditable()
  @Experimental() // untriaged
  Element insertAdjacentElement(String where, Element element) => _blink.BlinkElement.instance.insertAdjacentElement_Callback_2_(this, where, element);

  @DomName('Element.insertAdjacentHTML')
  @DocsEditable()
  @Experimental() // untriaged
  void insertAdjacentHtml(String where, String html) => _blink.BlinkElement.instance.insertAdjacentHTML_Callback_2_(this, where, html);

  @DomName('Element.insertAdjacentText')
  @DocsEditable()
  @Experimental() // untriaged
  void insertAdjacentText(String where, String text) => _blink.BlinkElement.instance.insertAdjacentText_Callback_2_(this, where, text);

  @DomName('Element.matches')
  @DocsEditable()
  @Experimental() // untriaged
  bool matches(String selectors) => _blink.BlinkElement.instance.matches_Callback_1_(this, selectors);

  @DomName('Element.removeAttribute')
  @DocsEditable()
  void _removeAttribute(String name) => _blink.BlinkElement.instance.removeAttribute_Callback_1_(this, name);

  @DomName('Element.removeAttributeNS')
  @DocsEditable()
  void _removeAttributeNS(String namespaceURI, String localName) => _blink.BlinkElement.instance.removeAttributeNS_Callback_2_(this, namespaceURI, localName);

  @DomName('Element.requestFullscreen')
  @DocsEditable()
  @Experimental() // untriaged
  void requestFullscreen() => _blink.BlinkElement.instance.requestFullscreen_Callback_0_(this);

  @DomName('Element.requestPointerLock')
  @DocsEditable()
  @Experimental() // untriaged
  void requestPointerLock() => _blink.BlinkElement.instance.requestPointerLock_Callback_0_(this);

  void _scrollIntoView([bool alignWithTop]) {
    if (alignWithTop != null) {
      _blink.BlinkElement.instance.scrollIntoView_Callback_1_(this, alignWithTop);
      return;
    }
    _blink.BlinkElement.instance.scrollIntoView_Callback_0_(this);
    return;
  }

  void _scrollIntoViewIfNeeded([bool centerIfNeeded]) {
    if (centerIfNeeded != null) {
      _blink.BlinkElement.instance.scrollIntoViewIfNeeded_Callback_1_(this, centerIfNeeded);
      return;
    }
    _blink.BlinkElement.instance.scrollIntoViewIfNeeded_Callback_0_(this);
    return;
  }

  @DomName('Element.setAttribute')
  @DocsEditable()
  void setAttribute(String name, String value) => _blink.BlinkElement.instance.setAttribute_Callback_2_(this, name, value);

  @DomName('Element.setAttributeNS')
  @DocsEditable()
  void setAttributeNS(String namespaceURI, String qualifiedName, String value) => _blink.BlinkElement.instance.setAttributeNS_Callback_3_(this, namespaceURI, qualifiedName, value);

  @DomName('Element.nextElementSibling')
  @DocsEditable()
  Element get nextElementSibling => _blink.BlinkElement.instance.nextElementSibling_Getter_(this);

  @DomName('Element.previousElementSibling')
  @DocsEditable()
  Element get previousElementSibling => _blink.BlinkElement.instance.previousElementSibling_Getter_(this);

  @DomName('Element.remove')
  @DocsEditable()
  void remove() => _blink.BlinkElement.instance.remove_Callback_0_(this);

  @DomName('Element.childElementCount')
  @DocsEditable()
  int get _childElementCount => _blink.BlinkElement.instance.childElementCount_Getter_(this);

  @DomName('Element.children')
  @DocsEditable()
  List<Node> get _children => _blink.BlinkElement.instance.children_Getter_(this);

  @DomName('Element.firstElementChild')
  @DocsEditable()
  Element get _firstElementChild => _blink.BlinkElement.instance.firstElementChild_Getter_(this);

  @DomName('Element.lastElementChild')
  @DocsEditable()
  Element get _lastElementChild => _blink.BlinkElement.instance.lastElementChild_Getter_(this);

  /**
   * 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) => _blink.BlinkElement.instance.querySelector_Callback_1_(this, selectors);

  @DomName('Element.querySelectorAll')
  @DocsEditable()
  List<Node> _querySelectorAll(String selectors) => _blink.BlinkElement.instance.querySelectorAll_Callback_1_(this, selectors);

  /// Stream of `abort` events handled by this [Element].
  @DomName('Element.onabort')
  @DocsEditable()
  ElementStream<Event> get onAbort => abortEvent.forElement(this);

  /// Stream of `beforecopy` events handled by this [Element].
  @DomName('Element.onbeforecopy')
  @DocsEditable()
  ElementStream<Event> get onBeforeCopy => beforeCopyEvent.forElement(this);

  /// Stream of `beforecut` events handled by this [Element].
  @DomName('Element.onbeforecut')
  @DocsEditable()
  ElementStream<Event> get onBeforeCut => beforeCutEvent.forElement(this);

  /// Stream of `beforepaste` events handled by this [Element].
  @DomName('Element.onbeforepaste')
  @DocsEditable()
  ElementStream<Event> get onBeforePaste => beforePasteEvent.forElement(this);

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

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

  @DomName('Element.oncanplaythrough')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onCanPlayThrough => canPlayThroughEvent.forElement(this);

  /// Stream of `change` events handled by this [Element].
  @DomName('Element.onchange')
  @DocsEditable()
  ElementStream<Event> get onChange => changeEvent.forElement(this);

  /// Stream of `click` events handled by this [Element].
  @DomName('Element.onclick')
  @DocsEditable()
  ElementStream<MouseEvent> get onClick => clickEvent.forElement(this);

  /// Stream of `contextmenu` events handled by this [Element].
  @DomName('Element.oncontextmenu')
  @DocsEditable()
  ElementStream<MouseEvent> get onContextMenu => contextMenuEvent.forElement(this);

  /// Stream of `copy` events handled by this [Element].
  @DomName('Element.oncopy')
  @DocsEditable()
  ElementStream<Event> get onCopy => copyEvent.forElement(this);

  /// Stream of `cut` events handled by this [Element].
  @DomName('Element.oncut')
  @DocsEditable()
  ElementStream<Event> get onCut => cutEvent.forElement(this);

  /// Stream of `doubleclick` events handled by this [Element].
  @DomName('Element.ondblclick')
  @DocsEditable()
  ElementStream<Event> get onDoubleClick => doubleClickEvent.forElement(this);

  /**
   * A stream of `drag` events fired when this element currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondrag')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrag => dragEvent.forElement(this);

  /**
   * A stream of `dragend` events fired when this element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragend')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnd => dragEndEvent.forElement(this);

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragenter')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnter => dragEnterEvent.forElement(this);

  /**
   * A stream of `dragleave` events fired when an object being dragged over this
   * element leaves this element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragleave')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragLeave => dragLeaveEvent.forElement(this);

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragover')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragOver => dragOverEvent.forElement(this);

  /**
   * A stream of `dragstart` events fired when this element starts being
   * dragged.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragstart')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragStart => dragStartEvent.forElement(this);

  /**
   * A stream of `drop` events fired when a dragged object is dropped on this
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondrop')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrop => dropEvent.forElement(this);

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

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

  @DomName('Element.onended')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEnded => endedEvent.forElement(this);

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

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

  /// Stream of `input` events handled by this [Element].
  @DomName('Element.oninput')
  @DocsEditable()
  ElementStream<Event> get onInput => inputEvent.forElement(this);

  /// Stream of `invalid` events handled by this [Element].
  @DomName('Element.oninvalid')
  @DocsEditable()
  ElementStream<Event> get onInvalid => invalidEvent.forElement(this);

  /// Stream of `keydown` events handled by this [Element].
  @DomName('Element.onkeydown')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyDown => keyDownEvent.forElement(this);

  /// Stream of `keypress` events handled by this [Element].
  @DomName('Element.onkeypress')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyPress => keyPressEvent.forElement(this);

  /// Stream of `keyup` events handled by this [Element].
  @DomName('Element.onkeyup')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyUp => keyUpEvent.forElement(this);

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

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

  @DomName('Element.onloadedmetadata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedMetadata => loadedMetadataEvent.forElement(this);

  /// Stream of `mousedown` events handled by this [Element].
  @DomName('Element.onmousedown')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseDown => mouseDownEvent.forElement(this);

  /// Stream of `mouseenter` events handled by this [Element].
  @DomName('Element.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseEnter => mouseEnterEvent.forElement(this);

  /// Stream of `mouseleave` events handled by this [Element].
  @DomName('Element.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseLeave => mouseLeaveEvent.forElement(this);

  /// Stream of `mousemove` events handled by this [Element].
  @DomName('Element.onmousemove')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseMove => mouseMoveEvent.forElement(this);

  /// Stream of `mouseout` events handled by this [Element].
  @DomName('Element.onmouseout')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOut => mouseOutEvent.forElement(this);

  /// Stream of `mouseover` events handled by this [Element].
  @DomName('Element.onmouseover')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOver => mouseOverEvent.forElement(this);

  /// Stream of `mouseup` events handled by this [Element].
  @DomName('Element.onmouseup')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseUp => mouseUpEvent.forElement(this);

  /// Stream of `mousewheel` events handled by this [Element].
  @DomName('Element.onmousewheel')
  @DocsEditable()
  // http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents
  @Experimental() // non-standard
  ElementStream<WheelEvent> get onMouseWheel => mouseWheelEvent.forElement(this);

  /// Stream of `paste` events handled by this [Element].
  @DomName('Element.onpaste')
  @DocsEditable()
  ElementStream<Event> get onPaste => pasteEvent.forElement(this);

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

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

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

  @DomName('Element.onratechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onRateChange => rateChangeEvent.forElement(this);

  /// Stream of `reset` events handled by this [Element].
  @DomName('Element.onreset')
  @DocsEditable()
  ElementStream<Event> get onReset => resetEvent.forElement(this);

  @DomName('Element.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onResize => resizeEvent.forElement(this);

  /// Stream of `scroll` events handled by this [Element].
  @DomName('Element.onscroll')
  @DocsEditable()
  ElementStream<Event> get onScroll => scrollEvent.forElement(this);

  /// Stream of `search` events handled by this [Element].
  @DomName('Element.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  ElementStream<Event> get onSearch => searchEvent.forElement(this);

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

  @DomName('Element.onseeking')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeking => seekingEvent.forElement(this);

  /// Stream of `select` events handled by this [Element].
  @DomName('Element.onselect')
  @DocsEditable()
  ElementStream<Event> get onSelect => selectEvent.forElement(this);

  /// Stream of `selectstart` events handled by this [Element].
  @DomName('Element.onselectstart')
  @DocsEditable()
  @Experimental() // nonstandard
  ElementStream<Event> get onSelectStart => selectStartEvent.forElement(this);

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

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

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

  @DomName('Element.ontimeupdate')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onTimeUpdate => timeUpdateEvent.forElement(this);

  /// Stream of `touchcancel` events handled by this [Element].
  @DomName('Element.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchCancel => touchCancelEvent.forElement(this);

  /// Stream of `touchend` events handled by this [Element].
  @DomName('Element.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnd => touchEndEvent.forElement(this);

  /// Stream of `touchenter` events handled by this [Element].
  @DomName('Element.ontouchenter')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnter => touchEnterEvent.forElement(this);

  /// Stream of `touchleave` events handled by this [Element].
  @DomName('Element.ontouchleave')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchLeave => touchLeaveEvent.forElement(this);

  /// Stream of `touchmove` events handled by this [Element].
  @DomName('Element.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchMove => touchMoveEvent.forElement(this);

  /// Stream of `touchstart` events handled by this [Element].
  @DomName('Element.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchStart => touchStartEvent.forElement(this);

  /// Stream of `transitionend` events handled by this [Element].
  @DomName('Element.ontransitionend')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  ElementStream<TransitionEvent> get onTransitionEnd => transitionEndEvent.forElement(this);

  @DomName('Element.onvolumechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onVolumeChange => volumeChangeEvent.forElement(this);

  @DomName('Element.onwaiting')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onWaiting => waitingEvent.forElement(this);

  /// Stream of `fullscreenchange` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenchange')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenChange => fullscreenChangeEvent.forElement(this);

  /// Stream of `fullscreenerror` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenError => fullscreenErrorEvent.forElement(this);

}


class _ElementFactoryProvider {

  @DomName('Document.createElement')
  static Element createElement_tag(String tag, String typeExtension) =>
      document.createElement(tag, typeExtension);
}


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

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('HTMLEmbedElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
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 => true;

  @DomName('HTMLEmbedElement.height')
  @DocsEditable()
  String get height => _blink.BlinkHTMLEmbedElement.instance.height_Getter_(this);

  @DomName('HTMLEmbedElement.height')
  @DocsEditable()
  void set height(String value) => _blink.BlinkHTMLEmbedElement.instance.height_Setter_(this, value);

  @DomName('HTMLEmbedElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String get integrity => _blink.BlinkHTMLEmbedElement.instance.integrity_Getter_(this);

  @DomName('HTMLEmbedElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  void set integrity(String value) => _blink.BlinkHTMLEmbedElement.instance.integrity_Setter_(this, value);

  @DomName('HTMLEmbedElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLEmbedElement.instance.name_Getter_(this);

  @DomName('HTMLEmbedElement.name')
  @DocsEditable()
  void set name(String value) => _blink.BlinkHTMLEmbedElement.instance.name_Setter_(this, value);

  @DomName('HTMLEmbedElement.src')
  @DocsEditable()
  String get src => _blink.BlinkHTMLEmbedElement.instance.src_Getter_(this);

  @DomName('HTMLEmbedElement.src')
  @DocsEditable()
  void set src(String value) => _blink.BlinkHTMLEmbedElement.instance.src_Setter_(this, value);

  @DomName('HTMLEmbedElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLEmbedElement.instance.type_Getter_(this);

  @DomName('HTMLEmbedElement.type')
  @DocsEditable()
  void set type(String value) => _blink.BlinkHTMLEmbedElement.instance.type_Setter_(this, value);

  @DomName('HTMLEmbedElement.width')
  @DocsEditable()
  String get width => _blink.BlinkHTMLEmbedElement.instance.width_Getter_(this);

  @DomName('HTMLEmbedElement.width')
  @DocsEditable()
  void set width(String value) => _blink.BlinkHTMLEmbedElement.instance.width_Setter_(this, value);

  @DomName('HTMLEmbedElement.__getter__')
  @DocsEditable()
  bool __getter__(index_OR_name) => _blink.BlinkHTMLEmbedElement.instance.$__getter___Callback_1_(this, index_OR_name);

  @DomName('HTMLEmbedElement.__setter__')
  @DocsEditable()
  void __setter__(index_OR_name, Node value) => _blink.BlinkHTMLEmbedElement.instance.$__setter___Callback_2_(this, index_OR_name, 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('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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('Entry')
// http://www.w3.org/TR/file-system-api/#the-entry-interface
@Experimental()
class Entry extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory Entry._() { throw new UnsupportedError("Not supported"); }

  @DomName('Entry.filesystem')
  @DocsEditable()
  FileSystem get filesystem => _blink.BlinkEntry.instance.filesystem_Getter_(this);

  @DomName('Entry.fullPath')
  @DocsEditable()
  String get fullPath => _blink.BlinkEntry.instance.fullPath_Getter_(this);

  @DomName('Entry.isDirectory')
  @DocsEditable()
  bool get isDirectory => _blink.BlinkEntry.instance.isDirectory_Getter_(this);

  @DomName('Entry.isFile')
  @DocsEditable()
  bool get isFile => _blink.BlinkEntry.instance.isFile_Getter_(this);

  @DomName('Entry.name')
  @DocsEditable()
  String get name => _blink.BlinkEntry.instance.name_Getter_(this);

  void _copyTo(DirectoryEntry parent, {String name, _EntryCallback successCallback, _ErrorCallback errorCallback}) {
    if (errorCallback != null) {
      _blink.BlinkEntry.instance.copyTo_Callback_4_(this, parent, name, successCallback, errorCallback);
      return;
    }
    if (successCallback != null) {
      _blink.BlinkEntry.instance.copyTo_Callback_3_(this, parent, name, successCallback);
      return;
    }
    if (name != null) {
      _blink.BlinkEntry.instance.copyTo_Callback_2_(this, parent, name);
      return;
    }
    _blink.BlinkEntry.instance.copyTo_Callback_1_(this, parent);
    return;
  }

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

  void _getMetadata(MetadataCallback successCallback, [_ErrorCallback errorCallback]) {
    if (errorCallback != null) {
      _blink.BlinkEntry.instance.getMetadata_Callback_2_(this, successCallback, errorCallback);
      return;
    }
    _blink.BlinkEntry.instance.getMetadata_Callback_1_(this, successCallback);
    return;
  }

  Future<Metadata> getMetadata() {
    var completer = new Completer<Metadata>();
    _getMetadata(
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  void _getParent([_EntryCallback successCallback, _ErrorCallback errorCallback]) {
    if (errorCallback != null) {
      _blink.BlinkEntry.instance.getParent_Callback_2_(this, successCallback, errorCallback);
      return;
    }
    if (successCallback != null) {
      _blink.BlinkEntry.instance.getParent_Callback_1_(this, successCallback);
      return;
    }
    _blink.BlinkEntry.instance.getParent_Callback_0_(this);
    return;
  }

  Future<Entry> getParent() {
    var completer = new Completer<Entry>();
    _getParent(
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  void _moveTo(DirectoryEntry parent, {String name, _EntryCallback successCallback, _ErrorCallback errorCallback}) {
    if (errorCallback != null) {
      _blink.BlinkEntry.instance.moveTo_Callback_4_(this, parent, name, successCallback, errorCallback);
      return;
    }
    if (successCallback != null) {
      _blink.BlinkEntry.instance.moveTo_Callback_3_(this, parent, name, successCallback);
      return;
    }
    if (name != null) {
      _blink.BlinkEntry.instance.moveTo_Callback_2_(this, parent, name);
      return;
    }
    _blink.BlinkEntry.instance.moveTo_Callback_1_(this, parent);
    return;
  }

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

  void _remove(VoidCallback successCallback, [_ErrorCallback errorCallback]) {
    if (errorCallback != null) {
      _blink.BlinkEntry.instance.remove_Callback_2_(this, successCallback, errorCallback);
      return;
    }
    _blink.BlinkEntry.instance.remove_Callback_1_(this, successCallback);
    return;
  }

  Future remove() {
    var completer = new Completer();
    _remove(
        () { completer.complete(); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  @DomName('Entry.toURL')
  @DocsEditable()
  String toUrl() => _blink.BlinkEntry.instance.toURL_Callback_0_(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('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.

// WARNING: Do not edit - generated code.


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

  @DomName('ErrorEvent.colno')
  @DocsEditable()
  @Experimental() // untriaged
  int get colno => _blink.BlinkErrorEvent.instance.colno_Getter_(this);

  @DomName('ErrorEvent.error')
  @DocsEditable()
  @Experimental() // untriaged
  Object get error => _blink.BlinkErrorEvent.instance.error_Getter_(this);

  @DomName('ErrorEvent.filename')
  @DocsEditable()
  String get filename => _blink.BlinkErrorEvent.instance.filename_Getter_(this);

  @DomName('ErrorEvent.lineno')
  @DocsEditable()
  int get lineno => _blink.BlinkErrorEvent.instance.lineno_Getter_(this);

  @DomName('ErrorEvent.message')
  @DocsEditable()
  String get message => _blink.BlinkErrorEvent.instance.message_Getter_(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('Event')
class Event extends NativeFieldWrapperClass2 {
  // In JS, canBubble and cancelable are technically required parameters to
  // init*Event. In practice, though, if they aren't provided they simply
  // default to false (since that's Boolean(undefined)).
  //
  // Contrary to JS, we default canBubble and cancelable to true, since that's
  // what people want most of the time anyway.
  factory Event(String type,
      {bool canBubble: true, bool cancelable: true}) {
    return new Event.eventType('Event', type, canBubble: canBubble,
        cancelable: cancelable);
  }

  /**
   * Creates a new Event object of the specified type.
   *
   * This is analogous to document.createEvent.
   * Normally events should be created via their constructors, if available.
   *
   *     var e = new Event.type('MouseEvent', 'mousedown', true, true);
   */
  factory Event.eventType(String type, String name, {bool canBubble: true,
      bool cancelable: true}) {
    final Event e = document._createEvent(type);
    e._initEvent(name, canBubble, cancelable);
    return e;
  }
  
  /** The CSS selector involved with event delegation. */
  String _selector;

  /**
   * A pointer to the element whose CSS selector matched within which an event
   * was fired. If this Event was not associated with any Event delegation,
   * accessing this value will throw an [UnsupportedError].
   */
  Element get matchingTarget {
    if (_selector == null) {
      throw new UnsupportedError('Cannot call matchingTarget if this Event did'
          ' not arise as a result of event delegation.');
    }
    var currentTarget = this.currentTarget;
    var target = this.target;
    var matchedTarget;
    do {
      if (target.matches(_selector)) return target;
      target = target.parent;
    } while (target != null && target != currentTarget.parent);
    throw new StateError('No selector matched for populating matchedTarget.');
  }
  // To suppress missing implicit constructor warnings.
  factory Event._() { throw new UnsupportedError("Not supported"); }

  /**
   * This event is being handled by the event target.
   *
   * ## Other resources
   *
   * * [Target phase] (http://www.w3.org/TR/DOM-Level-3-Events/#target-phase)
   * from W3C.
   */
  @DomName('Event.AT_TARGET')
  @DocsEditable()
  static const int AT_TARGET = 2;

  /**
   * This event is bubbling up through the target's ancestors.
   *
   * ## Other resources
   *
   * * [Bubble phase] (http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
   * from W3C.
   */
  @DomName('Event.BUBBLING_PHASE')
  @DocsEditable()
  static const int BUBBLING_PHASE = 3;

  /**
   * This event is propagating through the target's ancestors, starting from the
   * document.
   *
   * ## Other resources
   *
   * * [Bubble phase] (http://www.w3.org/TR/DOM-Level-3-Events/#bubble-phase)
   * from W3C.
   */
  @DomName('Event.CAPTURING_PHASE')
  @DocsEditable()
  static const int CAPTURING_PHASE = 1;

  @DomName('Event.bubbles')
  @DocsEditable()
  bool get bubbles => _blink.BlinkEvent.instance.bubbles_Getter_(this);

  @DomName('Event.cancelable')
  @DocsEditable()
  bool get cancelable => _blink.BlinkEvent.instance.cancelable_Getter_(this);

  /**
   * Access to the system's clipboard data during copy, cut, and paste events.
   *
   * ## Other resources
   *
   * * [clipboardData specification]
   * (http://www.w3.org/TR/clipboard-apis/#attributes) from W3C.
   */
  @DomName('Event.clipboardData')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // Part of copy/paste
  @Experimental() // nonstandard
  DataTransfer get clipboardData => _blink.BlinkEvent.instance.clipboardData_Getter_(this);

  @DomName('Event.currentTarget')
  @DocsEditable()
  EventTarget get currentTarget => _blink.BlinkEvent.instance.currentTarget_Getter_(this);

  @DomName('Event.defaultPrevented')
  @DocsEditable()
  bool get defaultPrevented => _blink.BlinkEvent.instance.defaultPrevented_Getter_(this);

  @DomName('Event.eventPhase')
  @DocsEditable()
  int get eventPhase => _blink.BlinkEvent.instance.eventPhase_Getter_(this);

  /**
   * 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()
  List<Node> get path => _blink.BlinkEvent.instance.path_Getter_(this);

  @DomName('Event.target')
  @DocsEditable()
  EventTarget get target => _blink.BlinkEvent.instance.target_Getter_(this);

  @DomName('Event.timeStamp')
  @DocsEditable()
  int get timeStamp => _blink.BlinkEvent.instance.timeStamp_Getter_(this);

  @DomName('Event.type')
  @DocsEditable()
  String get type => _blink.BlinkEvent.instance.type_Getter_(this);

  @DomName('Event.initEvent')
  @DocsEditable()
  void _initEvent(String eventTypeArg, bool canBubbleArg, bool cancelableArg) => _blink.BlinkEvent.instance.initEvent_Callback_3_(this, eventTypeArg, canBubbleArg, cancelableArg);

  @DomName('Event.preventDefault')
  @DocsEditable()
  void preventDefault() => _blink.BlinkEvent.instance.preventDefault_Callback_0_(this);

  @DomName('Event.stopImmediatePropagation')
  @DocsEditable()
  void stopImmediatePropagation() => _blink.BlinkEvent.instance.stopImmediatePropagation_Callback_0_(this);

  @DomName('Event.stopPropagation')
  @DocsEditable()
  void stopPropagation() => _blink.BlinkEvent.instance.stopPropagation_Callback_0_(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('EventSource')
// http://www.w3.org/TR/eventsource/#the-eventsource-interface
@Experimental() // stable
class EventSource extends EventTarget {
  factory EventSource(String title, {withCredentials: false}) {
    var parsedOptions = {
      'withCredentials': withCredentials,
    };
    return EventSource._factoryEventSource(title, parsedOptions);
  }
  // To suppress missing implicit constructor warnings.
  factory EventSource._() { throw new UnsupportedError("Not supported"); }

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

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

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

  @DomName('EventSource.EventSource')
  @DocsEditable()
  static EventSource _factoryEventSource(String url, [Map eventSourceInit]) {
    if (eventSourceInit != null) {
      return _blink.BlinkEventSource.instance.constructorCallback_2_(url, eventSourceInit);
    }
    return _blink.BlinkEventSource.instance.constructorCallback_1_(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()
  int get readyState => _blink.BlinkEventSource.instance.readyState_Getter_(this);

  @DomName('EventSource.url')
  @DocsEditable()
  String get url => _blink.BlinkEventSource.instance.url_Getter_(this);

  @DomName('EventSource.withCredentials')
  @DocsEditable()
  bool get withCredentials => _blink.BlinkEventSource.instance.withCredentials_Getter_(this);

  @DomName('EventSource.close')
  @DocsEditable()
  void close() => _blink.BlinkEventSource.instance.close_Callback_0_(this);

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

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

  /// Stream of `open` events handled by this [EventSource].
  @DomName('EventSource.onopen')
  @DocsEditable()
  Stream<Event> get onOpen => openEvent.forTarget(this);

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


/**
 * Base class that supports listening for and dispatching browser events.
 *
 * Normally events are accessed via the Stream getter:
 *
 *     element.onMouseOver.listen((e) => print('Mouse over!'));
 *
 * To access bubbling events which are declared on one element, but may bubble
 * up to another element type (common for MediaElement events):
 *
 *     MediaElement.pauseEvent.forTarget(document.body).listen(...);
 *
 * To useCapture on events:
 *
 *     Element.keyDownEvent.forTarget(element, useCapture: true).listen(...);
 *
 * Custom events can be declared as:
 *
 *     class DataGenerator {
 *       static EventStreamProvider<Event> dataEvent =
 *           new EventStreamProvider('data');
 *     }
 *
 * Then listeners should access the event with:
 *
 *     DataGenerator.dataEvent.forTarget(element).listen(...);
 *
 * Custom events can also be accessed as:
 *
 *     element.on['some_event'].listen(...);
 *
 * This approach is generally discouraged as it loses the event typing and
 * some DOM events may have multiple platform-dependent event names under the
 * covers. By using the standard Stream getters you will get the platform
 * specific event name automatically.
 */
class Events {
  /* Raw event target. */
  final EventTarget _ptr;

  Events(this._ptr);

  Stream operator [](String type) {
    return new _EventStream(_ptr, type, false);
  }
}

class ElementEvents extends Events {
  /* Raw event target. */
  final Element _ptr;
  static final webkitEvents = {
    'animationend' : 'webkitAnimationEnd', 
    'animationiteration' : 'webkitAnimationIteration', 
    'animationstart' : 'webkitAnimationStart', 
    'fullscreenchange' : 'webkitfullscreenchange', 
    'fullscreenerror' : 'webkitfullscreenerror',
    'keyadded' : 'webkitkeyadded', 
    'keyerror' : 'webkitkeyerror', 
    'keymessage' : 'webkitkeymessage', 
    'needkey' : 'webkitneedkey', 
    'pointerlockchange' : 'webkitpointerlockchange', 
    'pointerlockerror' : 'webkitpointerlockerror', 
    'resourcetimingbufferfull' : 'webkitresourcetimingbufferfull', 
    'transitionend': 'webkitTransitionEnd',
    'speechchange' : 'webkitSpeechChange'
  };

  ElementEvents(Element ptr) : this._ptr = ptr, super(ptr);

  Stream operator [](String type) {
    if (webkitEvents.keys.contains(type.toLowerCase())) {
      if (Device.isWebKit) {
        return new _ElementEventStreamImpl(
            _ptr, webkitEvents[type.toLowerCase()], false);
      }
    }
    return new _ElementEventStreamImpl(_ptr, type, false);
  }
}

/**
 * Base class for all browser objects that support events.
 *
 * Use the [on] property to add, and remove events
 * for compile-time type checks and a more concise API.
 */
@DomName('EventTarget')
class EventTarget extends NativeFieldWrapperClass2 {

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

  void _addEventListener([String type, EventListener listener, bool useCapture]) {
    if (useCapture != null) {
      _blink.BlinkEventTarget.instance.addEventListener_Callback_3_(this, type, listener, useCapture);
      return;
    }
    if (listener != null) {
      _blink.BlinkEventTarget.instance.addEventListener_Callback_2_(this, type, listener);
      return;
    }
    if (type != null) {
      _blink.BlinkEventTarget.instance.addEventListener_Callback_1_(this, type);
      return;
    }
    _blink.BlinkEventTarget.instance.addEventListener_Callback_0_(this);
    return;
  }

  @DomName('EventTarget.dispatchEvent')
  @DocsEditable()
  bool dispatchEvent(Event event) => _blink.BlinkEventTarget.instance.dispatchEvent_Callback_1_(this, event);

  void _removeEventListener([String type, EventListener listener, bool useCapture]) {
    if (useCapture != null) {
      _blink.BlinkEventTarget.instance.removeEventListener_Callback_3_(this, type, listener, useCapture);
      return;
    }
    if (listener != null) {
      _blink.BlinkEventTarget.instance.removeEventListener_Callback_2_(this, type, listener);
      return;
    }
    if (type != null) {
      _blink.BlinkEventTarget.instance.removeEventListener_Callback_1_(this, type);
      return;
    }
    _blink.BlinkEventTarget.instance.removeEventListener_Callback_0_(this);
    return;
  }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

  @DomName('FederatedCredential.FederatedCredential')
  @DocsEditable()
  factory FederatedCredential(String id, String name, String avatarURL, String federation) {
    return _blink.BlinkFederatedCredential.instance.constructorCallback_4_(id, name, avatarURL, federation);
  }

  @DomName('FederatedCredential.federation')
  @DocsEditable()
  @Experimental() // untriaged
  String get federation => _blink.BlinkFederatedCredential.instance.federation_Getter_(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.


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

  @DomName('FetchBodyStream.asArrayBuffer')
  @DocsEditable()
  @Experimental() // untriaged
  Future asArrayBuffer() => _blink.BlinkFetchBodyStream.instance.asArrayBuffer_Callback_0_(this);

  @DomName('FetchBodyStream.asBlob')
  @DocsEditable()
  @Experimental() // untriaged
  Future asBlob() => _blink.BlinkFetchBodyStream.instance.asBlob_Callback_0_(this);

  @DomName('FetchBodyStream.asJSON')
  @DocsEditable()
  @Experimental() // untriaged
  Future asJson() => _blink.BlinkFetchBodyStream.instance.asJSON_Callback_0_(this);

  @DomName('FetchBodyStream.asText')
  @DocsEditable()
  @Experimental() // untriaged
  Future asText() => _blink.BlinkFetchBodyStream.instance.asText_Callback_0_(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.


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

  @DomName('FetchEvent.isReload')
  @DocsEditable()
  @Experimental() // untriaged
  bool get isReload => _blink.BlinkFetchEvent.instance.isReload_Getter_(this);

  @DomName('FetchEvent.request')
  @DocsEditable()
  @Experimental() // untriaged
  _Request get request => _blink.BlinkFetchEvent.instance.request_Getter_(this);

  @DomName('FetchEvent.respondWith')
  @DocsEditable()
  @Experimental() // untriaged
  void respondWith(Object value) => _blink.BlinkFetchEvent.instance.respondWith_Callback_1_(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.

// WARNING: Do not edit - generated code.


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

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

  @DomName('HTMLFieldSetElement.disabled')
  @DocsEditable()
  bool get disabled => _blink.BlinkHTMLFieldSetElement.instance.disabled_Getter_(this);

  @DomName('HTMLFieldSetElement.disabled')
  @DocsEditable()
  void set disabled(bool value) => _blink.BlinkHTMLFieldSetElement.instance.disabled_Setter_(this, value);

  @DomName('HTMLFieldSetElement.elements')
  @DocsEditable()
  List<Node> get elements => _blink.BlinkHTMLFieldSetElement.instance.elements_Getter_(this);

  @DomName('HTMLFieldSetElement.form')
  @DocsEditable()
  FormElement get form => _blink.BlinkHTMLFieldSetElement.instance.form_Getter_(this);

  @DomName('HTMLFieldSetElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLFieldSetElement.instance.name_Getter_(this);

  @DomName('HTMLFieldSetElement.name')
  @DocsEditable()
  void set name(String value) => _blink.BlinkHTMLFieldSetElement.instance.name_Setter_(this, value);

  @DomName('HTMLFieldSetElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLFieldSetElement.instance.type_Getter_(this);

  @DomName('HTMLFieldSetElement.validationMessage')
  @DocsEditable()
  String get validationMessage => _blink.BlinkHTMLFieldSetElement.instance.validationMessage_Getter_(this);

  @DomName('HTMLFieldSetElement.validity')
  @DocsEditable()
  ValidityState get validity => _blink.BlinkHTMLFieldSetElement.instance.validity_Getter_(this);

  @DomName('HTMLFieldSetElement.willValidate')
  @DocsEditable()
  bool get willValidate => _blink.BlinkHTMLFieldSetElement.instance.willValidate_Getter_(this);

  @DomName('HTMLFieldSetElement.checkValidity')
  @DocsEditable()
  bool checkValidity() => _blink.BlinkHTMLFieldSetElement.instance.checkValidity_Callback_0_(this);

  @DomName('HTMLFieldSetElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) => _blink.BlinkHTMLFieldSetElement.instance.setCustomValidity_Callback_1_(this, 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.


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

  @DomName('File.lastModified')
  @DocsEditable()
  @Experimental() // untriaged
  int get lastModified => _blink.BlinkFile.instance.lastModified_Getter_(this);

  @DomName('File.lastModifiedDate')
  @DocsEditable()
  DateTime get lastModifiedDate => _blink.BlinkFile.instance.lastModifiedDate_Getter_(this);

  @DomName('File.name')
  @DocsEditable()
  String get name => _blink.BlinkFile.instance.name_Getter_(this);

  @DomName('File.webkitRelativePath')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://plus.sandbox.google.com/+AddyOsmani/posts/Dk5UhZ6zfF3
  String get relativePath => _blink.BlinkFile.instance.webkitRelativePath_Getter_(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('FileCallback')
// http://www.w3.org/TR/file-system-api/#the-filecallback-interface
@Experimental()
typedef void _FileCallback(File file);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('FileEntry')
// http://www.w3.org/TR/file-system-api/#the-fileentry-interface
@Experimental()
class FileEntry extends Entry {
  // To suppress missing implicit constructor warnings.
  factory FileEntry._() { throw new UnsupportedError("Not supported"); }

  void _createWriter(_FileWriterCallback successCallback, [_ErrorCallback errorCallback]) {
    if (errorCallback != null) {
      _blink.BlinkFileEntry.instance.createWriter_Callback_2_(this, successCallback, errorCallback);
      return;
    }
    _blink.BlinkFileEntry.instance.createWriter_Callback_1_(this, successCallback);
    return;
  }

  Future<FileWriter> createWriter() {
    var completer = new Completer<FileWriter>();
    _createWriter(
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  void _file(_FileCallback successCallback, [_ErrorCallback errorCallback]) {
    if (errorCallback != null) {
      _blink.BlinkFileEntry.instance.file_Callback_2_(this, successCallback, errorCallback);
      return;
    }
    _blink.BlinkFileEntry.instance.file_Callback_1_(this, successCallback);
    return;
  }

  Future<File> file() {
    var completer = new Completer<File>();
    _file(
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

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

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('FileError')
// http://dev.w3.org/2009/dap/file-system/pub/FileSystem/
@Experimental()
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()
  int get code => _blink.BlinkFileError.instance.code_Getter_(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.


@DocsEditable()
@DomName('FileList')
class FileList extends NativeFieldWrapperClass2 with ListMixin<File>, ImmutableListMixin<File> implements List<File> {
  // To suppress missing implicit constructor warnings.
  factory FileList._() { throw new UnsupportedError("Not supported"); }

  @DomName('FileList.length')
  @DocsEditable()
  int get length => _blink.BlinkFileList.instance.length_Getter_(this);

  File operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return _blink.BlinkFileList.instance.item_Callback_1_(this, index);
  }

  File _nativeIndexedGetter(int index) => _blink.BlinkFileList.instance.item_Callback_1_(this, index);

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


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

  File get first {
    if (this.length > 0) {
      return _nativeIndexedGetter(0);
    }
    throw new StateError("No elements");
  }

  File get last {
    int len = this.length;
    if (len > 0) {
      return _nativeIndexedGetter(len - 1);
    }
    throw new StateError("No elements");
  }

  File get single {
    int len = this.length;
    if (len == 1) {
      return _nativeIndexedGetter(0);
    }
    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) => _blink.BlinkFileList.instance.item_Callback_1_(this, index);

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


@DocsEditable()
@DomName('FileReader')
class FileReader extends EventTarget {

  @DomName('FileReader.result')
  @DocsEditable()
  Object get result {
    var res = _blink.BlinkFileReader.result_Getter(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 _blink.BlinkFileReader.instance.constructorCallback_0_();
  }

  @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()
  FileError get error => _blink.BlinkFileReader.instance.error_Getter_(this);

  @DomName('FileReader.readyState')
  @DocsEditable()
  int get readyState => _blink.BlinkFileReader.instance.readyState_Getter_(this);

  @DomName('FileReader.result')
  @DocsEditable()
  Object get _result => _blink.BlinkFileReader.instance.result_Getter_(this);

  @DomName('FileReader.abort')
  @DocsEditable()
  void abort() => _blink.BlinkFileReader.instance.abort_Callback_0_(this);

  @DomName('FileReader.readAsArrayBuffer')
  @DocsEditable()
  void readAsArrayBuffer(Blob blob) => _blink.BlinkFileReader.instance.readAsArrayBuffer_Callback_1_(this, blob);

  @DomName('FileReader.readAsDataURL')
  @DocsEditable()
  void readAsDataUrl(Blob blob) => _blink.BlinkFileReader.instance.readAsDataURL_Callback_1_(this, blob);

  void readAsText(Blob blob, [String encoding]) {
    if (encoding != null) {
      _blink.BlinkFileReader.instance.readAsText_Callback_2_(this, blob, encoding);
      return;
    }
    _blink.BlinkFileReader.instance.readAsText_Callback_1_(this, blob);
    return;
  }

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

// WARNING: Do not edit - generated code.


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

  @DomName('Stream.type')
  @DocsEditable()
  @Experimental() // untriaged
  String get type => _blink.BlinkStream.instance.type_Getter_(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.


@DocsEditable()
@DomName('DOMFileSystem')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://www.w3.org/TR/file-system-api/
class FileSystem extends NativeFieldWrapperClass2 {
  // 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 => true;

  @DomName('DOMFileSystem.name')
  @DocsEditable()
  String get name => _blink.BlinkDOMFileSystem.instance.name_Getter_(this);

  @DomName('DOMFileSystem.root')
  @DocsEditable()
  DirectoryEntry get root => _blink.BlinkDOMFileSystem.instance.root_Getter_(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('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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('FileWriter')
// http://www.w3.org/TR/file-writer-api/#the-filewriter-interface
@Experimental()
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()
  FileError get error => _blink.BlinkFileWriter.instance.error_Getter_(this);

  @DomName('FileWriter.length')
  @DocsEditable()
  int get length => _blink.BlinkFileWriter.instance.length_Getter_(this);

  @DomName('FileWriter.position')
  @DocsEditable()
  int get position => _blink.BlinkFileWriter.instance.position_Getter_(this);

  @DomName('FileWriter.readyState')
  @DocsEditable()
  int get readyState => _blink.BlinkFileWriter.instance.readyState_Getter_(this);

  @DomName('FileWriter.abort')
  @DocsEditable()
  void abort() => _blink.BlinkFileWriter.instance.abort_Callback_0_(this);

  @DomName('FileWriter.seek')
  @DocsEditable()
  void seek(int position) => _blink.BlinkFileWriter.instance.seek_Callback_1_(this, position);

  @DomName('FileWriter.truncate')
  @DocsEditable()
  void truncate(int size) => _blink.BlinkFileWriter.instance.truncate_Callback_1_(this, size);

  @DomName('FileWriter.write')
  @DocsEditable()
  void write(Blob data) => _blink.BlinkFileWriter.instance.write_Callback_1_(this, data);

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

// WARNING: Do not edit - generated code.


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

  @DomName('FocusEvent.relatedTarget')
  @DocsEditable()
  EventTarget get relatedTarget => _blink.BlinkFocusEvent.instance.relatedTarget_Getter_(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.


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

  @DomName('FontFace.FontFace')
  @DocsEditable()
  factory FontFace(String family, source, [Map descriptors]) {
    if ((source is String || source == null) && (family is String || family == null) && descriptors == null) {
      return _blink.BlinkFontFace.instance.constructorCallback_2_(family, source);
    }
    if ((descriptors is Map || descriptors == null) && (source is String || source == null) && (family is String || family == null)) {
      return _blink.BlinkFontFace.instance.constructorCallback_3_(family, source, descriptors);
    }
    if ((source is TypedData || source == null) && (family is String || family == null) && descriptors == null) {
      return _blink.BlinkFontFace.instance.constructorCallback_2_(family, source);
    }
    if ((descriptors is Map || descriptors == null) && (source is TypedData || source == null) && (family is String || family == null)) {
      return _blink.BlinkFontFace.instance.constructorCallback_3_(family, source, descriptors);
    }
    if ((source is ByteBuffer || source == null) && (family is String || family == null) && descriptors == null) {
      return _blink.BlinkFontFace.instance.constructorCallback_2_(family, source);
    }
    if ((descriptors is Map || descriptors == null) && (source is ByteBuffer || source == null) && (family is String || family == null)) {
      return _blink.BlinkFontFace.instance.constructorCallback_3_(family, source, descriptors);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('FontFace.family')
  @DocsEditable()
  @Experimental() // untriaged
  String get family => _blink.BlinkFontFace.instance.family_Getter_(this);

  @DomName('FontFace.family')
  @DocsEditable()
  @Experimental() // untriaged
  void set family(String value) => _blink.BlinkFontFace.instance.family_Setter_(this, value);

  @DomName('FontFace.featureSettings')
  @DocsEditable()
  @Experimental() // untriaged
  String get featureSettings => _blink.BlinkFontFace.instance.featureSettings_Getter_(this);

  @DomName('FontFace.featureSettings')
  @DocsEditable()
  @Experimental() // untriaged
  void set featureSettings(String value) => _blink.BlinkFontFace.instance.featureSettings_Setter_(this, value);

  @DomName('FontFace.loaded')
  @DocsEditable()
  @Experimental() // untriaged
  Future get loaded => _blink.BlinkFontFace.instance.loaded_Getter_(this);

  @DomName('FontFace.status')
  @DocsEditable()
  @Experimental() // untriaged
  String get status => _blink.BlinkFontFace.instance.status_Getter_(this);

  @DomName('FontFace.stretch')
  @DocsEditable()
  @Experimental() // untriaged
  String get stretch => _blink.BlinkFontFace.instance.stretch_Getter_(this);

  @DomName('FontFace.stretch')
  @DocsEditable()
  @Experimental() // untriaged
  void set stretch(String value) => _blink.BlinkFontFace.instance.stretch_Setter_(this, value);

  @DomName('FontFace.style')
  @DocsEditable()
  @Experimental() // untriaged
  String get style => _blink.BlinkFontFace.instance.style_Getter_(this);

  @DomName('FontFace.style')
  @DocsEditable()
  @Experimental() // untriaged
  void set style(String value) => _blink.BlinkFontFace.instance.style_Setter_(this, value);

  @DomName('FontFace.unicodeRange')
  @DocsEditable()
  @Experimental() // untriaged
  String get unicodeRange => _blink.BlinkFontFace.instance.unicodeRange_Getter_(this);

  @DomName('FontFace.unicodeRange')
  @DocsEditable()
  @Experimental() // untriaged
  void set unicodeRange(String value) => _blink.BlinkFontFace.instance.unicodeRange_Setter_(this, value);

  @DomName('FontFace.variant')
  @DocsEditable()
  @Experimental() // untriaged
  String get variant => _blink.BlinkFontFace.instance.variant_Getter_(this);

  @DomName('FontFace.variant')
  @DocsEditable()
  @Experimental() // untriaged
  void set variant(String value) => _blink.BlinkFontFace.instance.variant_Setter_(this, value);

  @DomName('FontFace.weight')
  @DocsEditable()
  @Experimental() // untriaged
  String get weight => _blink.BlinkFontFace.instance.weight_Getter_(this);

  @DomName('FontFace.weight')
  @DocsEditable()
  @Experimental() // untriaged
  void set weight(String value) => _blink.BlinkFontFace.instance.weight_Setter_(this, value);

  @DomName('FontFace.load')
  @DocsEditable()
  @Experimental() // untriaged
  Future load() => _blink.BlinkFontFace.instance.load_Callback_0_(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.


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

  @DomName('FontFaceSet.size')
  @DocsEditable()
  @Experimental() // untriaged
  int get size => _blink.BlinkFontFaceSet.instance.size_Getter_(this);

  @DomName('FontFaceSet.status')
  @DocsEditable()
  @Experimental() // untriaged
  String get status => _blink.BlinkFontFaceSet.instance.status_Getter_(this);

  @DomName('FontFaceSet.add')
  @DocsEditable()
  @Experimental() // untriaged
  void add(FontFace fontFace) => _blink.BlinkFontFaceSet.instance.add_Callback_1_(this, fontFace);

  @DomName('FontFaceSet.check')
  @DocsEditable()
  @Experimental() // untriaged
  bool check(String font, String text) => _blink.BlinkFontFaceSet.instance.check_Callback_2_(this, font, text);

  @DomName('FontFaceSet.clear')
  @DocsEditable()
  @Experimental() // untriaged
  void clear() => _blink.BlinkFontFaceSet.instance.clear_Callback_0_(this);

  @DomName('FontFaceSet.delete')
  @DocsEditable()
  @Experimental() // untriaged
  bool delete(FontFace fontFace) => _blink.BlinkFontFaceSet.instance.delete_Callback_1_(this, fontFace);

  void forEach(FontFaceSetForEachCallback callback, [Object thisArg]) {
    if (thisArg != null) {
      _blink.BlinkFontFaceSet.instance.forEach_Callback_2_(this, callback, thisArg);
      return;
    }
    _blink.BlinkFontFaceSet.instance.forEach_Callback_1_(this, callback);
    return;
  }

  @DomName('FontFaceSet.has')
  @DocsEditable()
  @Experimental() // untriaged
  bool has(FontFace fontFace) => _blink.BlinkFontFaceSet.instance.has_Callback_1_(this, fontFace);

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

// WARNING: Do not edit - generated code.


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

// WARNING: Do not edit - generated code.


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

  @DomName('FontFaceSetLoadEvent.fontfaces')
  @DocsEditable()
  @Experimental() // untriaged
  List<FontFace> get fontfaces => _blink.BlinkFontFaceSetLoadEvent.instance.fontfaces_Getter_(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.


@DocsEditable()
@DomName('FormData')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
class FormData extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory FormData._() { throw new UnsupportedError("Not supported"); }

  @DomName('FormData.FormData')
  @DocsEditable()
  factory FormData([FormElement form]) => _create(form);

  @DocsEditable()
  static FormData _create(form) => _blink.BlinkFormData.instance.constructorCallback_1_(form);

  /// Checks if this type is supported on the current platform.
  static bool get supported => true;

  @DomName('FormData.append')
  @DocsEditable()
  void append(String name, String value) => _blink.BlinkFormData.instance.append_Callback_2_(this, name, value);

  @DomName('FormData.appendBlob')
  @DocsEditable()
  void appendBlob(String name, Blob value, [String filename]) => _blink.BlinkFormData.instance.append_Callback_3_(this, name, value, filename);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

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

  @DomName('HTMLFormElement.acceptCharset')
  @DocsEditable()
  String get acceptCharset => _blink.BlinkHTMLFormElement.instance.acceptCharset_Getter_(this);

  @DomName('HTMLFormElement.acceptCharset')
  @DocsEditable()
  void set acceptCharset(String value) => _blink.BlinkHTMLFormElement.instance.acceptCharset_Setter_(this, value);

  @DomName('HTMLFormElement.action')
  @DocsEditable()
  String get action => _blink.BlinkHTMLFormElement.instance.action_Getter_(this);

  @DomName('HTMLFormElement.action')
  @DocsEditable()
  void set action(String value) => _blink.BlinkHTMLFormElement.instance.action_Setter_(this, value);

  @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 get autocomplete => _blink.BlinkHTMLFormElement.instance.autocomplete_Getter_(this);

  @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()
  void set autocomplete(String value) => _blink.BlinkHTMLFormElement.instance.autocomplete_Setter_(this, value);

  @DomName('HTMLFormElement.encoding')
  @DocsEditable()
  String get encoding => _blink.BlinkHTMLFormElement.instance.encoding_Getter_(this);

  @DomName('HTMLFormElement.encoding')
  @DocsEditable()
  void set encoding(String value) => _blink.BlinkHTMLFormElement.instance.encoding_Setter_(this, value);

  @DomName('HTMLFormElement.enctype')
  @DocsEditable()
  String get enctype => _blink.BlinkHTMLFormElement.instance.enctype_Getter_(this);

  @DomName('HTMLFormElement.enctype')
  @DocsEditable()
  void set enctype(String value) => _blink.BlinkHTMLFormElement.instance.enctype_Setter_(this, value);

  @DomName('HTMLFormElement.length')
  @DocsEditable()
  int get length => _blink.BlinkHTMLFormElement.instance.length_Getter_(this);

  @DomName('HTMLFormElement.method')
  @DocsEditable()
  String get method => _blink.BlinkHTMLFormElement.instance.method_Getter_(this);

  @DomName('HTMLFormElement.method')
  @DocsEditable()
  void set method(String value) => _blink.BlinkHTMLFormElement.instance.method_Setter_(this, value);

  @DomName('HTMLFormElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLFormElement.instance.name_Getter_(this);

  @DomName('HTMLFormElement.name')
  @DocsEditable()
  void set name(String value) => _blink.BlinkHTMLFormElement.instance.name_Setter_(this, value);

  @DomName('HTMLFormElement.noValidate')
  @DocsEditable()
  bool get noValidate => _blink.BlinkHTMLFormElement.instance.noValidate_Getter_(this);

  @DomName('HTMLFormElement.noValidate')
  @DocsEditable()
  void set noValidate(bool value) => _blink.BlinkHTMLFormElement.instance.noValidate_Setter_(this, value);

  @DomName('HTMLFormElement.target')
  @DocsEditable()
  String get target => _blink.BlinkHTMLFormElement.instance.target_Getter_(this);

  @DomName('HTMLFormElement.target')
  @DocsEditable()
  void set target(String value) => _blink.BlinkHTMLFormElement.instance.target_Setter_(this, value);

  Element __getter__(index_OR_name) {
    if ((index_OR_name is int || index_OR_name == null)) {
      return _blink.BlinkHTMLFormElement.instance.$__getter___Callback_1_(this, index_OR_name);
    }
    if ((index_OR_name is String || index_OR_name == null)) {
      return _blink.BlinkHTMLFormElement.instance.$__getter___Callback_1_(this, index_OR_name);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('HTMLFormElement.checkValidity')
  @DocsEditable()
  bool checkValidity() => _blink.BlinkHTMLFormElement.instance.checkValidity_Callback_0_(this);

  @DomName('HTMLFormElement.requestAutocomplete')
  @DocsEditable()
  // http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2012-October/037711.html
  @Experimental()
  void requestAutocomplete(Map details) => _blink.BlinkHTMLFormElement.instance.requestAutocomplete_Callback_1_(this, details);

  @DomName('HTMLFormElement.reset')
  @DocsEditable()
  void reset() => _blink.BlinkHTMLFormElement.instance.reset_Callback_0_(this);

  @DomName('HTMLFormElement.submit')
  @DocsEditable()
  void submit() => _blink.BlinkHTMLFormElement.instance.submit_Callback_0_(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.


@DocsEditable()
@DomName('Gamepad')
// https://dvcs.w3.org/hg/gamepad/raw-file/default/gamepad.html#gamepad-interface
@Experimental()
class Gamepad extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory Gamepad._() { throw new UnsupportedError("Not supported"); }

  @DomName('Gamepad.axes')
  @DocsEditable()
  List<num> get axes => _blink.BlinkGamepad.instance.axes_Getter_(this);

  @DomName('Gamepad.connected')
  @DocsEditable()
  @Experimental() // untriaged
  bool get connected => _blink.BlinkGamepad.instance.connected_Getter_(this);

  @DomName('Gamepad.id')
  @DocsEditable()
  String get id => _blink.BlinkGamepad.instance.id_Getter_(this);

  @DomName('Gamepad.index')
  @DocsEditable()
  int get index => _blink.BlinkGamepad.instance.index_Getter_(this);

  @DomName('Gamepad.mapping')
  @DocsEditable()
  @Experimental() // untriaged
  String get mapping => _blink.BlinkGamepad.instance.mapping_Getter_(this);

  @DomName('Gamepad.timestamp')
  @DocsEditable()
  int get timestamp => _blink.BlinkGamepad.instance.timestamp_Getter_(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.


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

  @DomName('GamepadButton.pressed')
  @DocsEditable()
  @Experimental() // untriaged
  bool get pressed => _blink.BlinkGamepadButton.instance.pressed_Getter_(this);

  @DomName('GamepadButton.value')
  @DocsEditable()
  @Experimental() // untriaged
  double get value => _blink.BlinkGamepadButton.instance.value_Getter_(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.


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

  @DomName('GamepadEvent.gamepad')
  @DocsEditable()
  @Experimental() // untriaged
  Gamepad get gamepad => _blink.BlinkGamepadEvent.instance.gamepad_Getter_(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.


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

  @DomName('Geofencing.getRegisteredRegions')
  @DocsEditable()
  @Experimental() // untriaged
  Future getRegisteredRegions() => _blink.BlinkGeofencing.instance.getRegisteredRegions_Callback_0_(this);

  @DomName('Geofencing.registerRegion')
  @DocsEditable()
  @Experimental() // untriaged
  Future registerRegion(GeofencingRegion region) => _blink.BlinkGeofencing.instance.registerRegion_Callback_1_(this, region);

  @DomName('Geofencing.unregisterRegion')
  @DocsEditable()
  @Experimental() // untriaged
  Future unregisterRegion(String regionId) => _blink.BlinkGeofencing.instance.unregisterRegion_Callback_1_(this, regionId);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

  @DomName('GeofencingRegion.id')
  @DocsEditable()
  @Experimental() // untriaged
  String get id => _blink.BlinkGeofencingRegion.instance.id_Getter_(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('Geolocation')
@Unstable()
class Geolocation extends NativeFieldWrapperClass2 {

  @DomName('Geolocation.getCurrentPosition')
  Future<Geoposition> getCurrentPosition({bool enableHighAccuracy,
      Duration timeout, Duration maximumAge}) {
    var options = {};
    if (enableHighAccuracy != null) {
      options['enableHighAccuracy'] = enableHighAccuracy;
    }
    if (timeout != null) {
      options['timeout'] = timeout.inMilliseconds;
    }
    if (maximumAge != null) {
      options['maximumAge'] = maximumAge.inMilliseconds;
    }
    var completer = new Completer<Geoposition>();
    try {
      _getCurrentPosition(
          (position) {
            completer.complete(_ensurePosition(position));
          },
          (error) {
            completer.completeError(error);
          },
          options);
    } catch (e, stacktrace) {
      completer.completeError(e, stacktrace);
    }
    return completer.future;
  }

  @DomName('Geolocation.watchPosition')
  Stream<Geoposition> watchPosition({bool enableHighAccuracy,
      Duration timeout, Duration maximumAge}) {

    var options = {};
    if (enableHighAccuracy != null) {
      options['enableHighAccuracy'] = enableHighAccuracy;
    }
    if (timeout != null) {
      options['timeout'] = timeout.inMilliseconds;
    }
    if (maximumAge != null) {
      options['maximumAge'] = maximumAge.inMilliseconds;
    }

    int watchId;
    var controller;
    controller = new StreamController<Geoposition>(sync: true,
      onListen: () {
        assert(watchId == null);
        watchId = _watchPosition(
            (position) {
              controller.add(_ensurePosition(position));
            },
            (error) {
              controller.addError(error);
            },
            options);
      },
      onCancel: () {
        assert(watchId != null);
        _clearWatch(watchId);
      });

    return controller.stream;
  }

  Geoposition _ensurePosition(domPosition) {
    return domPosition;
  }

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

  @DomName('Geolocation.clearWatch')
  @DocsEditable()
  void _clearWatch(int watchID) => _blink.BlinkGeolocation.instance.clearWatch_Callback_1_(this, watchID);

  void _getCurrentPosition(_PositionCallback successCallback, [_PositionErrorCallback errorCallback, Map options]) {
    if (options != null) {
      _blink.BlinkGeolocation.instance.getCurrentPosition_Callback_3_(this, successCallback, errorCallback, options);
      return;
    }
    if (errorCallback != null) {
      _blink.BlinkGeolocation.instance.getCurrentPosition_Callback_2_(this, successCallback, errorCallback);
      return;
    }
    _blink.BlinkGeolocation.instance.getCurrentPosition_Callback_1_(this, successCallback);
    return;
  }

  int _watchPosition(_PositionCallback successCallback, [_PositionErrorCallback errorCallback, Map options]) {
    if (options != null) {
      return _blink.BlinkGeolocation.instance.watchPosition_Callback_3_(this, successCallback, errorCallback, options);
    }
    if (errorCallback != null) {
      return _blink.BlinkGeolocation.instance.watchPosition_Callback_2_(this, successCallback, errorCallback);
    }
    return _blink.BlinkGeolocation.instance.watchPosition_Callback_1_(this, successCallback);
  }
}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

  @DomName('Geoposition.coords')
  @DocsEditable()
  Coordinates get coords => _blink.BlinkGeoposition.instance.coords_Getter_(this);

  @DomName('Geoposition.timestamp')
  @DocsEditable()
  int get timestamp => _blink.BlinkGeoposition.instance.timestamp_Getter_(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('GlobalEventHandlers')
@Experimental() // untriaged
abstract class GlobalEventHandlers extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory GlobalEventHandlers._() { throw new UnsupportedError("Not supported"); }

  @DomName('GlobalEventHandlers.abortEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> abortEvent = const EventStreamProvider<Event>('abort');

  @DomName('GlobalEventHandlers.blurEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> blurEvent = const EventStreamProvider<Event>('blur');

  @DomName('GlobalEventHandlers.canplayEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> canPlayEvent = const EventStreamProvider<Event>('canplay');

  @DomName('GlobalEventHandlers.canplaythroughEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> canPlayThroughEvent = const EventStreamProvider<Event>('canplaythrough');

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

  @DomName('GlobalEventHandlers.clickEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> clickEvent = const EventStreamProvider<MouseEvent>('click');

  @DomName('GlobalEventHandlers.contextmenuEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> contextMenuEvent = const EventStreamProvider<MouseEvent>('contextmenu');

  @DomName('GlobalEventHandlers.dblclickEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> doubleClickEvent = const EventStreamProvider<Event>('dblclick');

  @DomName('GlobalEventHandlers.dragEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragEvent = const EventStreamProvider<MouseEvent>('drag');

  @DomName('GlobalEventHandlers.dragendEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragEndEvent = const EventStreamProvider<MouseEvent>('dragend');

  @DomName('GlobalEventHandlers.dragenterEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragEnterEvent = const EventStreamProvider<MouseEvent>('dragenter');

  @DomName('GlobalEventHandlers.dragleaveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragLeaveEvent = const EventStreamProvider<MouseEvent>('dragleave');

  @DomName('GlobalEventHandlers.dragoverEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragOverEvent = const EventStreamProvider<MouseEvent>('dragover');

  @DomName('GlobalEventHandlers.dragstartEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragStartEvent = const EventStreamProvider<MouseEvent>('dragstart');

  @DomName('GlobalEventHandlers.dropEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dropEvent = const EventStreamProvider<MouseEvent>('drop');

  @DomName('GlobalEventHandlers.durationchangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> durationChangeEvent = const EventStreamProvider<Event>('durationchange');

  @DomName('GlobalEventHandlers.emptiedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> emptiedEvent = const EventStreamProvider<Event>('emptied');

  @DomName('GlobalEventHandlers.endedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');

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

  @DomName('GlobalEventHandlers.focusEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> focusEvent = const EventStreamProvider<Event>('focus');

  @DomName('GlobalEventHandlers.inputEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> inputEvent = const EventStreamProvider<Event>('input');

  @DomName('GlobalEventHandlers.invalidEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> invalidEvent = const EventStreamProvider<Event>('invalid');

  @DomName('GlobalEventHandlers.keydownEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<KeyboardEvent> keyDownEvent = const EventStreamProvider<KeyboardEvent>('keydown');

  @DomName('GlobalEventHandlers.keypressEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<KeyboardEvent> keyPressEvent = const EventStreamProvider<KeyboardEvent>('keypress');

  @DomName('GlobalEventHandlers.keyupEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<KeyboardEvent> keyUpEvent = const EventStreamProvider<KeyboardEvent>('keyup');

  @DomName('GlobalEventHandlers.loadEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadEvent = const EventStreamProvider<Event>('load');

  @DomName('GlobalEventHandlers.loadeddataEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadedDataEvent = const EventStreamProvider<Event>('loadeddata');

  @DomName('GlobalEventHandlers.loadedmetadataEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadedMetadataEvent = const EventStreamProvider<Event>('loadedmetadata');

  @DomName('GlobalEventHandlers.mousedownEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseDownEvent = const EventStreamProvider<MouseEvent>('mousedown');

  @DomName('GlobalEventHandlers.mouseenterEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseEnterEvent = const EventStreamProvider<MouseEvent>('mouseenter');

  @DomName('GlobalEventHandlers.mouseleaveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseLeaveEvent = const EventStreamProvider<MouseEvent>('mouseleave');

  @DomName('GlobalEventHandlers.mousemoveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseMoveEvent = const EventStreamProvider<MouseEvent>('mousemove');

  @DomName('GlobalEventHandlers.mouseoutEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseOutEvent = const EventStreamProvider<MouseEvent>('mouseout');

  @DomName('GlobalEventHandlers.mouseoverEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseOverEvent = const EventStreamProvider<MouseEvent>('mouseover');

  @DomName('GlobalEventHandlers.mouseupEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseUpEvent = const EventStreamProvider<MouseEvent>('mouseup');

  @DomName('GlobalEventHandlers.mousewheelEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<WheelEvent> mouseWheelEvent = const EventStreamProvider<WheelEvent>('mousewheel');

  @DomName('GlobalEventHandlers.pauseEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> pauseEvent = const EventStreamProvider<Event>('pause');

  @DomName('GlobalEventHandlers.playEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> playEvent = const EventStreamProvider<Event>('play');

  @DomName('GlobalEventHandlers.playingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> playingEvent = const EventStreamProvider<Event>('playing');

  @DomName('GlobalEventHandlers.ratechangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> rateChangeEvent = const EventStreamProvider<Event>('ratechange');

  @DomName('GlobalEventHandlers.resetEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> resetEvent = const EventStreamProvider<Event>('reset');

  @DomName('GlobalEventHandlers.resizeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> resizeEvent = const EventStreamProvider<Event>('resize');

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

  @DomName('GlobalEventHandlers.seekedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> seekedEvent = const EventStreamProvider<Event>('seeked');

  @DomName('GlobalEventHandlers.seekingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> seekingEvent = const EventStreamProvider<Event>('seeking');

  @DomName('GlobalEventHandlers.selectEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> selectEvent = const EventStreamProvider<Event>('select');

  @DomName('GlobalEventHandlers.stalledEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> stalledEvent = const EventStreamProvider<Event>('stalled');

  @DomName('GlobalEventHandlers.submitEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> submitEvent = const EventStreamProvider<Event>('submit');

  @DomName('GlobalEventHandlers.suspendEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> suspendEvent = const EventStreamProvider<Event>('suspend');

  @DomName('GlobalEventHandlers.timeupdateEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> timeUpdateEvent = const EventStreamProvider<Event>('timeupdate');

  @DomName('GlobalEventHandlers.volumechangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> volumeChangeEvent = const EventStreamProvider<Event>('volumechange');

  @DomName('GlobalEventHandlers.waitingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> waitingEvent = const EventStreamProvider<Event>('waiting');

  @DomName('GlobalEventHandlers.onabort')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onAbort => abortEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onblur')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onBlur => blurEvent.forTarget(this);

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

  @DomName('GlobalEventHandlers.oncanplaythrough')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onCanPlayThrough => canPlayThroughEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onChange => changeEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onclick')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onClick => clickEvent.forTarget(this);

  @DomName('GlobalEventHandlers.oncontextmenu')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onContextMenu => contextMenuEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondblclick')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onDoubleClick => doubleClickEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondrag')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDrag => dragEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondragend')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDragEnd => dragEndEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondragenter')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDragEnter => dragEnterEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondragleave')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDragLeave => dragLeaveEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondragover')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDragOver => dragOverEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondragstart')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDragStart => dragStartEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondrop')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDrop => dropEvent.forTarget(this);

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

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

  @DomName('GlobalEventHandlers.onended')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onEnded => endedEvent.forTarget(this);

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

  @DomName('GlobalEventHandlers.onfocus')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onFocus => focusEvent.forTarget(this);

  @DomName('GlobalEventHandlers.oninput')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onInput => inputEvent.forTarget(this);

  @DomName('GlobalEventHandlers.oninvalid')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onInvalid => invalidEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onkeydown')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<KeyboardEvent> get onKeyDown => keyDownEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onkeypress')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<KeyboardEvent> get onKeyPress => keyPressEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onkeyup')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<KeyboardEvent> get onKeyUp => keyUpEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onload')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onLoad => loadEvent.forTarget(this);

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

  @DomName('GlobalEventHandlers.onloadedmetadata')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onLoadedMetadata => loadedMetadataEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmousedown')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseDown => mouseDownEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseEnter => mouseEnterEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseLeave => mouseLeaveEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmousemove')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseMove => mouseMoveEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmouseout')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseOut => mouseOutEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmouseover')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseOver => mouseOverEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmouseup')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseUp => mouseUpEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmousewheel')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<WheelEvent> get onMouseWheel => mouseWheelEvent.forTarget(this);

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

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

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

  @DomName('GlobalEventHandlers.onratechange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onRateChange => rateChangeEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onreset')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onReset => resetEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onResize => resizeEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onscroll')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onScroll => scrollEvent.forTarget(this);

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

  @DomName('GlobalEventHandlers.onseeking')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSeeking => seekingEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onselect')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSelect => selectEvent.forTarget(this);

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

  @DomName('GlobalEventHandlers.onsubmit')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSubmit => submitEvent.forTarget(this);

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

  @DomName('GlobalEventHandlers.ontimeupdate')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onTimeUpdate => timeUpdateEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onvolumechange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onVolumeChange => volumeChangeEvent.forTarget(this);

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

// WARNING: Do not edit - generated code.


@DocsEditable()
/**
 * An `<hr>` tag.
 */
@DomName('HTMLHRElement')
class HRElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory HRElement._() { throw new UnsupportedError("Not supported"); }

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

  @DomName('HTMLHRElement.color')
  @DocsEditable()
  @Experimental() // untriaged
  String get color => _blink.BlinkHTMLHRElement.instance.color_Getter_(this);

  @DomName('HTMLHRElement.color')
  @DocsEditable()
  @Experimental() // untriaged
  void set color(String value) => _blink.BlinkHTMLHRElement.instance.color_Setter_(this, value);

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

// WARNING: Do not edit - generated code.

@DomName('HashChangeEvent')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
class HashChangeEvent extends Event {
  factory HashChangeEvent(String type,
      {bool canBubble: true, bool cancelable: true, String oldUrl,
      String newUrl}) {
    var event = document._createEvent("HashChangeEvent");
    event._initHashChangeEvent(type, canBubble, cancelable, oldUrl, newUrl);
    return event;
  }
  // To suppress missing implicit constructor warnings.
  factory HashChangeEvent._() { throw new UnsupportedError("Not supported"); }

  /// Checks if this type is supported on the current platform.
  static bool get supported => true;

  @DomName('HashChangeEvent.newURL')
  @DocsEditable()
  String get newUrl => _blink.BlinkHashChangeEvent.instance.newURL_Getter_(this);

  @DomName('HashChangeEvent.oldURL')
  @DocsEditable()
  String get oldUrl => _blink.BlinkHashChangeEvent.instance.oldURL_Getter_(this);

  @DomName('HashChangeEvent.initHashChangeEvent')
  @DocsEditable()
  void _initHashChangeEvent(String type, bool canBubble, bool cancelable, String oldURL, String newURL) => _blink.BlinkHashChangeEvent.instance.initHashChangeEvent_Callback_5_(this, type, canBubble, cancelable, oldURL, newURL);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

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

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

// WARNING: Do not edit - generated code.


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

  @DomName('Headers.Headers')
  @DocsEditable()
  factory Headers([input]) {
    if (input == null) {
      return _blink.BlinkHeaders.instance.constructorCallback_0_();
    }
    if ((input is Headers || input == null)) {
      return _blink.BlinkHeaders.instance.constructorCallback_1_(input);
    }
    if ((input is Map || input == null)) {
      return _blink.BlinkHeaders.instance.constructorCallback_1_(input);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('Headers.size')
  @DocsEditable()
  @Experimental() // untriaged
  int get size => _blink.BlinkHeaders.instance.size_Getter_(this);

  void forEach(HeadersForEachCallback callback, [Object thisArg]) {
    if (thisArg != null) {
      _blink.BlinkHeaders.instance.forEach_Callback_2_(this, callback, thisArg);
      return;
    }
    _blink.BlinkHeaders.instance.forEach_Callback_1_(this, callback);
    return;
  }

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

// WARNING: Do not edit - generated code.


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

// WARNING: Do not edit - generated code.


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

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h1() => document.createElement("h1");

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h2() => document.createElement("h2");

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h3() => document.createElement("h3");

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h4() => document.createElement("h4");

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h5() => document.createElement("h5");

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

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


@DomName('History')
class History extends NativeFieldWrapperClass2 implements HistoryBase {

  /**
   * Checks if the State APIs are supported on the current platform.
   *
   * See also:
   *
   * * [pushState]
   * * [replaceState]
   * * [state]
   */
  static bool get supportsState => true;
  // To suppress missing implicit constructor warnings.
  factory History._() { throw new UnsupportedError("Not supported"); }

  @DomName('History.length')
  @DocsEditable()
  int get length => _blink.BlinkHistory.instance.length_Getter_(this);

  @DomName('History.state')
  @DocsEditable()
  dynamic get state => _blink.BlinkHistory.instance.state_Getter_(this);

  @DomName('History.back')
  @DocsEditable()
  void back() => _blink.BlinkHistory.instance.back_Callback_0_(this);

  @DomName('History.forward')
  @DocsEditable()
  void forward() => _blink.BlinkHistory.instance.forward_Callback_0_(this);

  @DomName('History.go')
  @DocsEditable()
  void go(int distance) => _blink.BlinkHistory.instance.go_Callback_1_(this, distance);

  @DomName('History.pushState')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void pushState(Object data, String title, [String url]) => _blink.BlinkHistory.instance.pushState_Callback_3_(this, data, title, url);

  @DomName('History.replaceState')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void replaceState(Object data, String title, [String url]) => _blink.BlinkHistory.instance.replaceState_Callback_3_(this, data, title, url);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('HTMLCollection')
class HtmlCollection extends NativeFieldWrapperClass2 with ListMixin<Node>, ImmutableListMixin<Node> implements List<Node> {
  // To suppress missing implicit constructor warnings.
  factory HtmlCollection._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLCollection.length')
  @DocsEditable()
  int get length => _blink.BlinkHTMLCollection.instance.length_Getter_(this);

  Node operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return _blink.BlinkHTMLCollection.instance.item_Callback_1_(this, index);
  }

  Node _nativeIndexedGetter(int index) => _blink.BlinkHTMLCollection.instance.item_Callback_1_(this, index);

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


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

  Node get first {
    if (this.length > 0) {
      return _nativeIndexedGetter(0);
    }
    throw new StateError("No elements");
  }

  Node get last {
    int len = this.length;
    if (len > 0) {
      return _nativeIndexedGetter(len - 1);
    }
    throw new StateError("No elements");
  }

  Node get single {
    int len = this.length;
    if (len == 1) {
      return _nativeIndexedGetter(0);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

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

  @DomName('HTMLCollection.item')
  @DocsEditable()
  Element item(int index) => _blink.BlinkHTMLCollection.instance.item_Callback_1_(this, index);

  @DomName('HTMLCollection.namedItem')
  @DocsEditable()
  Element namedItem(String name) => _blink.BlinkHTMLCollection.instance.namedItem_Callback_1_(this, 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('HTMLDocument')
class HtmlDocument extends Document {
  // To suppress missing implicit constructor warnings.
  factory HtmlDocument._() { throw new UnsupportedError("Not supported"); }


  @DomName('Document.body')
  BodyElement get body => _body;

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

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

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

  /**
   * Checks if the getCssCanvasContext API is supported on the current platform.
   *
   * See also:
   *
   * * [getCssCanvasContext]
   */
  static bool get supportsCssCanvasContext => true;


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

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

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

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

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

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

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

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

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

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

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

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

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

  @DomName('Document.visibilityState')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @Experimental()
  String get visibilityState => _webkitVisibilityState;

  @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}) {
    _Utils.register(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) {
    return 'webkitvisibilitychange';
  }

  @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 _VMElementUpgrader(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.

// WARNING: Do not edit - generated code.


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

  @DomName('HTMLElement.abortEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> abortEvent = const EventStreamProvider<Event>('abort');

  @DomName('HTMLElement.blurEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> blurEvent = const EventStreamProvider<Event>('blur');

  @DomName('HTMLElement.canplayEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> canPlayEvent = const EventStreamProvider<Event>('canplay');

  @DomName('HTMLElement.canplaythroughEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> canPlayThroughEvent = const EventStreamProvider<Event>('canplaythrough');

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

  @DomName('HTMLElement.clickEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> clickEvent = const EventStreamProvider<MouseEvent>('click');

  @DomName('HTMLElement.contextmenuEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> contextMenuEvent = const EventStreamProvider<MouseEvent>('contextmenu');

  @DomName('HTMLElement.dblclickEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> doubleClickEvent = const EventStreamProvider<Event>('dblclick');

  @DomName('HTMLElement.dragEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragEvent = const EventStreamProvider<MouseEvent>('drag');

  @DomName('HTMLElement.dragendEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragEndEvent = const EventStreamProvider<MouseEvent>('dragend');

  @DomName('HTMLElement.dragenterEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragEnterEvent = const EventStreamProvider<MouseEvent>('dragenter');

  @DomName('HTMLElement.dragleaveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragLeaveEvent = const EventStreamProvider<MouseEvent>('dragleave');

  @DomName('HTMLElement.dragoverEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragOverEvent = const EventStreamProvider<MouseEvent>('dragover');

  @DomName('HTMLElement.dragstartEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragStartEvent = const EventStreamProvider<MouseEvent>('dragstart');

  @DomName('HTMLElement.dropEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dropEvent = const EventStreamProvider<MouseEvent>('drop');

  @DomName('HTMLElement.durationchangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> durationChangeEvent = const EventStreamProvider<Event>('durationchange');

  @DomName('HTMLElement.emptiedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> emptiedEvent = const EventStreamProvider<Event>('emptied');

  @DomName('HTMLElement.endedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');

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

  @DomName('HTMLElement.focusEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> focusEvent = const EventStreamProvider<Event>('focus');

  @DomName('HTMLElement.inputEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> inputEvent = const EventStreamProvider<Event>('input');

  @DomName('HTMLElement.invalidEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> invalidEvent = const EventStreamProvider<Event>('invalid');

  @DomName('HTMLElement.keydownEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<KeyboardEvent> keyDownEvent = const EventStreamProvider<KeyboardEvent>('keydown');

  @DomName('HTMLElement.keypressEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<KeyboardEvent> keyPressEvent = const EventStreamProvider<KeyboardEvent>('keypress');

  @DomName('HTMLElement.keyupEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<KeyboardEvent> keyUpEvent = const EventStreamProvider<KeyboardEvent>('keyup');

  @DomName('HTMLElement.loadEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadEvent = const EventStreamProvider<Event>('load');

  @DomName('HTMLElement.loadeddataEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadedDataEvent = const EventStreamProvider<Event>('loadeddata');

  @DomName('HTMLElement.loadedmetadataEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadedMetadataEvent = const EventStreamProvider<Event>('loadedmetadata');

  @DomName('HTMLElement.mousedownEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseDownEvent = const EventStreamProvider<MouseEvent>('mousedown');

  @DomName('HTMLElement.mouseenterEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseEnterEvent = const EventStreamProvider<MouseEvent>('mouseenter');

  @DomName('HTMLElement.mouseleaveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseLeaveEvent = const EventStreamProvider<MouseEvent>('mouseleave');

  @DomName('HTMLElement.mousemoveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseMoveEvent = const EventStreamProvider<MouseEvent>('mousemove');

  @DomName('HTMLElement.mouseoutEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseOutEvent = const EventStreamProvider<MouseEvent>('mouseout');

  @DomName('HTMLElement.mouseoverEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseOverEvent = const EventStreamProvider<MouseEvent>('mouseover');

  @DomName('HTMLElement.mouseupEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseUpEvent = const EventStreamProvider<MouseEvent>('mouseup');

  @DomName('HTMLElement.mousewheelEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<WheelEvent> mouseWheelEvent = const EventStreamProvider<WheelEvent>('mousewheel');

  @DomName('HTMLElement.pauseEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> pauseEvent = const EventStreamProvider<Event>('pause');

  @DomName('HTMLElement.playEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> playEvent = const EventStreamProvider<Event>('play');

  @DomName('HTMLElement.playingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> playingEvent = const EventStreamProvider<Event>('playing');

  @DomName('HTMLElement.ratechangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> rateChangeEvent = const EventStreamProvider<Event>('ratechange');

  @DomName('HTMLElement.resetEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> resetEvent = const EventStreamProvider<Event>('reset');

  @DomName('HTMLElement.resizeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> resizeEvent = const EventStreamProvider<Event>('resize');

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

  @DomName('HTMLElement.seekedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> seekedEvent = const EventStreamProvider<Event>('seeked');

  @DomName('HTMLElement.seekingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> seekingEvent = const EventStreamProvider<Event>('seeking');

  @DomName('HTMLElement.selectEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> selectEvent = const EventStreamProvider<Event>('select');

  @DomName('HTMLElement.stalledEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> stalledEvent = const EventStreamProvider<Event>('stalled');

  @DomName('HTMLElement.submitEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> submitEvent = const EventStreamProvider<Event>('submit');

  @DomName('HTMLElement.suspendEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> suspendEvent = const EventStreamProvider<Event>('suspend');

  @DomName('HTMLElement.timeupdateEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> timeUpdateEvent = const EventStreamProvider<Event>('timeupdate');

  @DomName('HTMLElement.volumechangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> volumeChangeEvent = const EventStreamProvider<Event>('volumechange');

  @DomName('HTMLElement.waitingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> waitingEvent = const EventStreamProvider<Event>('waiting');
  /**
   * 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();

  @DomName('HTMLElement.contentEditable')
  @DocsEditable()
  String get contentEditable => _blink.BlinkHTMLElement.instance.contentEditable_Getter_(this);

  @DomName('HTMLElement.contentEditable')
  @DocsEditable()
  void set contentEditable(String value) => _blink.BlinkHTMLElement.instance.contentEditable_Setter_(this, value);

  @DomName('HTMLElement.dir')
  @DocsEditable()
  String get dir => _blink.BlinkHTMLElement.instance.dir_Getter_(this);

  @DomName('HTMLElement.dir')
  @DocsEditable()
  void set dir(String value) => _blink.BlinkHTMLElement.instance.dir_Setter_(this, value);

  @DomName('HTMLElement.draggable')
  @DocsEditable()
  bool get draggable => _blink.BlinkHTMLElement.instance.draggable_Getter_(this);

  @DomName('HTMLElement.draggable')
  @DocsEditable()
  void set draggable(bool value) => _blink.BlinkHTMLElement.instance.draggable_Setter_(this, value);

  @DomName('HTMLElement.hidden')
  @DocsEditable()
  bool get hidden => _blink.BlinkHTMLElement.instance.hidden_Getter_(this);

  @DomName('HTMLElement.hidden')
  @DocsEditable()
  void set hidden(bool value) => _blink.BlinkHTMLElement.instance.hidden_Setter_(this, value);

  @DomName('HTMLElement.inputMethodContext')
  @DocsEditable()
  @Experimental() // untriaged
  InputMethodContext get inputMethodContext => _blink.BlinkHTMLElement.instance.inputMethodContext_Getter_(this);

  @DomName('HTMLElement.isContentEditable')
  @DocsEditable()
  bool get isContentEditable => _blink.BlinkHTMLElement.instance.isContentEditable_Getter_(this);

  @DomName('HTMLElement.lang')
  @DocsEditable()
  String get lang => _blink.BlinkHTMLElement.instance.lang_Getter_(this);

  @DomName('HTMLElement.lang')
  @DocsEditable()
  void set lang(String value) => _blink.BlinkHTMLElement.instance.lang_Setter_(this, value);

  @DomName('HTMLElement.spellcheck')
  @DocsEditable()
  // http://blog.whatwg.org/the-road-to-html-5-spellchecking
  @Experimental() // nonstandard
  bool get spellcheck => _blink.BlinkHTMLElement.instance.spellcheck_Getter_(this);

  @DomName('HTMLElement.spellcheck')
  @DocsEditable()
  // http://blog.whatwg.org/the-road-to-html-5-spellchecking
  @Experimental() // nonstandard
  void set spellcheck(bool value) => _blink.BlinkHTMLElement.instance.spellcheck_Setter_(this, value);

  @DomName('HTMLElement.tabIndex')
  @DocsEditable()
  int get tabIndex => _blink.BlinkHTMLElement.instance.tabIndex_Getter_(this);

  @DomName('HTMLElement.tabIndex')
  @DocsEditable()
  void set tabIndex(int value) => _blink.BlinkHTMLElement.instance.tabIndex_Setter_(this, value);

  @DomName('HTMLElement.title')
  @DocsEditable()
  String get title => _blink.BlinkHTMLElement.instance.title_Getter_(this);

  @DomName('HTMLElement.title')
  @DocsEditable()
  void set title(String value) => _blink.BlinkHTMLElement.instance.title_Setter_(this, value);

  @DomName('HTMLElement.translate')
  @DocsEditable()
  bool get translate => _blink.BlinkHTMLElement.instance.translate_Getter_(this);

  @DomName('HTMLElement.translate')
  @DocsEditable()
  void set translate(bool value) => _blink.BlinkHTMLElement.instance.translate_Setter_(this, value);

  @DomName('HTMLElement.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 get dropzone => _blink.BlinkHTMLElement.instance.webkitdropzone_Getter_(this);

  @DomName('HTMLElement.webkitdropzone')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#the-dropzone-attribute
  void set dropzone(String value) => _blink.BlinkHTMLElement.instance.webkitdropzone_Setter_(this, value);

  @DomName('HTMLElement.click')
  @DocsEditable()
  void click() => _blink.BlinkHTMLElement.instance.click_Callback_0_(this);

  @DomName('HTMLElement.onabort')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onAbort => abortEvent.forElement(this);

  @DomName('HTMLElement.onblur')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onBlur => blurEvent.forElement(this);

  @DomName('HTMLElement.oncanplay')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onCanPlay => canPlayEvent.forElement(this);

  @DomName('HTMLElement.oncanplaythrough')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onCanPlayThrough => canPlayThroughEvent.forElement(this);

  @DomName('HTMLElement.onchange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onChange => changeEvent.forElement(this);

  @DomName('HTMLElement.onclick')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onClick => clickEvent.forElement(this);

  @DomName('HTMLElement.oncontextmenu')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onContextMenu => contextMenuEvent.forElement(this);

  @DomName('HTMLElement.ondblclick')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onDoubleClick => doubleClickEvent.forElement(this);

  @DomName('HTMLElement.ondrag')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onDrag => dragEvent.forElement(this);

  @DomName('HTMLElement.ondragend')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onDragEnd => dragEndEvent.forElement(this);

  @DomName('HTMLElement.ondragenter')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onDragEnter => dragEnterEvent.forElement(this);

  @DomName('HTMLElement.ondragleave')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onDragLeave => dragLeaveEvent.forElement(this);

  @DomName('HTMLElement.ondragover')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onDragOver => dragOverEvent.forElement(this);

  @DomName('HTMLElement.ondragstart')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onDragStart => dragStartEvent.forElement(this);

  @DomName('HTMLElement.ondrop')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onDrop => dropEvent.forElement(this);

  @DomName('HTMLElement.ondurationchange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onDurationChange => durationChangeEvent.forElement(this);

  @DomName('HTMLElement.onemptied')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEmptied => emptiedEvent.forElement(this);

  @DomName('HTMLElement.onended')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEnded => endedEvent.forElement(this);

  @DomName('HTMLElement.onerror')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onError => errorEvent.forElement(this);

  @DomName('HTMLElement.onfocus')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onFocus => focusEvent.forElement(this);

  @DomName('HTMLElement.oninput')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onInput => inputEvent.forElement(this);

  @DomName('HTMLElement.oninvalid')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onInvalid => invalidEvent.forElement(this);

  @DomName('HTMLElement.onkeydown')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<KeyboardEvent> get onKeyDown => keyDownEvent.forElement(this);

  @DomName('HTMLElement.onkeypress')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<KeyboardEvent> get onKeyPress => keyPressEvent.forElement(this);

  @DomName('HTMLElement.onkeyup')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<KeyboardEvent> get onKeyUp => keyUpEvent.forElement(this);

  @DomName('HTMLElement.onload')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoad => loadEvent.forElement(this);

  @DomName('HTMLElement.onloadeddata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedData => loadedDataEvent.forElement(this);

  @DomName('HTMLElement.onloadedmetadata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedMetadata => loadedMetadataEvent.forElement(this);

  @DomName('HTMLElement.onmousedown')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseDown => mouseDownEvent.forElement(this);

  @DomName('HTMLElement.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseEnter => mouseEnterEvent.forElement(this);

  @DomName('HTMLElement.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseLeave => mouseLeaveEvent.forElement(this);

  @DomName('HTMLElement.onmousemove')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseMove => mouseMoveEvent.forElement(this);

  @DomName('HTMLElement.onmouseout')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseOut => mouseOutEvent.forElement(this);

  @DomName('HTMLElement.onmouseover')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseOver => mouseOverEvent.forElement(this);

  @DomName('HTMLElement.onmouseup')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseUp => mouseUpEvent.forElement(this);

  @DomName('HTMLElement.onmousewheel')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<WheelEvent> get onMouseWheel => mouseWheelEvent.forElement(this);

  @DomName('HTMLElement.onpause')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPause => pauseEvent.forElement(this);

  @DomName('HTMLElement.onplay')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPlay => playEvent.forElement(this);

  @DomName('HTMLElement.onplaying')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPlaying => playingEvent.forElement(this);

  @DomName('HTMLElement.onratechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onRateChange => rateChangeEvent.forElement(this);

  @DomName('HTMLElement.onreset')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onReset => resetEvent.forElement(this);

  @DomName('HTMLElement.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onResize => resizeEvent.forElement(this);

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

  @DomName('HTMLElement.onseeked')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeked => seekedEvent.forElement(this);

  @DomName('HTMLElement.onseeking')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeking => seekingEvent.forElement(this);

  @DomName('HTMLElement.onselect')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSelect => selectEvent.forElement(this);

  @DomName('HTMLElement.onstalled')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onStalled => stalledEvent.forElement(this);

  @DomName('HTMLElement.onsubmit')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSubmit => submitEvent.forElement(this);

  @DomName('HTMLElement.onsuspend')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSuspend => suspendEvent.forElement(this);

  @DomName('HTMLElement.ontimeupdate')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onTimeUpdate => timeUpdateEvent.forElement(this);

  @DomName('HTMLElement.onvolumechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onVolumeChange => volumeChangeEvent.forElement(this);

  @DomName('HTMLElement.onwaiting')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onWaiting => waitingEvent.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.

// WARNING: Do not edit - generated code.


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

  @DomName('HTMLFormControlsCollection.namedItem')
  @DocsEditable()
  Object namedItem(String name) => _blink.BlinkHTMLFormControlsCollection.instance.namedItem_Callback_1_(this, 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.


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

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

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

// WARNING: Do not edit - generated code.


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

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


 /**
  * A client-side XHR request for getting data from a URL,
  * formally known as XMLHttpRequest.
  *
  * HttpRequest can be used to obtain data from HTTP and FTP protocols,
  * and is useful for AJAX-style page updates.
  *
  * The simplest way to get the contents of a text file, such as a
  * JSON-formatted file, is with [getString].
  * For example, the following code gets the contents of a JSON file
  * and prints its length:
  *
  *     var path = 'myData.json';
  *     HttpRequest.getString(path)
  *         .then((String fileContents) {
  *           print(fileContents.length);
  *         })
  *         .catchError((Error error) {
  *           print(error.toString());
  *         });
  *
  * ## Fetching data from other servers
  *
  * For security reasons, browsers impose restrictions on requests
  * made by embedded apps.
  * With the default behavior of this class,
  * the code making the request must be served from the same origin
  * (domain name, port, and application layer protocol)
  * as the requested resource.
  * In the example above, the myData.json file must be co-located with the
  * app that uses it.
  * You might be able to
  * [get around this restriction](http://www.dartlang.org/articles/json-web-service/#a-note-on-cors-and-httprequest)
  * by using CORS headers or JSONP.
  *
  * ## Other resources
  *
  * * [Fetch Data Dynamically](https://www.dartlang.org/docs/tutorials/fetchdata/),
  * a tutorial from _A Game of Darts_,
  * shows two different ways to use HttpRequest to get a JSON file.
  * * [Get Input from a Form](https://www.dartlang.org/docs/tutorials/forms/),
  * another tutorial from _A Game of Darts_,
  * shows using HttpRequest with a custom server.
  * * [Dart article on using HttpRequests](http://www.dartlang.org/articles/json-web-service/#getting-data)
  * * [JS XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest)
  * * [Using XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest)
 */
@DomName('XMLHttpRequest')
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((xhr) => xhr.responseText);
  }

  /**
   * Makes a server POST request with the specified data encoded as form data.
   *
   * This is roughly the POST equivalent of getString. This method is similar
   * to sending a FormData object with broader browser support but limited to
   * String values.
   *
   * If [data] is supplied, the key/value pairs are URI encoded with
   * [Uri.encodeQueryComponent] and converted into an HTTP query string.
   *
   * Unless otherwise specified, this method appends the following header:
   *
   *     Content-Type: application/x-www-form-urlencoded; charset=UTF-8
   *
   * Here's an example of using this method:
   *
   *     var data = { 'firstName' : 'John', 'lastName' : 'Doe' };
   *     HttpRequest.postFormData('/send', data).then((HttpRequest resp) {
   *       // Do something with the response.
   *     });
   *
   * See also:
   *
   * * [request]
   */
  static Future<HttpRequest> postFormData(String url, Map<String, String> data,
      {bool withCredentials, String responseType,
      Map<String, String> requestHeaders,
      void onProgress(ProgressEvent e)}) {

    var parts = [];
    data.forEach((key, value) {
      parts.add('${Uri.encodeQueryComponent(key)}='
          '${Uri.encodeQueryComponent(value)}');
    });
    var formData = parts.join('&');

    if (requestHeaders == null) {
      requestHeaders = <String, String>{};
    }
    requestHeaders.putIfAbsent('Content-Type',
        () => 'application/x-www-form-urlencoded; charset=UTF-8');

    return request(url, method: 'POST', withCredentials: withCredentials,
        responseType: responseType,
        requestHeaders: requestHeaders, sendData: formData,
        onProgress: onProgress);
  }

  /**
   * Creates and sends a URL request for the specified [url].
   *
   * By default `request` will perform an HTTP GET request, but a different
   * method (`POST`, `PUT`, `DELETE`, etc) can be used by specifying the
   * [method] parameter. (See also [HttpRequest.postFormData] for `POST` 
   * requests only.
   *
   * The Future is completed when the response is available.
   *
   * If specified, `sendData` will send data in the form of a [ByteBuffer],
   * [Blob], [Document], [String], or [FormData] along with the HttpRequest.
   *
   * If specified, [responseType] sets the desired response format for the
   * request. By default it is [String], but can also be 'arraybuffer', 'blob', 
   * 'document', 'json', or 'text'. See also [HttpRequest.responseType] 
   * for more information.
   *
   * The [withCredentials] parameter specified that credentials such as a cookie
   * (already) set in the header or
   * [authorization headers](http://tools.ietf.org/html/rfc1945#section-10.2)
   * should be specified for the request. Details to keep in mind when using
   * credentials:
   *
   * * Using credentials is only useful for cross-origin requests.
   * * The `Access-Control-Allow-Origin` header of `url` cannot contain a wildcard (*).
   * * The `Access-Control-Allow-Credentials` header of `url` must be set to true.
   * * If `Access-Control-Expose-Headers` has not been set to true, only a subset of all the response headers will be returned when calling [getAllRequestHeaders].
   *
   * The following is equivalent to the [getString] sample above:
   *
   *     var name = Uri.encodeQueryComponent('John');
   *     var id = Uri.encodeQueryComponent('42');
   *     HttpRequest.request('users.json?name=$name&id=$id')
   *       .then((HttpRequest resp) {
   *         // Do something with the response.
   *     });
   *
   * Here's an example of submitting an entire form with [FormData].
   *
   *     var myForm = querySelector('form#myForm');
   *     var data = new FormData(myForm);
   *     HttpRequest.request('/submit', method: 'POST', sendData: data)
   *       .then((HttpRequest resp) {
   *         // Do something with the response.
   *     });
   *
   * Note that requests for file:// URIs are only supported by Chrome extensions
   * with appropriate permissions in their manifest. Requests to file:// URIs
   * will also never fail- the Future will always complete successfully, even
   * when the file cannot be found.
   *
   * See also: [authorization headers](http://en.wikipedia.org/wiki/Basic_access_authentication).
   */
  static Future<HttpRequest> request(String url,
      {String method, bool withCredentials, String responseType,
      String mimeType, Map<String, String> requestHeaders, sendData,
      void onProgress(ProgressEvent e)}) {
    var completer = new Completer<HttpRequest>();

    var xhr = new HttpRequest();
    if (method == null) {
      method = 'GET';
    }
    xhr.open(method, url, async: true);

    if (withCredentials != null) {
      xhr.withCredentials = withCredentials;
    }

    if (responseType != null) {
      xhr.responseType = responseType;
    }

    if (mimeType != null) {
      xhr.overrideMimeType(mimeType);
    }

    if (requestHeaders != null) {
      requestHeaders.forEach((header, value) {
        xhr.setRequestHeader(header, value);
      });
    }

    if (onProgress != null) {
      xhr.onProgress.listen(onProgress);
    }

    xhr.onLoad.listen((e) {
      // Note: file:// URIs have status of 0.
      if ((xhr.status >= 200 && xhr.status < 300) ||
          xhr.status == 0 || xhr.status == 304) {
        completer.complete(xhr);
      } else {
        completer.completeError(e);
      }
    });

    xhr.onError.listen(completer.completeError);

    if (sendData != null) {
      xhr.send(sendData);
    } else {
      xhr.send();
    }

    return completer.future;
  }

  /**
   * Checks to see if the Progress event is supported on the current platform.
   */
  static bool get supportsProgressEvent {
    return true;
  }

  /**
   * 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 {
    return true;
  }

  /**
   * Checks to see if the LoadEnd event is supported on the current platform.
   */
  static bool get supportsLoadEndEvent {
    return true;
  }

  /**
   * Checks to see if the overrideMimeType method is supported on the current
   * platform.
   */
  static bool get supportsOverrideMimeType {
    return true;
  }

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

  /**
   * Returns all response headers as a key-value map.
   *
   * Multiple values for the same header key can be combined into one,
   * separated by a comma and a space.
   *
   * See: http://www.w3.org/TR/XMLHttpRequest/#the-getresponseheader()-method
   */
  Map<String, String> get responseHeaders {
    // from Closure's goog.net.Xhrio.getResponseHeaders.
    var headers = <String, String>{};
    var headersString = this.getAllResponseHeaders();
    if (headersString == null) {
      return headers;
    }
    var headersList = headersString.split('\r\n');
    for (var header in headersList) {
      if (header.isEmpty) {
        continue;
      }

      var splitIdx = header.indexOf(': ');
      if (splitIdx == -1) {
        continue;
      }
      var key = header.substring(0, splitIdx).toLowerCase();
      var value = header.substring(splitIdx + 2);
      if (headers.containsKey(key)) {
        headers[key] = '${headers[key]}, $value';
      } else {
        headers[key] = value;
      }
    }
    return headers;
  }

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

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

  /**
   * General constructor for any type of request (GET, POST, etc).
   *
   * This call is used in conjunction with [open]:
   *
   *     var request = new HttpRequest();
   *     request.open('GET', 'http://dartlang.org');
   *     request.onLoad.listen((event) => print(
   *         'Request complete ${event.target.reponseText}'));
   *     request.send();
   *
   * is the (more verbose) equivalent of
   *
   *     HttpRequest.getString('http://dartlang.org').then(
   *         (result) => print('Request complete: $result'));
   */
  @DomName('XMLHttpRequest.XMLHttpRequest')
  @DocsEditable()
  factory HttpRequest() => _create();

  @DocsEditable()
  static HttpRequest _create() => _blink.BlinkXMLHttpRequest.instance.constructorCallback_0_();

  @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()
  int get readyState => _blink.BlinkXMLHttpRequest.instance.readyState_Getter_(this);

  /**
   * 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)
  Object get response => _blink.BlinkXMLHttpRequest.instance.response_Getter_(this);

  /**
   * The response in String form or empty String on failure.
   */
  @DomName('XMLHttpRequest.responseText')
  @DocsEditable()
  String get responseText => _blink.BlinkXMLHttpRequest.instance.responseText_Getter_(this);

  /**
   * [String] telling the server the desired response format.
   *
   * Default is `String`.
   * Other options are one of 'arraybuffer', 'blob', 'document', 'json',
   * 'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if
   * `responseType` is set while performing a synchronous request.
   *
   * See also: [MDN responseType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType)
   */
  @DomName('XMLHttpRequest.responseType')
  @DocsEditable()
  String get responseType => _blink.BlinkXMLHttpRequest.instance.responseType_Getter_(this);

  /**
   * [String] telling the server the desired response format.
   *
   * Default is `String`.
   * Other options are one of 'arraybuffer', 'blob', 'document', 'json',
   * 'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if
   * `responseType` is set while performing a synchronous request.
   *
   * See also: [MDN responseType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType)
   */
  @DomName('XMLHttpRequest.responseType')
  @DocsEditable()
  void set responseType(String value) => _blink.BlinkXMLHttpRequest.instance.responseType_Setter_(this, value);

  @DomName('XMLHttpRequest.responseURL')
  @DocsEditable()
  @Experimental() // untriaged
  String get responseUrl => _blink.BlinkXMLHttpRequest.instance.responseURL_Getter_(this);

  /**
   * 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()
  Document get responseXml => _blink.BlinkXMLHttpRequest.instance.responseXML_Getter_(this);

  /**
   * 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()
  int get status => _blink.BlinkXMLHttpRequest.instance.status_Getter_(this);

  /**
   * 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()
  String get statusText => _blink.BlinkXMLHttpRequest.instance.statusText_Getter_(this);

  /**
   * Length of time before a request is automatically terminated.
   *
   * When the time has passed, a [TimeoutEvent] is dispatched.
   *
   * If [timeout] is set to 0, then the request will not time out.
   *
   * ## Other resources
   *
   * * [XMLHttpRequest.timeout]
   * (https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#timeout)
   * from MDN.
   * * [The timeout attribute]
   * (http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute)
   * from W3C.
   */
  @DomName('XMLHttpRequest.timeout')
  @DocsEditable()
  @Experimental() // untriaged
  int get timeout => _blink.BlinkXMLHttpRequest.instance.timeout_Getter_(this);

  /**
   * Length of time before a request is automatically terminated.
   *
   * When the time has passed, a [TimeoutEvent] is dispatched.
   *
   * If [timeout] is set to 0, then the request will not time out.
   *
   * ## Other resources
   *
   * * [XMLHttpRequest.timeout]
   * (https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#timeout)
   * from MDN.
   * * [The timeout attribute]
   * (http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute)
   * from W3C.
   */
  @DomName('XMLHttpRequest.timeout')
  @DocsEditable()
  @Experimental() // untriaged
  void set timeout(int value) => _blink.BlinkXMLHttpRequest.instance.timeout_Setter_(this, value);

  /**
   * [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()
  HttpRequestUpload get upload => _blink.BlinkXMLHttpRequest.instance.upload_Getter_(this);

  /**
   * 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 get withCredentials => _blink.BlinkXMLHttpRequest.instance.withCredentials_Getter_(this);

  /**
   * 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()
  void set withCredentials(bool value) => _blink.BlinkXMLHttpRequest.instance.withCredentials_Setter_(this, value);

  /**
   * Stop the current request.
   *
   * The request can only be stopped if readyState is `HEADERS_RECIEVED` or
   * `LOADING`. If this method is not in the process of being sent, the method
   * has no effect.
   */
  @DomName('XMLHttpRequest.abort')
  @DocsEditable()
  void abort() => _blink.BlinkXMLHttpRequest.instance.abort_Callback_0_(this);

  /**
   * Retrieve all the response headers from a request.
   *
   * `null` if no headers have been received. For multipart requests,
   * `getAllResponseHeaders` will return the response headers for the current
   * part of the request.
   *
   * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)
   * for a list of common response headers.
   */
  @DomName('XMLHttpRequest.getAllResponseHeaders')
  @DocsEditable()
  @Unstable()
  String getAllResponseHeaders() => _blink.BlinkXMLHttpRequest.instance.getAllResponseHeaders_Callback_0_(this);

  /**
   * Return the response header named `header`, or null if not found.
   *
   * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)
   * for a list of common response headers.
   */
  @DomName('XMLHttpRequest.getResponseHeader')
  @DocsEditable()
  @Unstable()
  String getResponseHeader(String header) => _blink.BlinkXMLHttpRequest.instance.getResponseHeader_Callback_1_(this, header);

  /**
   * Specify the desired `url`, and `method` to use in making the request.
   *
   * By default the request is done asyncronously, with no user or password
   * authentication information. If `async` is false, the request will be send
   * synchronously.
   *
   * Calling `open` again on a currently active request is equivalent to
   * calling `abort`.
   *
   * Note: Most simple HTTP requests can be accomplished using the [getString],
   * [request], [requestCrossOrigin], or [postFormData] methods. Use of this
   * `open` method is intended only for more complext HTTP requests where
   * finer-grained control is needed.
   */
  @DomName('XMLHttpRequest.open')
  @DocsEditable()
  void open(String method, String url, {bool async, String user, String password}) => _blink.BlinkXMLHttpRequest.instance.open_Callback_5_(this, method, url, async, user, password);

  /**
   * Specify a particular MIME type (such as `text/xml`) desired for the
   * response.
   *
   * This value must be set before the request has been sent. See also the list
   * of [common MIME types](http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types)
   */
  @DomName('XMLHttpRequest.overrideMimeType')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void overrideMimeType(String override) => _blink.BlinkXMLHttpRequest.instance.overrideMimeType_Callback_1_(this, override);

  /**
   * Send the request with any given `data`.
   *
   * Note: Most simple HTTP requests can be accomplished using the [getString],
   * [request], [requestCrossOrigin], or [postFormData] methods. Use of this
   * `send` method is intended only for more complext HTTP requests where
   * finer-grained control is needed.
   *
   * ## Other resources
   *
   * * [XMLHttpRequest.send]
   * (https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
   * from MDN.
   */
  @DomName('XMLHttpRequest.send')
  @DocsEditable()
  void send([data]) => _blink.BlinkXMLHttpRequest.instance.send_Callback_1_(this, data);

  /**
   * Sets the value of an HTTP requst header.
   *
   * This method should be called after the request is opened, but before
   * the request is sent.
   *
   * Multiple calls with the same header will combine all their values into a
   * single header.
   *
   * ## Other resources
   *
   * * [XMLHttpRequest.setRequestHeader]
   * (https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
   * from MDN.
   * * [The setRequestHeader() method]
   * (http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method) from
   * W3C.
   */
  @DomName('XMLHttpRequest.setRequestHeader')
  @DocsEditable()
  void setRequestHeader(String header, String value) => _blink.BlinkXMLHttpRequest.instance.setRequestHeader_Callback_2_(this, header, value);

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

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('XMLHttpRequestEventTarget')
@Experimental() // untriaged
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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('XMLHttpRequestUpload')
// http://xhr.spec.whatwg.org/#xmlhttprequestupload
@Experimental()
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.

// WARNING: Do not edit - generated code.


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

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

  @DomName('HTMLIFrameElement.allowFullscreen')
  @DocsEditable()
  @Experimental() // untriaged
  bool get allowFullscreen => _blink.BlinkHTMLIFrameElement.instance.allowFullscreen_Getter_(this);

  @DomName('HTMLIFrameElement.allowFullscreen')
  @DocsEditable()
  @Experimental() // untriaged
  void set allowFullscreen(bool value) => _blink.BlinkHTMLIFrameElement.instance.allowFullscreen_Setter_(this, value);

  @DomName('HTMLIFrameElement.contentWindow')
  @DocsEditable()
  WindowBase get contentWindow => _blink.BlinkHTMLIFrameElement.instance.contentWindow_Getter_(this);

  @DomName('HTMLIFrameElement.height')
  @DocsEditable()
  String get height => _blink.BlinkHTMLIFrameElement.instance.height_Getter_(this);

  @DomName('HTMLIFrameElement.height')
  @DocsEditable()
  void set height(String value) => _blink.BlinkHTMLIFrameElement.instance.height_Setter_(this, value);

  @DomName('HTMLIFrameElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String get integrity => _blink.BlinkHTMLIFrameElement.instance.integrity_Getter_(this);

  @DomName('HTMLIFrameElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  void set integrity(String value) => _blink.BlinkHTMLIFrameElement.instance.integrity_Setter_(this, value);

  @DomName('HTMLIFrameElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLIFrameElement.instance.name_Getter_(this);

  @DomName('HTMLIFrameElement.name')
  @DocsEditable()
  void set name(String value) => _blink.BlinkHTMLIFrameElement.instance.name_Setter_(this, value);

  @DomName('HTMLIFrameElement.sandbox')
  @DocsEditable()
  String get sandbox => _blink.BlinkHTMLIFrameElement.instance.sandbox_Getter_(this);

  @DomName('HTMLIFrameElement.sandbox')
  @DocsEditable()
  void set sandbox(String value) => _blink.BlinkHTMLIFrameElement.instance.sandbox_Setter_(this, value);

  @DomName('HTMLIFrameElement.src')
  @DocsEditable()
  String get src => _blink.BlinkHTMLIFrameElement.instance.src_Getter_(this);

  @DomName('HTMLIFrameElement.src')
  @DocsEditable()
  void set src(String value) => _blink.BlinkHTMLIFrameElement.instance.src_Setter_(this, value);

  @DomName('HTMLIFrameElement.srcdoc')
  @DocsEditable()
  String get srcdoc => _blink.BlinkHTMLIFrameElement.instance.srcdoc_Getter_(this);

  @DomName('HTMLIFrameElement.srcdoc')
  @DocsEditable()
  void set srcdoc(String value) => _blink.BlinkHTMLIFrameElement.instance.srcdoc_Setter_(this, value);

  @DomName('HTMLIFrameElement.width')
  @DocsEditable()
  String get width => _blink.BlinkHTMLIFrameElement.instance.width_Getter_(this);

  @DomName('HTMLIFrameElement.width')
  @DocsEditable()
  void set width(String value) => _blink.BlinkHTMLIFrameElement.instance.width_Setter_(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.

// WARNING: Do not edit - generated code.


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

  @DomName('ImageBitmap.height')
  @DocsEditable()
  @Experimental() // untriaged
  int get height => _blink.BlinkImageBitmap.instance.height_Getter_(this);

  @DomName('ImageBitmap.width')
  @DocsEditable()
  @Experimental() // untriaged
  int get width => _blink.BlinkImageBitmap.instance.width_Getter_(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('ImageData')
class ImageData extends NativeFieldWrapperClass2 {
  List<int> __data;

  List<int> get data {
    if (__data == null) {
      __data = _data;
    }
    return __data;
  }

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

  @DomName('ImageData.ImageData')
  @DocsEditable()
  factory ImageData(data_OR_width, int height_OR_width, [int height]) {
    if ((height_OR_width is int || height_OR_width == null) && (data_OR_width is int || data_OR_width == null) && height == null) {
      return _blink.BlinkImageData.instance.constructorCallback_2_(data_OR_width, height_OR_width);
    }
    if ((height is int || height == null) && (height_OR_width is int || height_OR_width == null) && (data_OR_width is Uint8ClampedList || data_OR_width == null)) {
      return _blink.BlinkImageData.instance.constructorCallback_3_(data_OR_width, height_OR_width, height);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('ImageData.data')
  @DocsEditable()
  Uint8ClampedList get _data => _blink.BlinkImageData.instance.data_Getter_(this);

  @DomName('ImageData.height')
  @DocsEditable()
  int get height => _blink.BlinkImageData.instance.height_Getter_(this);

  @DomName('ImageData.width')
  @DocsEditable()
  int get width => _blink.BlinkImageData.instance.width_Getter_(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('HTMLImageElement')
class ImageElement extends HtmlElement implements CanvasImageSource {
  // To suppress missing implicit constructor warnings.
  factory ImageElement._() { throw new UnsupportedError("Not supported"); }

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

  @DomName('HTMLImageElement.alt')
  @DocsEditable()
  String get alt => _blink.BlinkHTMLImageElement.instance.alt_Getter_(this);

  @DomName('HTMLImageElement.alt')
  @DocsEditable()
  void set alt(String value) => _blink.BlinkHTMLImageElement.instance.alt_Setter_(this, value);

  @DomName('HTMLImageElement.complete')
  @DocsEditable()
  bool get complete => _blink.BlinkHTMLImageElement.instance.complete_Getter_(this);

  @DomName('HTMLImageElement.crossOrigin')
  @DocsEditable()
  String get crossOrigin => _blink.BlinkHTMLImageElement.instance.crossOrigin_Getter_(this);

  @DomName('HTMLImageElement.crossOrigin')
  @DocsEditable()
  void set crossOrigin(String value) => _blink.BlinkHTMLImageElement.instance.crossOrigin_Setter_(this, value);

  @DomName('HTMLImageElement.currentSrc')
  @DocsEditable()
  @Experimental() // untriaged
  String get currentSrc => _blink.BlinkHTMLImageElement.instance.currentSrc_Getter_(this);

  @DomName('HTMLImageElement.height')
  @DocsEditable()
  int get height => _blink.BlinkHTMLImageElement.instance.height_Getter_(this);

  @DomName('HTMLImageElement.height')
  @DocsEditable()
  void set height(int value) => _blink.BlinkHTMLImageElement.instance.height_Setter_(this, value);

  @DomName('HTMLImageElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String get integrity => _blink.BlinkHTMLImageElement.instance.integrity_Getter_(this);

  @DomName('HTMLImageElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  void set integrity(String value) => _blink.BlinkHTMLImageElement.instance.integrity_Setter_(this, value);

  @DomName('HTMLImageElement.isMap')
  @DocsEditable()
  bool get isMap => _blink.BlinkHTMLImageElement.instance.isMap_Getter_(this);

  @DomName('HTMLImageElement.isMap')
  @DocsEditable()
  void set isMap(bool value) => _blink.BlinkHTMLImageElement.instance.isMap_Setter_(this, value);

  @DomName('HTMLImageElement.naturalHeight')
  @DocsEditable()
  int get naturalHeight => _blink.BlinkHTMLImageElement.instance.naturalHeight_Getter_(this);

  @DomName('HTMLImageElement.naturalWidth')
  @DocsEditable()
  int get naturalWidth => _blink.BlinkHTMLImageElement.instance.naturalWidth_Getter_(this);

  @DomName('HTMLImageElement.sizes')
  @DocsEditable()
  @Experimental() // untriaged
  String get sizes => _blink.BlinkHTMLImageElement.instance.sizes_Getter_(this);

  @DomName('HTMLImageElement.sizes')
  @DocsEditable()
  @Experimental() // untriaged
  void set sizes(String value) => _blink.BlinkHTMLImageElement.instance.sizes_Setter_(this, value);

  @DomName('HTMLImageElement.src')
  @DocsEditable()
  String get src => _blink.BlinkHTMLImageElement.instance.src_Getter_(this);

  @DomName('HTMLImageElement.src')
  @DocsEditable()
  void set src(String value) => _blink.BlinkHTMLImageElement.instance.src_Setter_(this, value);

  @DomName('HTMLImageElement.srcset')
  @DocsEditable()
  @Experimental() // untriaged
  String get srcset => _blink.BlinkHTMLImageElement.instance.srcset_Getter_(this);

  @DomName('HTMLImageElement.srcset')
  @DocsEditable()
  @Experimental() // untriaged
  void set srcset(String value) => _blink.BlinkHTMLImageElement.instance.srcset_Setter_(this, value);

  @DomName('HTMLImageElement.useMap')
  @DocsEditable()
  String get useMap => _blink.BlinkHTMLImageElement.instance.useMap_Getter_(this);

  @DomName('HTMLImageElement.useMap')
  @DocsEditable()
  void set useMap(String value) => _blink.BlinkHTMLImageElement.instance.useMap_Setter_(this, value);

  @DomName('HTMLImageElement.width')
  @DocsEditable()
  int get width => _blink.BlinkHTMLImageElement.instance.width_Getter_(this);

  @DomName('HTMLImageElement.width')
  @DocsEditable()
  void set width(int value) => _blink.BlinkHTMLImageElement.instance.width_Setter_(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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('InjectedScriptHost')
@Experimental() // untriaged
class InjectedScriptHost extends NativeFieldWrapperClass2 {
  // 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) => _blink.BlinkInjectedScriptHost.instance.inspect_Callback_2_(this, objectId, hints);

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


@DomName('HTMLInputElement')
class InputElement extends HtmlElement implements
    HiddenInputElement,
    SearchInputElement,
    TextInputElement,
    UrlInputElement,
    TelephoneInputElement,
    EmailInputElement,
    PasswordInputElement,
    DateInputElement,
    MonthInputElement,
    WeekInputElement,
    TimeInputElement,
    LocalDateTimeInputElement,
    NumberInputElement,
    RangeInputElement,
    CheckboxInputElement,
    RadioButtonInputElement,
    FileUploadInputElement,
    SubmitButtonInputElement,
    ImageButtonInputElement,
    ResetButtonInputElement,
    ButtonInputElement {

  factory InputElement({String type}) {
    var e = document.createElement("input");
    if (type != null) {
      try {
        // IE throws an exception for unknown types.
        e.type = type;
      } catch(_) {}
    }
    return e;
  }

  // To suppress missing implicit constructor warnings.
  factory InputElement._() { throw new UnsupportedError("Not supported"); }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  InputElement.created() : super.created();

  @DomName('HTMLInputElement.accept')
  @DocsEditable()
  String get accept => _blink.BlinkHTMLInputElement.instance.accept_Getter_(this);

  @DomName('HTMLInputElement.accept')
  @DocsEditable()
  void set accept(String value) => _blink.BlinkHTMLInputElement.instance.accept_Setter_(this, value);

  @DomName('HTMLInputElement.alt')
  @DocsEditable()
  String get alt => _blink.BlinkHTMLInputElement.instance.alt_Getter_(this);

  @DomName('HTMLInputElement.alt')
  @DocsEditable()
  void set alt(String value) => _blink.BlinkHTMLInputElement.instance.alt_Setter_(this, value);

  @DomName('HTMLInputElement.autocomplete')
  @DocsEditable()
  String get autocomplete => _blink.BlinkHTMLInputElement.instance.autocomplete_Getter_(this);

  @DomName('HTMLInputElement.autocomplete')
  @DocsEditable()
  void set autocomplete(String value) => _blink.BlinkHTMLInputElement.instance.autocomplete_Setter_(this, value);

  @DomName('HTMLInputElement.autofocus')
  @DocsEditable()
  bool get autofocus => _blink.BlinkHTMLInputElement.instance.autofocus_Getter_(this);

  @DomName('HTMLInputElement.autofocus')
  @DocsEditable()
  void set autofocus(bool value) => _blink.BlinkHTMLInputElement.instance.autofocus_Setter_(this, value);

  @DomName('HTMLInputElement.capture')
  @DocsEditable()
  @Experimental() // untriaged
  bool get capture => _blink.BlinkHTMLInputElement.instance.capture_Getter_(this);

  @DomName('HTMLInputElement.capture')
  @DocsEditable()
  @Experimental() // untriaged
  void set capture(bool value) => _blink.BlinkHTMLInputElement.instance.capture_Setter_(this, value);

  @DomName('HTMLInputElement.checked')
  @DocsEditable()
  bool get checked => _blink.BlinkHTMLInputElement.instance.checked_Getter_(this);

  @DomName('HTMLInputElement.checked')
  @DocsEditable()
  void set checked(bool value) => _blink.BlinkHTMLInputElement.instance.checked_Setter_(this, value);

  @DomName('HTMLInputElement.defaultChecked')
  @DocsEditable()
  bool get defaultChecked => _blink.BlinkHTMLInputElement.instance.defaultChecked_Getter_(this);

  @DomName('HTMLInputElement.defaultChecked')
  @DocsEditable()
  void set defaultChecked(bool value) => _blink.BlinkHTMLInputElement.instance.defaultChecked_Setter_(this, value);

  @DomName('HTMLInputElement.defaultValue')
  @DocsEditable()
  String get defaultValue => _blink.BlinkHTMLInputElement.instance.defaultValue_Getter_(this);

  @DomName('HTMLInputElement.defaultValue')
  @DocsEditable()
  void set defaultValue(String value) => _blink.BlinkHTMLInputElement.instance.defaultValue_Setter_(this, value);

  @DomName('HTMLInputElement.dirName')
  @DocsEditable()
  String get dirName => _blink.BlinkHTMLInputElement.instance.dirName_Getter_(this);

  @DomName('HTMLInputElement.dirName')
  @DocsEditable()
  void set dirName(String value) => _blink.BlinkHTMLInputElement.instance.dirName_Setter_(this, value);

  @DomName('HTMLInputElement.disabled')
  @DocsEditable()
  bool get disabled => _blink.BlinkHTMLInputElement.instance.disabled_Getter_(this);

  @DomName('HTMLInputElement.disabled')
  @DocsEditable()
  void set disabled(bool value) => _blink.BlinkHTMLInputElement.instance.disabled_Setter_(this, value);

  @DomName('HTMLInputElement.files')
  @DocsEditable()
  List<File> get files => _blink.BlinkHTMLInputElement.instance.files_Getter_(this);

  @DomName('HTMLInputElement.files')
  @DocsEditable()
  void set files(List<File> value) => _blink.BlinkHTMLInputElement.instance.files_Setter_(this, value);

  @DomName('HTMLInputElement.form')
  @DocsEditable()
  FormElement get form => _blink.BlinkHTMLInputElement.instance.form_Getter_(this);

  @DomName('HTMLInputElement.formAction')
  @DocsEditable()
  String get formAction => _blink.BlinkHTMLInputElement.instance.formAction_Getter_(this);

  @DomName('HTMLInputElement.formAction')
  @DocsEditable()
  void set formAction(String value) => _blink.BlinkHTMLInputElement.instance.formAction_Setter_(this, value);

  @DomName('HTMLInputElement.formEnctype')
  @DocsEditable()
  String get formEnctype => _blink.BlinkHTMLInputElement.instance.formEnctype_Getter_(this);

  @DomName('HTMLInputElement.formEnctype')
  @DocsEditable()
  void set formEnctype(String value) => _blink.BlinkHTMLInputElement.instance.formEnctype_Setter_(this, value);

  @DomName('HTMLInputElement.formMethod')
  @DocsEditable()
  String get formMethod => _blink.BlinkHTMLInputElement.instance.formMethod_Getter_(this);

  @DomName('HTMLInputElement.formMethod')
  @DocsEditable()
  void set formMethod(String value) => _blink.BlinkHTMLInputElement.instance.formMethod_Setter_(this, value);

  @DomName('HTMLInputElement.formNoValidate')
  @DocsEditable()
  bool get formNoValidate => _blink.BlinkHTMLInputElement.instance.formNoValidate_Getter_(this);

  @DomName('HTMLInputElement.formNoValidate')
  @DocsEditable()
  void set formNoValidate(bool value) => _blink.BlinkHTMLInputElement.instance.formNoValidate_Setter_(this, value);

  @DomName('HTMLInputElement.formTarget')
  @DocsEditable()
  String get formTarget => _blink.BlinkHTMLInputElement.instance.formTarget_Getter_(this);

  @DomName('HTMLInputElement.formTarget')
  @DocsEditable()
  void set formTarget(String value) => _blink.BlinkHTMLInputElement.instance.formTarget_Setter_(this, value);

  @DomName('HTMLInputElement.height')
  @DocsEditable()
  int get height => _blink.BlinkHTMLInputElement.instance.height_Getter_(this);

  @DomName('HTMLInputElement.height')
  @DocsEditable()
  void set height(int value) => _blink.BlinkHTMLInputElement.instance.height_Setter_(this, value);

  @DomName('HTMLInputElement.incremental')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  bool get incremental => _blink.BlinkHTMLInputElement.instance.incremental_Getter_(this);

  @DomName('HTMLInputElement.incremental')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  void set incremental(bool value) => _blink.BlinkHTMLInputElement.instance.incremental_Setter_(this, value);

  @DomName('HTMLInputElement.indeterminate')
  @DocsEditable()
  bool get indeterminate => _blink.BlinkHTMLInputElement.instance.indeterminate_Getter_(this);

  @DomName('HTMLInputElement.indeterminate')
  @DocsEditable()
  void set indeterminate(bool value) => _blink.BlinkHTMLInputElement.instance.indeterminate_Setter_(this, value);

  @DomName('HTMLInputElement.inputMode')
  @DocsEditable()
  @Experimental() // untriaged
  String get inputMode => _blink.BlinkHTMLInputElement.instance.inputMode_Getter_(this);

  @DomName('HTMLInputElement.inputMode')
  @DocsEditable()
  @Experimental() // untriaged
  void set inputMode(String value) => _blink.BlinkHTMLInputElement.instance.inputMode_Setter_(this, value);

  @DomName('HTMLInputElement.labels')
  @DocsEditable()
  List<Node> get labels => _blink.BlinkHTMLInputElement.instance.labels_Getter_(this);

  @DomName('HTMLInputElement.list')
  @DocsEditable()
  HtmlElement get list => _blink.BlinkHTMLInputElement.instance.list_Getter_(this);

  @DomName('HTMLInputElement.max')
  @DocsEditable()
  String get max => _blink.BlinkHTMLInputElement.instance.max_Getter_(this);

  @DomName('HTMLInputElement.max')
  @DocsEditable()
  void set max(String value) => _blink.BlinkHTMLInputElement.instance.max_Setter_(this, value);

  @DomName('HTMLInputElement.maxLength')
  @DocsEditable()
  int get maxLength => _blink.BlinkHTMLInputElement.instance.maxLength_Getter_(this);

  @DomName('HTMLInputElement.maxLength')
  @DocsEditable()
  void set maxLength(int value) => _blink.BlinkHTMLInputElement.instance.maxLength_Setter_(this, value);

  @DomName('HTMLInputElement.min')
  @DocsEditable()
  String get min => _blink.BlinkHTMLInputElement.instance.min_Getter_(this);

  @DomName('HTMLInputElement.min')
  @DocsEditable()
  void set min(String value) => _blink.BlinkHTMLInputElement.instance.min_Setter_(this, value);

  @DomName('HTMLInputElement.multiple')
  @DocsEditable()
  bool get multiple => _blink.BlinkHTMLInputElement.instance.multiple_Getter_(this);

  @DomName('HTMLInputElement.multiple')
  @DocsEditable()
  void set multiple(bool value) => _blink.BlinkHTMLInputElement.instance.multiple_Setter_(this, value);

  @DomName('HTMLInputElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLInputElement.instance.name_Getter_(this);

  @DomName('HTMLInputElement.name')
  @DocsEditable()
  void set name(String value) => _blink.BlinkHTMLInputElement.instance.name_Setter_(this, value);

  @DomName('HTMLInputElement.pattern')
  @DocsEditable()
  String get pattern => _blink.BlinkHTMLInputElement.instance.pattern_Getter_(this);

  @DomName('HTMLInputElement.pattern')
  @DocsEditable()
  void set pattern(String value) => _blink.BlinkHTMLInputElement.instance.pattern_Setter_(this, value);

  @DomName('HTMLInputElement.placeholder')
  @DocsEditable()
  String get placeholder => _blink.BlinkHTMLInputElement.instance.placeholder_Getter_(this);

  @DomName('HTMLInputElement.placeholder')
  @DocsEditable()
  void set placeholder(String value) => _blink.BlinkHTMLInputElement.instance.placeholder_Setter_(this, value);

  @DomName('HTMLInputElement.readOnly')
  @DocsEditable()
  bool get readOnly => _blink.BlinkHTMLInputElement.instance.readOnly_Getter_(this);

  @DomName('HTMLInputElement.readOnly')
  @DocsEditable()
  void set readOnly(bool value) => _blink.BlinkHTMLInputElement.instance.readOnly_Setter_(this, value);

  @DomName('HTMLInputElement.required')
  @DocsEditable()
  bool get required => _blink.BlinkHTMLInputElement.instance.required_Getter_(this);

  @DomName('HTMLInputElement.required')
  @DocsEditable()
  void set required(bool value) => _blink.BlinkHTMLInputElement.instance.required_Setter_(this, value);

  @DomName('HTMLInputElement.selectionDirection')
  @DocsEditable()
  String get selectionDirection => _blink.BlinkHTMLInputElement.instance.selectionDirection_Getter_(this);

  @DomName('HTMLInputElement.selectionDirection')
  @DocsEditable()
  void set selectionDirection(String value) => _blink.BlinkHTMLInputElement.instance.selectionDirection_Setter_(this, value);

  @DomName('HTMLInputElement.selectionEnd')
  @DocsEditable()
  int get selectionEnd => _blink.BlinkHTMLInputElement.instance.selectionEnd_Getter_(this);

  @DomName('HTMLInputElement.selectionEnd')
  @DocsEditable()
  void set selectionEnd(int value) => _blink.BlinkHTMLInputElement.instance.selectionEnd_Setter_(this, value);

  @DomName('HTMLInputElement.selectionStart')
  @DocsEditable()
  int get selectionStart => _blink.BlinkHTMLInputElement.instance.selectionStart_Getter_(this);

  @DomName('HTMLInputElement.selectionStart')
  @DocsEditable()
  void set selectionStart(int value) => _blink.BlinkHTMLInputElement.instance.selectionStart_Setter_(this, value);

  @DomName('HTMLInputElement.size')
  @DocsEditable()
  int get size => _blink.BlinkHTMLInputElement.instance.size_Getter_(this);

  @DomName('HTMLInputElement.size')
  @DocsEditable()
  void set size(int value) => _blink.BlinkHTMLInputElement.instance.size_Setter_(this, value);

  @DomName('HTMLInputElement.src')
  @DocsEditable()
  String get src => _blink.BlinkHTMLInputElement.instance.src_Getter_(this);

  @DomName('HTMLInputElement.src')
  @DocsEditable()
  void set src(String value) => _blink.BlinkHTMLInputElement.instance.src_Setter_(this, value);

  @DomName('HTMLInputElement.step')
  @DocsEditable()
  String get step => _blink.BlinkHTMLInputElement.instance.step_Getter_(this);

  @DomName('HTMLInputElement.step')
  @DocsEditable()
  void set step(String value) => _blink.BlinkHTMLInputElement.instance.step_Setter_(this, value);

  @DomName('HTMLInputElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLInputElement.instance.type_Getter_(this);

  @DomName('HTMLInputElement.type')
  @DocsEditable()
  void set type(String value) => _blink.BlinkHTMLInputElement.instance.type_Setter_(this, value);

  @DomName('HTMLInputElement.validationMessage')
  @DocsEditable()
  String get validationMessage => _blink.BlinkHTMLInputElement.instance.validationMessage_Getter_(this);

  @DomName('HTMLInputElement.validity')
  @DocsEditable()
  ValidityState get validity => _blink.BlinkHTMLInputElement.instance.validity_Getter_(this);

  @DomName('HTMLInputElement.value')
  @DocsEditable()
  String get value => _blink.BlinkHTMLInputElement.instance.value_Getter_(this);

  @DomName('HTMLInputElement.value')
  @DocsEditable()
  void set value(String value) => _blink.BlinkHTMLInputElement.instance.value_Setter_(this, value);

  @DomName('HTMLInputElement.valueAsDate')
  @DocsEditable()
  DateTime get valueAsDate => _blink.BlinkHTMLInputElement.instance.valueAsDate_Getter_(this);

  @DomName('HTMLInputElement.valueAsDate')
  @DocsEditable()
  void set valueAsDate(DateTime value) => _blink.BlinkHTMLInputElement.instance.valueAsDate_Setter_(this, value);

  @DomName('HTMLInputElement.valueAsNumber')
  @DocsEditable()
  num get valueAsNumber => _blink.BlinkHTMLInputElement.instance.valueAsNumber_Getter_(this);

  @DomName('HTMLInputElement.valueAsNumber')
  @DocsEditable()
  void set valueAsNumber(num value) => _blink.BlinkHTMLInputElement.instance.valueAsNumber_Setter_(this, value);

  @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
  List<Entry> get entries => _blink.BlinkHTMLInputElement.instance.webkitEntries_Getter_(this);

  @DomName('HTMLInputElement.webkitdirectory')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://plus.sandbox.google.com/+AddyOsmani/posts/Dk5UhZ6zfF3
  bool get directory => _blink.BlinkHTMLInputElement.instance.webkitdirectory_Getter_(this);

  @DomName('HTMLInputElement.webkitdirectory')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://plus.sandbox.google.com/+AddyOsmani/posts/Dk5UhZ6zfF3
  void set directory(bool value) => _blink.BlinkHTMLInputElement.instance.webkitdirectory_Setter_(this, value);

  @DomName('HTMLInputElement.width')
  @DocsEditable()
  int get width => _blink.BlinkHTMLInputElement.instance.width_Getter_(this);

  @DomName('HTMLInputElement.width')
  @DocsEditable()
  void set width(int value) => _blink.BlinkHTMLInputElement.instance.width_Setter_(this, value);

  @DomName('HTMLInputElement.willValidate')
  @DocsEditable()
  bool get willValidate => _blink.BlinkHTMLInputElement.instance.willValidate_Getter_(this);

  @DomName('HTMLInputElement.checkValidity')
  @DocsEditable()
  bool checkValidity() => _blink.BlinkHTMLInputElement.instance.checkValidity_Callback_0_(this);

  @DomName('HTMLInputElement.select')
  @DocsEditable()
  void select() => _blink.BlinkHTMLInputElement.instance.select_Callback_0_(this);

  @DomName('HTMLInputElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) => _blink.BlinkHTMLInputElement.instance.setCustomValidity_Callback_1_(this, error);

  void setRangeText(String replacement, {int start, int end, String selectionMode}) {
    if ((replacement is String || replacement == null) && start == null && end == null && selectionMode == null) {
      _blink.BlinkHTMLInputElement.instance.setRangeText_Callback_1_(this, replacement);
      return;
    }
    if ((selectionMode is String || selectionMode == null) && (end is int || end == null) && (start is int || start == null) && (replacement is String || replacement == null)) {
      _blink.BlinkHTMLInputElement.instance.setRangeText_Callback_4_(this, replacement, start, end, selectionMode);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  void setSelectionRange(int start, int end, [String direction]) {
    if (direction != null) {
      _blink.BlinkHTMLInputElement.instance.setSelectionRange_Callback_3_(this, start, end, direction);
      return;
    }
    _blink.BlinkHTMLInputElement.instance.setSelectionRange_Callback_2_(this, start, end);
    return;
  }

  void stepDown([int n]) {
    if (n != null) {
      _blink.BlinkHTMLInputElement.instance.stepDown_Callback_1_(this, n);
      return;
    }
    _blink.BlinkHTMLInputElement.instance.stepDown_Callback_0_(this);
    return;
  }

  void stepUp([int n]) {
    if (n != null) {
      _blink.BlinkHTMLInputElement.instance.stepUp_Callback_1_(this, n);
      return;
    }
    _blink.BlinkHTMLInputElement.instance.stepUp_Callback_0_(this);
    return;
  }

}


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

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('InputMethodContext')
// http://www.w3.org/TR/ime-api/#idl-def-InputMethodContext
@Experimental()
class InputMethodContext extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory InputMethodContext._() { throw new UnsupportedError("Not supported"); }

  @DomName('InputMethodContext.compositionEndOffset')
  @DocsEditable()
  @Experimental() // untriaged
  int get compositionEndOffset => _blink.BlinkInputMethodContext.instance.compositionEndOffset_Getter_(this);

  @DomName('InputMethodContext.compositionStartOffset')
  @DocsEditable()
  @Experimental() // untriaged
  int get compositionStartOffset => _blink.BlinkInputMethodContext.instance.compositionStartOffset_Getter_(this);

  @DomName('InputMethodContext.locale')
  @DocsEditable()
  String get locale => _blink.BlinkInputMethodContext.instance.locale_Getter_(this);

  @DomName('InputMethodContext.target')
  @DocsEditable()
  @Experimental() // untriaged
  HtmlElement get target => _blink.BlinkInputMethodContext.instance.target_Getter_(this);

  @DomName('InputMethodContext.confirmComposition')
  @DocsEditable()
  void confirmComposition() => _blink.BlinkInputMethodContext.instance.confirmComposition_Callback_0_(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.


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

  @DomName('InstallEvent.reloadAll')
  @DocsEditable()
  @Experimental() // untriaged
  Future reloadAll() => _blink.BlinkInstallEvent.instance.reloadAll_Callback_0_(this);

  @DomName('InstallEvent.replace')
  @DocsEditable()
  @Experimental() // untriaged
  void replace() => _blink.BlinkInstallEvent.instance.replace_Callback_0_(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.


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

  @DomName('InstallPhaseEvent.waitUntil')
  @DocsEditable()
  @Experimental() // untriaged
  void waitUntil(Object value) => _blink.BlinkInstallPhaseEvent.instance.waitUntil_Callback_1_(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('KeyboardEvent')
class KeyboardEvent extends UIEvent {

  factory KeyboardEvent(String type,
      {Window view, bool canBubble: true, bool cancelable: true,
      int keyLocation: 1, bool ctrlKey: false,
      bool altKey: false, bool shiftKey: false, bool metaKey: false}) {
    if (view == null) {
      view = window;
    }
    final e = document._createEvent("KeyboardEvent");
    e._initKeyboardEvent(type, canBubble, cancelable, view, "",
        keyLocation, ctrlKey, altKey, shiftKey, metaKey);
    return e;
  }

  @DomName('KeyboardEvent.keyCode')
  int get keyCode => _keyCode;

  @DomName('KeyboardEvent.charCode')
  int get charCode => _charCode;
  // To suppress missing implicit constructor warnings.
  factory KeyboardEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('KeyboardEvent.DOM_KEY_LOCATION_LEFT')
  @DocsEditable()
  @Experimental() // untriaged
  static const int DOM_KEY_LOCATION_LEFT = 0x01;

  @DomName('KeyboardEvent.DOM_KEY_LOCATION_NUMPAD')
  @DocsEditable()
  @Experimental() // untriaged
  static const int DOM_KEY_LOCATION_NUMPAD = 0x03;

  @DomName('KeyboardEvent.DOM_KEY_LOCATION_RIGHT')
  @DocsEditable()
  @Experimental() // untriaged
  static const int DOM_KEY_LOCATION_RIGHT = 0x02;

  @DomName('KeyboardEvent.DOM_KEY_LOCATION_STANDARD')
  @DocsEditable()
  @Experimental() // untriaged
  static const int DOM_KEY_LOCATION_STANDARD = 0x00;

  @DomName('KeyboardEvent.altKey')
  @DocsEditable()
  bool get altKey => _blink.BlinkKeyboardEvent.instance.altKey_Getter_(this);

  @DomName('KeyboardEvent.ctrlKey')
  @DocsEditable()
  bool get ctrlKey => _blink.BlinkKeyboardEvent.instance.ctrlKey_Getter_(this);

  @DomName('KeyboardEvent.keyIdentifier')
  @DocsEditable()
  @Experimental() // nonstandard
  String get _keyIdentifier => _blink.BlinkKeyboardEvent.instance.keyIdentifier_Getter_(this);

  @DomName('KeyboardEvent.keyLocation')
  @DocsEditable()
  @Experimental() // nonstandard
  int get keyLocation => _blink.BlinkKeyboardEvent.instance.keyLocation_Getter_(this);

  @DomName('KeyboardEvent.location')
  @DocsEditable()
  @Experimental() // untriaged
  int get location => _blink.BlinkKeyboardEvent.instance.location_Getter_(this);

  @DomName('KeyboardEvent.metaKey')
  @DocsEditable()
  bool get metaKey => _blink.BlinkKeyboardEvent.instance.metaKey_Getter_(this);

  @DomName('KeyboardEvent.repeat')
  @DocsEditable()
  @Experimental() // untriaged
  bool get repeat => _blink.BlinkKeyboardEvent.instance.repeat_Getter_(this);

  @DomName('KeyboardEvent.shiftKey')
  @DocsEditable()
  bool get shiftKey => _blink.BlinkKeyboardEvent.instance.shiftKey_Getter_(this);

  @DomName('KeyboardEvent.getModifierState')
  @DocsEditable()
  @Experimental() // untriaged
  bool getModifierState(String keyArgument) => _blink.BlinkKeyboardEvent.instance.getModifierState_Callback_1_(this, keyArgument);

  @DomName('KeyboardEvent.initKeyboardEvent')
  @DocsEditable()
  void _initKeyboardEvent(String type, bool canBubble, bool cancelable, Window view, String keyIdentifier, int location, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey) => _blink.BlinkKeyboardEvent.instance.initKeyboardEvent_Callback_10_(this, type, canBubble, cancelable, view, keyIdentifier, location, ctrlKey, altKey, shiftKey, metaKey);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


@DocsEditable()
@DomName('HTMLKeygenElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#the-keygen-element
class KeygenElement extends HtmlElement {
  // 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 => true;

  @DomName('HTMLKeygenElement.autofocus')
  @DocsEditable()
  bool get autofocus => _blink.BlinkHTMLKeygenElement.instance.autofocus_Getter_(this);

  @DomName('HTMLKeygenElement.autofocus')
  @DocsEditable()
  void set autofocus(bool value) => _blink.BlinkHTMLKeygenElement.instance.autofocus_Setter_(this, value);

  @DomName('HTMLKeygenElement.challenge')
  @DocsEditable()
  String get challenge => _blink.BlinkHTMLKeygenElement.instance.challenge_Getter_(this);

  @DomName('HTMLKeygenElement.challenge')
  @DocsEditable()
  void set challenge(String value) => _blink.BlinkHTMLKeygenElement.instance.challenge_Setter_(this, value);

  @DomName('HTMLKeygenElement.disabled')
  @DocsEditable()
  bool get disabled => _blink.BlinkHTMLKeygenElement.instance.disabled_Getter_(this);

  @DomName('HTMLKeygenElement.disabled')
  @DocsEditable()
  void set disabled(bool value) => _blink.BlinkHTMLKeygenElement.instance.disabled_Setter_(this, value);

  @DomName('HTMLKeygenElement.form')
  @DocsEditable()
  FormElement get form => _blink.BlinkHTMLKeygenElement.instance.form_Getter_(this);

  @DomName('HTMLKeygenElement.keytype')
  @DocsEditable()
  String get keytype => _blink.BlinkHTMLKeygenElement.instance.keytype_Getter_(this);

  @DomName('HTMLKeygenElement.keytype')
  @DocsEditable()
  void set keytype(String value) => _blink.BlinkHTMLKeygenElement.instance.keytype_Setter_(this, value);

  @DomName('HTMLKeygenElement.labels')
  @DocsEditable()
  @Unstable()
  List<Node> get labels => _blink.BlinkHTMLKeygenElement.instance.labels_Getter_(this);

  @DomName('HTMLKeygenElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLKeygenElement.instance.name_Getter_(this);

  @DomName('HTMLKeygenElement.name')
  @DocsEditable()
  void set name(String value) => _blink.BlinkHTMLKeygenElement.instance.name_Setter_(this, value);

  @DomName('HTMLKeygenElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLKeygenElement.instance.type_Getter_(this);

  @DomName('HTMLKeygenElement.validationMessage')
  @DocsEditable()
  String get validationMessage => _blink.BlinkHTMLKeygenElement.instance.validationMessage_Getter_(this);

  @DomName('HTMLKeygenElement.validity')
  @DocsEditable()
  ValidityState get validity => _blink.BlinkHTMLKeygenElement.instance.validity_Getter_(this);

  @DomName('HTMLKeygenElement.willValidate')
  @DocsEditable()
  bool get willValidate => _blink.BlinkHTMLKeygenElement.instance.willValidate_Getter_(this);

  @DomName('HTMLKeygenElement.checkValidity')
  @DocsEditable()
  bool checkValidity() => _blink.BlinkHTMLKeygenElement.instance.checkValidity_Callback_0_(this);

  @DomName('HTMLKeygenElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) => _blink.BlinkHTMLKeygenElement.instance.setCustomValidity_Callback_1_(this, 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.


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

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

  @DomName('HTMLLIElement.value')
  @DocsEditable()
  int get value => _blink.BlinkHTMLLIElement.instance.value_Getter_(this);

  @DomName('HTMLLIElement.value')
  @DocsEditable()
  void set value(int value) => _blink.BlinkHTMLLIElement.instance.value_Setter_(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.

// WARNING: Do not edit - generated code.


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

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

  @DomName('HTMLLabelElement.control')
  @DocsEditable()
  HtmlElement get control => _blink.BlinkHTMLLabelElement.instance.control_Getter_(this);

  @DomName('HTMLLabelElement.form')
  @DocsEditable()
  FormElement get form => _blink.BlinkHTMLLabelElement.instance.form_Getter_(this);

  @DomName('HTMLLabelElement.htmlFor')
  @DocsEditable()
  String get htmlFor => _blink.BlinkHTMLLabelElement.instance.htmlFor_Getter_(this);

  @DomName('HTMLLabelElement.htmlFor')
  @DocsEditable()
  void set htmlFor(String value) => _blink.BlinkHTMLLabelElement.instance.htmlFor_Setter_(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.

// WARNING: Do not edit - generated code.


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

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

  @DomName('HTMLLegendElement.form')
  @DocsEditable()
  FormElement get form => _blink.BlinkHTMLLegendElement.instance.form_Getter_(this);

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


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

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

  @DomName('HTMLLinkElement.crossOrigin')
  @DocsEditable()
  @Experimental() // untriaged
  String get crossOrigin => _blink.BlinkHTMLLinkElement.instance.crossOrigin_Getter_(this);

  @DomName('HTMLLinkElement.crossOrigin')
  @DocsEditable()
  @Experimental() // untriaged
  void set crossOrigin(String value) => _blink.BlinkHTMLLinkElement.instance.crossOrigin_Setter_(this, value);

  @DomName('HTMLLinkElement.disabled')
  @DocsEditable()
  bool get disabled => _blink.BlinkHTMLLinkElement.instance.disabled_Getter_(this);

  @DomName('HTMLLinkElement.disabled')
  @DocsEditable()
  void set disabled(bool value) => _blink.BlinkHTMLLinkElement.instance.disabled_Setter_(this, value);

  @DomName('HTMLLinkElement.href')
  @DocsEditable()
  String get href => _blink.BlinkHTMLLinkElement.instance.href_Getter_(this);

  @DomName('HTMLLinkElement.href')
  @DocsEditable()
  void set href(String value) => _blink.BlinkHTMLLinkElement.instance.href_Setter_(this, value);

  @DomName('HTMLLinkElement.hreflang')
  @DocsEditable()
  String get hreflang => _blink.BlinkHTMLLinkElement.instance.hreflang_Getter_(this);

  @DomName('HTMLLinkElement.hreflang')
  @DocsEditable()
  void set hreflang(String value) => _blink.BlinkHTMLLinkElement.instance.hreflang_Setter_(this, value);

  @DomName('HTMLLinkElement.import')
  @DocsEditable()
  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/imports/index.html#interface-import
  @Experimental()
  Document get import => _blink.BlinkHTMLLinkElement.instance.import_Getter_(this);

  @DomName('HTMLLinkElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String get integrity => _blink.BlinkHTMLLinkElement.instance.integrity_Getter_(this);

  @DomName('HTMLLinkElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  void set integrity(String value) => _blink.BlinkHTMLLinkElement.instance.integrity_Setter_(this, value);

  @DomName('HTMLLinkElement.media')
  @DocsEditable()
  String get media => _blink.BlinkHTMLLinkElement.instance.media_Getter_(this);

  @DomName('HTMLLinkElement.media')
  @DocsEditable()
  void set media(String value) => _blink.BlinkHTMLLinkElement.instance.media_Setter_(this, value);

  @DomName('HTMLLinkElement.rel')
  @DocsEditable()
  String get rel => _blink.BlinkHTMLLinkElement.instance.rel_Getter_(this);

  @DomName('HTMLLinkElement.rel')
  @DocsEditable()
  void set rel(String value) => _blink.BlinkHTMLLinkElement.instance.rel_Setter_(this, value);

  @DomName('HTMLLinkElement.sheet')
  @DocsEditable()
  StyleSheet get sheet => _blink.BlinkHTMLLinkElement.instance.sheet_Getter_(this);

  @DomName('HTMLLinkElement.sizes')
  @DocsEditable()
  DomSettableTokenList get sizes => _blink.BlinkHTMLLinkElement.instance.sizes_Getter_(this);

  @DomName('HTMLLinkElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLLinkElement.instance.type_Getter_(this);

  @DomName('HTMLLinkElement.type')
  @DocsEditable()
  void set type(String value) => _blink.BlinkHTMLLinkElement.instance.type_Setter_(this, value);


    /// Checks if HTML imports are supported on the current platform.
  bool get supportsImport {
    return true;
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

  @DomName('LocalCredential.LocalCredential')
  @DocsEditable()
  factory LocalCredential(String id, String name, String avatarURL, String password) {
    return _blink.BlinkLocalCredential.instance.constructorCallback_4_(id, name, avatarURL, password);
  }

  @DomName('LocalCredential.password')
  @DocsEditable()
  @Experimental() // untriaged
  String get password => _blink.BlinkLocalCredential.instance.password_Getter_(this);

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


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

  @DomName('Location.ancestorOrigins')
  @DocsEditable()
  @Experimental() // nonstandard
  List<String> get ancestorOrigins => _blink.BlinkLocation.instance.ancestorOrigins_Getter_(this);

  @DomName('Location.hash')
  @DocsEditable()
  String get hash => _blink.BlinkLocation.instance.hash_Getter_(this);

  @DomName('Location.hash')
  @DocsEditable()
  void set hash(String value) => _blink.BlinkLocation.instance.hash_Setter_(this, value);

  @DomName('Location.host')
  @DocsEditable()
  String get host => _blink.BlinkLocation.instance.host_Getter_(this);

  @DomName('Location.host')
  @DocsEditable()
  void set host(String value) => _blink.BlinkLocation.instance.host_Setter_(this, value);

  @DomName('Location.hostname')
  @DocsEditable()
  String get hostname => _blink.BlinkLocation.instance.hostname_Getter_(this);

  @DomName('Location.hostname')
  @DocsEditable()
  void set hostname(String value) => _blink.BlinkLocation.instance.hostname_Setter_(this, value);

  @DomName('Location.href')
  @DocsEditable()
  String get href => _blink.BlinkLocation.instance.href_Getter_(this);

  @DomName('Location.href')
  @DocsEditable()
  void set href(String value) => _blink.BlinkLocation.instance.href_Setter_(this, value);

  @DomName('Location.origin')
  @DocsEditable()
  // http://url.spec.whatwg.org/#urlutils Webkit Only
  @Experimental() // non-standard
  String get origin => _blink.BlinkLocation.instance.origin_Getter_(this);

  @DomName('Location.pathname')
  @DocsEditable()
  String get pathname => _blink.BlinkLocation.instance.pathname_Getter_(this);

  @DomName('Location.pathname')
  @DocsEditable()
  void set pathname(String value) => _blink.BlinkLocation.instance.pathname_Setter_(this, value);

  @DomName('Location.port')
  @DocsEditable()
  String get port => _blink.BlinkLocation.instance.port_Getter_(this);

  @DomName('Location.port')
  @DocsEditable()
  void set port(String value) => _blink.BlinkLocation.instance.port_Setter_(this, value);

  @DomName('Location.protocol')
  @DocsEditable()
  String get protocol => _blink.BlinkLocation.instance.protocol_Getter_(this);

  @DomName('Location.protocol')
  @DocsEditable()
  void set protocol(String value) => _blink.BlinkLocation.instance.protocol_Setter_(this, value);

  @DomName('Location.search')
  @DocsEditable()
  String get search => _blink.BlinkLocation.instance.search_Getter_(this);

  @DomName('Location.search')
  @DocsEditable()
  void set search(String value) => _blink.BlinkLocation.instance.search_Setter_(this, value);

  @DomName('Location.assign')
  @DocsEditable()
  void assign([String url]) => _blink.BlinkLocation.instance.assign_Callback_1_(this, url);

  @DomName('Location.reload')
  @DocsEditable()
  void reload() => _blink.BlinkLocation.instance.reload_Callback_0_(this);

  @DomName('Location.replace')
  @DocsEditable()
  void replace(String url) => _blink.BlinkLocation.instance.replace_Callback_1_(this, url);

  @DomName('Location.toString')
  @DocsEditable()
  String toString() => _blink.BlinkLocation.instance.toString_Callback_0_(this);


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

// WARNING: Do not edit - generated code.


@DomName('MIDIErrorCallback')
// http://webaudio.github.io/web-midi-api/#midierrorcallback
@Experimental()
typedef void MidiErrorCallback(DomError error);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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

// WARNING: Do not edit - generated code.


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

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

  @DomName('HTMLMapElement.areas')
  @DocsEditable()
  List<Node> get areas => _blink.BlinkHTMLMapElement.instance.areas_Getter_(this);

  @DomName('HTMLMapElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLMapElement.instance.name_Getter_(this);

  @DomName('HTMLMapElement.name')
  @DocsEditable()
  void set name(String value) => _blink.BlinkHTMLMapElement.instance.name_Setter_(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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('MediaController')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#mediacontroller
@Experimental()
class MediaController extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaController._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaController.MediaController')
  @DocsEditable()
  factory MediaController() {
    return _blink.BlinkMediaController.instance.constructorCallback_0_();
  }

  @DomName('MediaController.buffered')
  @DocsEditable()
  TimeRanges get buffered => _blink.BlinkMediaController.instance.buffered_Getter_(this);

  @DomName('MediaController.currentTime')
  @DocsEditable()
  num get currentTime => _blink.BlinkMediaController.instance.currentTime_Getter_(this);

  @DomName('MediaController.currentTime')
  @DocsEditable()
  void set currentTime(num value) => _blink.BlinkMediaController.instance.currentTime_Setter_(this, value);

  @DomName('MediaController.defaultPlaybackRate')
  @DocsEditable()
  num get defaultPlaybackRate => _blink.BlinkMediaController.instance.defaultPlaybackRate_Getter_(this);

  @DomName('MediaController.defaultPlaybackRate')
  @DocsEditable()
  void set defaultPlaybackRate(num value) => _blink.BlinkMediaController.instance.defaultPlaybackRate_Setter_(this, value);

  @DomName('MediaController.duration')
  @DocsEditable()
  double get duration => _blink.BlinkMediaController.instance.duration_Getter_(this);

  @DomName('MediaController.muted')
  @DocsEditable()
  bool get muted => _blink.BlinkMediaController.instance.muted_Getter_(this);

  @DomName('MediaController.muted')
  @DocsEditable()
  void set muted(bool value) => _blink.BlinkMediaController.instance.muted_Setter_(this, value);

  @DomName('MediaController.paused')
  @DocsEditable()
  bool get paused => _blink.BlinkMediaController.instance.paused_Getter_(this);

  @DomName('MediaController.playbackRate')
  @DocsEditable()
  num get playbackRate => _blink.BlinkMediaController.instance.playbackRate_Getter_(this);

  @DomName('MediaController.playbackRate')
  @DocsEditable()
  void set playbackRate(num value) => _blink.BlinkMediaController.instance.playbackRate_Setter_(this, value);

  @DomName('MediaController.playbackState')
  @DocsEditable()
  String get playbackState => _blink.BlinkMediaController.instance.playbackState_Getter_(this);

  @DomName('MediaController.played')
  @DocsEditable()
  TimeRanges get played => _blink.BlinkMediaController.instance.played_Getter_(this);

  @DomName('MediaController.seekable')
  @DocsEditable()
  TimeRanges get seekable => _blink.BlinkMediaController.instance.seekable_Getter_(this);

  @DomName('MediaController.volume')
  @DocsEditable()
  num get volume => _blink.BlinkMediaController.instance.volume_Getter_(this);

  @DomName('MediaController.volume')
  @DocsEditable()
  void set volume(num value) => _blink.BlinkMediaController.instance.volume_Setter_(this, value);

  @DomName('MediaController.pause')
  @DocsEditable()
  void pause() => _blink.BlinkMediaController.instance.pause_Callback_0_(this);

  @DomName('MediaController.play')
  @DocsEditable()
  void play() => _blink.BlinkMediaController.instance.play_Callback_0_(this);

  @DomName('MediaController.unpause')
  @DocsEditable()
  void unpause() => _blink.BlinkMediaController.instance.unpause_Callback_0_(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.


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

  @DomName('MediaDeviceInfo.deviceId')
  @DocsEditable()
  @Experimental() // untriaged
  String get deviceId => _blink.BlinkMediaDeviceInfo.instance.deviceId_Getter_(this);

  @DomName('MediaDeviceInfo.groupId')
  @DocsEditable()
  @Experimental() // untriaged
  String get groupId => _blink.BlinkMediaDeviceInfo.instance.groupId_Getter_(this);

  @DomName('MediaDeviceInfo.kind')
  @DocsEditable()
  @Experimental() // untriaged
  String get kind => _blink.BlinkMediaDeviceInfo.instance.kind_Getter_(this);

  @DomName('MediaDeviceInfo.label')
  @DocsEditable()
  @Experimental() // untriaged
  String get label => _blink.BlinkMediaDeviceInfo.instance.label_Getter_(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('MediaDeviceInfoCallback')
@Experimental() // untriaged
typedef void MediaDeviceInfoCallback(List<MediaDeviceInfo> devices);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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

  /**
   * Static factory designed to expose `keyadded` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.webkitkeyaddedEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  static const EventStreamProvider<MediaKeyEvent> keyAddedEvent = const EventStreamProvider<MediaKeyEvent>('webkitkeyadded');

  /**
   * Static factory designed to expose `keyerror` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.webkitkeyerrorEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  static const EventStreamProvider<MediaKeyEvent> keyErrorEvent = const EventStreamProvider<MediaKeyEvent>('webkitkeyerror');

  /**
   * Static factory designed to expose `keymessage` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.webkitkeymessageEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  static const EventStreamProvider<MediaKeyEvent> keyMessageEvent = const EventStreamProvider<MediaKeyEvent>('webkitkeymessage');

  /**
   * Static factory designed to expose `needkey` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.webkitneedkeyEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  static const EventStreamProvider<MediaKeyEvent> needKeyEvent = const EventStreamProvider<MediaKeyEvent>('webkitneedkey');
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  MediaElement.created() : super.created();

  @DomName('HTMLMediaElement.HAVE_CURRENT_DATA')
  @DocsEditable()
  static const int HAVE_CURRENT_DATA = 2;

  @DomName('HTMLMediaElement.HAVE_ENOUGH_DATA')
  @DocsEditable()
  static const int HAVE_ENOUGH_DATA = 4;

  @DomName('HTMLMediaElement.HAVE_FUTURE_DATA')
  @DocsEditable()
  static const int HAVE_FUTURE_DATA = 3;

  @DomName('HTMLMediaElement.HAVE_METADATA')
  @DocsEditable()
  static const int HAVE_METADATA = 1;

  @DomName('HTMLMediaElement.HAVE_NOTHING')
  @DocsEditable()
  static const int HAVE_NOTHING = 0;

  @DomName('HTMLMediaElement.NETWORK_EMPTY')
  @DocsEditable()
  static const int NETWORK_EMPTY = 0;

  @DomName('HTMLMediaElement.NETWORK_IDLE')
  @DocsEditable()
  static const int NETWORK_IDLE = 1;

  @DomName('HTMLMediaElement.NETWORK_LOADING')
  @DocsEditable()
  static const int NETWORK_LOADING = 2;

  @DomName('HTMLMediaElement.NETWORK_NO_SOURCE')
  @DocsEditable()
  static const int NETWORK_NO_SOURCE = 3;

  @DomName('HTMLMediaElement.audioTracks')
  @DocsEditable()
  @Experimental() // untriaged
  AudioTrackList get audioTracks => _blink.BlinkHTMLMediaElement.instance.audioTracks_Getter_(this);

  @DomName('HTMLMediaElement.autoplay')
  @DocsEditable()
  bool get autoplay => _blink.BlinkHTMLMediaElement.instance.autoplay_Getter_(this);

  @DomName('HTMLMediaElement.autoplay')
  @DocsEditable()
  void set autoplay(bool value) => _blink.BlinkHTMLMediaElement.instance.autoplay_Setter_(this, value);

  @DomName('HTMLMediaElement.buffered')
  @DocsEditable()
  TimeRanges get buffered => _blink.BlinkHTMLMediaElement.instance.buffered_Getter_(this);

  @DomName('HTMLMediaElement.controller')
  @DocsEditable()
  MediaController get controller => _blink.BlinkHTMLMediaElement.instance.controller_Getter_(this);

  @DomName('HTMLMediaElement.controller')
  @DocsEditable()
  void set controller(MediaController value) => _blink.BlinkHTMLMediaElement.instance.controller_Setter_(this, value);

  @DomName('HTMLMediaElement.controls')
  @DocsEditable()
  bool get controls => _blink.BlinkHTMLMediaElement.instance.controls_Getter_(this);

  @DomName('HTMLMediaElement.controls')
  @DocsEditable()
  void set controls(bool value) => _blink.BlinkHTMLMediaElement.instance.controls_Setter_(this, value);

  @DomName('HTMLMediaElement.crossOrigin')
  @DocsEditable()
  @Experimental() // untriaged
  String get crossOrigin => _blink.BlinkHTMLMediaElement.instance.crossOrigin_Getter_(this);

  @DomName('HTMLMediaElement.crossOrigin')
  @DocsEditable()
  @Experimental() // untriaged
  void set crossOrigin(String value) => _blink.BlinkHTMLMediaElement.instance.crossOrigin_Setter_(this, value);

  @DomName('HTMLMediaElement.currentSrc')
  @DocsEditable()
  String get currentSrc => _blink.BlinkHTMLMediaElement.instance.currentSrc_Getter_(this);

  @DomName('HTMLMediaElement.currentTime')
  @DocsEditable()
  num get currentTime => _blink.BlinkHTMLMediaElement.instance.currentTime_Getter_(this);

  @DomName('HTMLMediaElement.currentTime')
  @DocsEditable()
  void set currentTime(num value) => _blink.BlinkHTMLMediaElement.instance.currentTime_Setter_(this, value);

  @DomName('HTMLMediaElement.defaultMuted')
  @DocsEditable()
  bool get defaultMuted => _blink.BlinkHTMLMediaElement.instance.defaultMuted_Getter_(this);

  @DomName('HTMLMediaElement.defaultMuted')
  @DocsEditable()
  void set defaultMuted(bool value) => _blink.BlinkHTMLMediaElement.instance.defaultMuted_Setter_(this, value);

  @DomName('HTMLMediaElement.defaultPlaybackRate')
  @DocsEditable()
  num get defaultPlaybackRate => _blink.BlinkHTMLMediaElement.instance.defaultPlaybackRate_Getter_(this);

  @DomName('HTMLMediaElement.defaultPlaybackRate')
  @DocsEditable()
  void set defaultPlaybackRate(num value) => _blink.BlinkHTMLMediaElement.instance.defaultPlaybackRate_Setter_(this, value);

  @DomName('HTMLMediaElement.duration')
  @DocsEditable()
  double get duration => _blink.BlinkHTMLMediaElement.instance.duration_Getter_(this);

  @DomName('HTMLMediaElement.ended')
  @DocsEditable()
  bool get ended => _blink.BlinkHTMLMediaElement.instance.ended_Getter_(this);

  @DomName('HTMLMediaElement.error')
  @DocsEditable()
  MediaError get error => _blink.BlinkHTMLMediaElement.instance.error_Getter_(this);

  @DomName('HTMLMediaElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String get integrity => _blink.BlinkHTMLMediaElement.instance.integrity_Getter_(this);

  @DomName('HTMLMediaElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  void set integrity(String value) => _blink.BlinkHTMLMediaElement.instance.integrity_Setter_(this, value);

  @DomName('HTMLMediaElement.loop')
  @DocsEditable()
  bool get loop => _blink.BlinkHTMLMediaElement.instance.loop_Getter_(this);

  @DomName('HTMLMediaElement.loop')
  @DocsEditable()
  void set loop(bool value) => _blink.BlinkHTMLMediaElement.instance.loop_Setter_(this, value);

  @DomName('HTMLMediaElement.mediaGroup')
  @DocsEditable()
  String get mediaGroup => _blink.BlinkHTMLMediaElement.instance.mediaGroup_Getter_(this);

  @DomName('HTMLMediaElement.mediaGroup')
  @DocsEditable()
  void set mediaGroup(String value) => _blink.BlinkHTMLMediaElement.instance.mediaGroup_Setter_(this, value);

  @DomName('HTMLMediaElement.mediaKeys')
  @DocsEditable()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html
  @Experimental()
  MediaKeys get mediaKeys => _blink.BlinkHTMLMediaElement.instance.mediaKeys_Getter_(this);

  @DomName('HTMLMediaElement.muted')
  @DocsEditable()
  bool get muted => _blink.BlinkHTMLMediaElement.instance.muted_Getter_(this);

  @DomName('HTMLMediaElement.muted')
  @DocsEditable()
  void set muted(bool value) => _blink.BlinkHTMLMediaElement.instance.muted_Setter_(this, value);

  @DomName('HTMLMediaElement.networkState')
  @DocsEditable()
  int get networkState => _blink.BlinkHTMLMediaElement.instance.networkState_Getter_(this);

  @DomName('HTMLMediaElement.paused')
  @DocsEditable()
  bool get paused => _blink.BlinkHTMLMediaElement.instance.paused_Getter_(this);

  @DomName('HTMLMediaElement.playbackRate')
  @DocsEditable()
  num get playbackRate => _blink.BlinkHTMLMediaElement.instance.playbackRate_Getter_(this);

  @DomName('HTMLMediaElement.playbackRate')
  @DocsEditable()
  void set playbackRate(num value) => _blink.BlinkHTMLMediaElement.instance.playbackRate_Setter_(this, value);

  @DomName('HTMLMediaElement.played')
  @DocsEditable()
  TimeRanges get played => _blink.BlinkHTMLMediaElement.instance.played_Getter_(this);

  @DomName('HTMLMediaElement.preload')
  @DocsEditable()
  String get preload => _blink.BlinkHTMLMediaElement.instance.preload_Getter_(this);

  @DomName('HTMLMediaElement.preload')
  @DocsEditable()
  void set preload(String value) => _blink.BlinkHTMLMediaElement.instance.preload_Setter_(this, value);

  @DomName('HTMLMediaElement.readyState')
  @DocsEditable()
  int get readyState => _blink.BlinkHTMLMediaElement.instance.readyState_Getter_(this);

  @DomName('HTMLMediaElement.seekable')
  @DocsEditable()
  TimeRanges get seekable => _blink.BlinkHTMLMediaElement.instance.seekable_Getter_(this);

  @DomName('HTMLMediaElement.seeking')
  @DocsEditable()
  bool get seeking => _blink.BlinkHTMLMediaElement.instance.seeking_Getter_(this);

  @DomName('HTMLMediaElement.src')
  @DocsEditable()
  String get src => _blink.BlinkHTMLMediaElement.instance.src_Getter_(this);

  @DomName('HTMLMediaElement.src')
  @DocsEditable()
  void set src(String value) => _blink.BlinkHTMLMediaElement.instance.src_Setter_(this, value);

  @DomName('HTMLMediaElement.textTracks')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-media-texttracks
  @Experimental()
  TextTrackList get textTracks => _blink.BlinkHTMLMediaElement.instance.textTracks_Getter_(this);

  @DomName('HTMLMediaElement.videoTracks')
  @DocsEditable()
  @Experimental() // untriaged
  VideoTrackList get videoTracks => _blink.BlinkHTMLMediaElement.instance.videoTracks_Getter_(this);

  @DomName('HTMLMediaElement.volume')
  @DocsEditable()
  num get volume => _blink.BlinkHTMLMediaElement.instance.volume_Getter_(this);

  @DomName('HTMLMediaElement.volume')
  @DocsEditable()
  void set volume(num value) => _blink.BlinkHTMLMediaElement.instance.volume_Setter_(this, value);

  @DomName('HTMLMediaElement.webkitAudioDecodedByteCount')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // nonstandard
  int get audioDecodedByteCount => _blink.BlinkHTMLMediaElement.instance.webkitAudioDecodedByteCount_Getter_(this);

  @DomName('HTMLMediaElement.webkitVideoDecodedByteCount')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // nonstandard
  int get videoDecodedByteCount => _blink.BlinkHTMLMediaElement.instance.webkitVideoDecodedByteCount_Getter_(this);

  TextTrack addTextTrack(String kind, [String label, String language]) {
    if (language != null) {
      return _blink.BlinkHTMLMediaElement.instance.addTextTrack_Callback_3_(this, kind, label, language);
    }
    if (label != null) {
      return _blink.BlinkHTMLMediaElement.instance.addTextTrack_Callback_2_(this, kind, label);
    }
    return _blink.BlinkHTMLMediaElement.instance.addTextTrack_Callback_1_(this, kind);
  }

  String canPlayType(String type, [String keySystem]) {
    if (keySystem != null) {
      return _blink.BlinkHTMLMediaElement.instance.canPlayType_Callback_2_(this, type, keySystem);
    }
    return _blink.BlinkHTMLMediaElement.instance.canPlayType_Callback_1_(this, type);
  }

  @DomName('HTMLMediaElement.load')
  @DocsEditable()
  void load() => _blink.BlinkHTMLMediaElement.instance.load_Callback_0_(this);

  @DomName('HTMLMediaElement.pause')
  @DocsEditable()
  void pause() => _blink.BlinkHTMLMediaElement.instance.pause_Callback_0_(this);

  @DomName('HTMLMediaElement.play')
  @DocsEditable()
  void play() => _blink.BlinkHTMLMediaElement.instance.play_Callback_0_(this);

  @DomName('HTMLMediaElement.setMediaKeys')
  @DocsEditable()
  @Experimental() // untriaged
  void setMediaKeys(MediaKeys mediaKeys) => _blink.BlinkHTMLMediaElement.instance.setMediaKeys_Callback_1_(this, mediaKeys);

  void addKey(String keySystem, Uint8List key, [Uint8List initData, String sessionId]) {
    if (initData != null) {
      _blink.BlinkHTMLMediaElement.instance.webkitAddKey_Callback_4_(this, keySystem, key, initData, sessionId);
      return;
    }
    _blink.BlinkHTMLMediaElement.instance.webkitAddKey_Callback_2_(this, keySystem, key);
    return;
  }

  @DomName('HTMLMediaElement.webkitCancelKeyRequest')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#extensions
  void cancelKeyRequest(String keySystem, String sessionId) => _blink.BlinkHTMLMediaElement.instance.webkitCancelKeyRequest_Callback_2_(this, keySystem, sessionId);

  void generateKeyRequest(String keySystem, [Uint8List initData]) {
    if (initData != null) {
      _blink.BlinkHTMLMediaElement.instance.webkitGenerateKeyRequest_Callback_2_(this, keySystem, initData);
      return;
    }
    _blink.BlinkHTMLMediaElement.instance.webkitGenerateKeyRequest_Callback_1_(this, keySystem);
    return;
  }

  /// Stream of `keyadded` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onwebkitkeyadded')
  @DocsEditable()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  @Experimental()
  ElementStream<MediaKeyEvent> get onKeyAdded => keyAddedEvent.forElement(this);

  /// Stream of `keyerror` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onwebkitkeyerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  @Experimental()
  ElementStream<MediaKeyEvent> get onKeyError => keyErrorEvent.forElement(this);

  /// Stream of `keymessage` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onwebkitkeymessage')
  @DocsEditable()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  @Experimental()
  ElementStream<MediaKeyEvent> get onKeyMessage => keyMessageEvent.forElement(this);

  /// Stream of `needkey` events handled by this [MediaElement].
  @DomName('HTMLMediaElement.onwebkitneedkey')
  @DocsEditable()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  @Experimental()
  ElementStream<MediaKeyEvent> get onNeedKey => needKeyEvent.forElement(this);

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

// WARNING: Do not edit - generated code.


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

  @DomName('MediaError.MEDIA_ERR_ABORTED')
  @DocsEditable()
  static const int MEDIA_ERR_ABORTED = 1;

  @DomName('MediaError.MEDIA_ERR_DECODE')
  @DocsEditable()
  static const int MEDIA_ERR_DECODE = 3;

  @DomName('MediaError.MEDIA_ERR_ENCRYPTED')
  @DocsEditable()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#error-codes
  @Experimental()
  static const int MEDIA_ERR_ENCRYPTED = 5;

  @DomName('MediaError.MEDIA_ERR_NETWORK')
  @DocsEditable()
  static const int MEDIA_ERR_NETWORK = 2;

  @DomName('MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED')
  @DocsEditable()
  static const int MEDIA_ERR_SRC_NOT_SUPPORTED = 4;

  @DomName('MediaError.code')
  @DocsEditable()
  int get code => _blink.BlinkMediaError.instance.code_Getter_(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.


@DocsEditable()
@DomName('MediaKeyError')
// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#error-codes
@Experimental()
class MediaKeyError extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory MediaKeyError._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaKeyError.MEDIA_KEYERR_CLIENT')
  @DocsEditable()
  static const int MEDIA_KEYERR_CLIENT = 2;

  @DomName('MediaKeyError.MEDIA_KEYERR_DOMAIN')
  @DocsEditable()
  static const int MEDIA_KEYERR_DOMAIN = 6;

  @DomName('MediaKeyError.MEDIA_KEYERR_HARDWARECHANGE')
  @DocsEditable()
  static const int MEDIA_KEYERR_HARDWARECHANGE = 5;

  @DomName('MediaKeyError.MEDIA_KEYERR_OUTPUT')
  @DocsEditable()
  static const int MEDIA_KEYERR_OUTPUT = 4;

  @DomName('MediaKeyError.MEDIA_KEYERR_SERVICE')
  @DocsEditable()
  static const int MEDIA_KEYERR_SERVICE = 3;

  @DomName('MediaKeyError.MEDIA_KEYERR_UNKNOWN')
  @DocsEditable()
  static const int MEDIA_KEYERR_UNKNOWN = 1;

  @DomName('MediaKeyError.code')
  @DocsEditable()
  int get code => _blink.BlinkMediaKeyError.instance.code_Getter_(this);

  @DomName('MediaKeyError.systemCode')
  @DocsEditable()
  @Experimental() // non-standard
  int get systemCode => _blink.BlinkMediaKeyError.instance.systemCode_Getter_(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.


@DocsEditable()
@DomName('MediaKeyEvent')
// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#event-definitions
@Experimental()
class MediaKeyEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MediaKeyEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaKeyEvent.defaultURL')
  @DocsEditable()
  String get defaultUrl => _blink.BlinkMediaKeyEvent.instance.defaultURL_Getter_(this);

  @DomName('MediaKeyEvent.errorCode')
  @DocsEditable()
  MediaKeyError get errorCode => _blink.BlinkMediaKeyEvent.instance.errorCode_Getter_(this);

  @DomName('MediaKeyEvent.initData')
  @DocsEditable()
  Uint8List get initData => _blink.BlinkMediaKeyEvent.instance.initData_Getter_(this);

  @DomName('MediaKeyEvent.keySystem')
  @DocsEditable()
  String get keySystem => _blink.BlinkMediaKeyEvent.instance.keySystem_Getter_(this);

  @DomName('MediaKeyEvent.message')
  @DocsEditable()
  Uint8List get message => _blink.BlinkMediaKeyEvent.instance.message_Getter_(this);

  @DomName('MediaKeyEvent.sessionId')
  @DocsEditable()
  String get sessionId => _blink.BlinkMediaKeyEvent.instance.sessionId_Getter_(this);

  @DomName('MediaKeyEvent.systemCode')
  @DocsEditable()
  int get systemCode => _blink.BlinkMediaKeyEvent.instance.systemCode_Getter_(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.


@DocsEditable()
@DomName('MediaKeyMessageEvent')
// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-mediakeymessageevent
@Experimental()
class MediaKeyMessageEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MediaKeyMessageEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaKeyMessageEvent.destinationURL')
  @DocsEditable()
  String get destinationUrl => _blink.BlinkMediaKeyMessageEvent.instance.destinationURL_Getter_(this);

  @DomName('MediaKeyMessageEvent.message')
  @DocsEditable()
  ByteBuffer get message => _blink.BlinkMediaKeyMessageEvent.instance.message_Getter_(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.


@DocsEditable()
@DomName('MediaKeyNeededEvent')
// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-mediakeyneededevent
@Experimental()
class MediaKeyNeededEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MediaKeyNeededEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaKeyNeededEvent.contentType')
  @DocsEditable()
  @Experimental() // untriaged
  String get contentType => _blink.BlinkMediaKeyNeededEvent.instance.contentType_Getter_(this);

  @DomName('MediaKeyNeededEvent.initData')
  @DocsEditable()
  Uint8List get initData => _blink.BlinkMediaKeyNeededEvent.instance.initData_Getter_(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.


@DocsEditable()
@DomName('MediaKeySession')
// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-mediakeysession
@Experimental()
class MediaKeySession extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaKeySession._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaKeySession.closed')
  @DocsEditable()
  @Experimental() // untriaged
  Future get closed => _blink.BlinkMediaKeySession.instance.closed_Getter_(this);

  @DomName('MediaKeySession.error')
  @DocsEditable()
  MediaKeyError get error => _blink.BlinkMediaKeySession.instance.error_Getter_(this);

  @DomName('MediaKeySession.keySystem')
  @DocsEditable()
  String get keySystem => _blink.BlinkMediaKeySession.instance.keySystem_Getter_(this);

  @DomName('MediaKeySession.sessionId')
  @DocsEditable()
  String get sessionId => _blink.BlinkMediaKeySession.instance.sessionId_Getter_(this);

  @DomName('MediaKeySession.release')
  @DocsEditable()
  @Experimental() // untriaged
  Future release() => _blink.BlinkMediaKeySession.instance.release_Callback_0_(this);

  Future _update(response) {
    if ((response is TypedData)) {
      return _blink.BlinkMediaKeySession.instance.update_Callback_1_(this, response);
    }
    if ((response is ByteBuffer)) {
      return _blink.BlinkMediaKeySession.instance.update_Callback_1_(this, response);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


@DocsEditable()
@DomName('MediaKeys')
// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html
@Experimental()
class MediaKeys extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory MediaKeys._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaKeys.keySystem')
  @DocsEditable()
  String get keySystem => _blink.BlinkMediaKeys.instance.keySystem_Getter_(this);

  @DomName('MediaKeys.create')
  @DocsEditable()
  @Experimental() // untriaged
  static Future create(String keySystem) => _blink.BlinkMediaKeys.instance.create_Callback_1_(keySystem);

  Future _createSession(String initDataType, initData, [String sessionType]) {
    if ((initData is TypedData) && (initDataType is String) && sessionType == null) {
      return _blink.BlinkMediaKeys.instance.createSession_Callback_2_(this, initDataType, initData);
    }
    if ((sessionType is String || sessionType == null) && (initData is TypedData) && (initDataType is String)) {
      return _blink.BlinkMediaKeys.instance.createSession_Callback_3_(this, initDataType, initData, sessionType);
    }
    if ((initData is ByteBuffer) && (initDataType is String) && sessionType == null) {
      return _blink.BlinkMediaKeys.instance.createSession_Callback_2_(this, initDataType, initData);
    }
    if ((sessionType is String || sessionType == null) && (initData is ByteBuffer) && (initDataType is String)) {
      return _blink.BlinkMediaKeys.instance.createSession_Callback_3_(this, initDataType, initData, sessionType);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('MediaKeys.isTypeSupported')
  @DocsEditable()
  @Experimental() // untriaged
  static bool isTypeSupported(String keySystem, String contentType) => _blink.BlinkMediaKeys.instance.isTypeSupported_Callback_2_(keySystem, contentType);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

  @DomName('MediaList.length')
  @DocsEditable()
  int get length => _blink.BlinkMediaList.instance.length_Getter_(this);

  @DomName('MediaList.mediaText')
  @DocsEditable()
  String get mediaText => _blink.BlinkMediaList.instance.mediaText_Getter_(this);

  @DomName('MediaList.mediaText')
  @DocsEditable()
  void set mediaText(String value) => _blink.BlinkMediaList.instance.mediaText_Setter_(this, value);

  @DomName('MediaList.appendMedium')
  @DocsEditable()
  void appendMedium(String newMedium) => _blink.BlinkMediaList.instance.appendMedium_Callback_1_(this, newMedium);

  @DomName('MediaList.deleteMedium')
  @DocsEditable()
  void deleteMedium(String oldMedium) => _blink.BlinkMediaList.instance.deleteMedium_Callback_1_(this, oldMedium);

  @DomName('MediaList.item')
  @DocsEditable()
  String item(int index) => _blink.BlinkMediaList.instance.item_Callback_1_(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.


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

  @DomName('MediaQueryList.matches')
  @DocsEditable()
  bool get matches => _blink.BlinkMediaQueryList.instance.matches_Getter_(this);

  @DomName('MediaQueryList.media')
  @DocsEditable()
  String get media => _blink.BlinkMediaQueryList.instance.media_Getter_(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.


@DocsEditable()
@DomName('MediaSource')
// https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#mediasource
@Experimental()
class MediaSource extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaSource._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaSource.MediaSource')
  @DocsEditable()
  factory MediaSource() {
    return _blink.BlinkMediaSource.instance.constructorCallback_0_();
  }

  @DomName('MediaSource.activeSourceBuffers')
  @DocsEditable()
  SourceBufferList get activeSourceBuffers => _blink.BlinkMediaSource.instance.activeSourceBuffers_Getter_(this);

  @DomName('MediaSource.duration')
  @DocsEditable()
  num get duration => _blink.BlinkMediaSource.instance.duration_Getter_(this);

  @DomName('MediaSource.duration')
  @DocsEditable()
  void set duration(num value) => _blink.BlinkMediaSource.instance.duration_Setter_(this, value);

  @DomName('MediaSource.readyState')
  @DocsEditable()
  String get readyState => _blink.BlinkMediaSource.instance.readyState_Getter_(this);

  @DomName('MediaSource.sourceBuffers')
  @DocsEditable()
  SourceBufferList get sourceBuffers => _blink.BlinkMediaSource.instance.sourceBuffers_Getter_(this);

  @DomName('MediaSource.addSourceBuffer')
  @DocsEditable()
  SourceBuffer addSourceBuffer(String type) => _blink.BlinkMediaSource.instance.addSourceBuffer_Callback_1_(this, type);

  void endOfStream([String error]) {
    if (error != null) {
      _blink.BlinkMediaSource.instance.endOfStream_Callback_1_(this, error);
      return;
    }
    _blink.BlinkMediaSource.instance.endOfStream_Callback_0_(this);
    return;
  }

  @DomName('MediaSource.isTypeSupported')
  @DocsEditable()
  static bool isTypeSupported(String type) => _blink.BlinkMediaSource.instance.isTypeSupported_Callback_1_(type);

  @DomName('MediaSource.removeSourceBuffer')
  @DocsEditable()
  void removeSourceBuffer(SourceBuffer buffer) => _blink.BlinkMediaSource.instance.removeSourceBuffer_Callback_1_(this, buffer);

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


@DomName('MediaStream')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html#mediastream
class MediaStream extends EventTarget {
  // 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 _blink.BlinkMediaStream.instance.constructorCallback_0_();
    }
    if ((stream_OR_tracks is MediaStream || stream_OR_tracks == null)) {
      return _blink.BlinkMediaStream.instance.constructorCallback_1_(stream_OR_tracks);
    }
    if ((stream_OR_tracks is List<MediaStreamTrack> || stream_OR_tracks == null)) {
      return _blink.BlinkMediaStream.instance.constructorCallback_1_(stream_OR_tracks);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('MediaStream.ended')
  @DocsEditable()
  bool get ended => _blink.BlinkMediaStream.instance.ended_Getter_(this);

  @DomName('MediaStream.id')
  @DocsEditable()
  String get id => _blink.BlinkMediaStream.instance.id_Getter_(this);

  @DomName('MediaStream.label')
  @DocsEditable()
  @Experimental() // non-standard
  String get label => _blink.BlinkMediaStream.instance.label_Getter_(this);

  @DomName('MediaStream.addTrack')
  @DocsEditable()
  void addTrack(MediaStreamTrack track) => _blink.BlinkMediaStream.instance.addTrack_Callback_1_(this, track);

  @DomName('MediaStream.clone')
  @DocsEditable()
  @Experimental() // untriaged
  MediaStream clone() => _blink.BlinkMediaStream.instance.clone_Callback_0_(this);

  @DomName('MediaStream.getAudioTracks')
  @DocsEditable()
  List<MediaStreamTrack> getAudioTracks() => _blink.BlinkMediaStream.instance.getAudioTracks_Callback_0_(this);

  @DomName('MediaStream.getTrackById')
  @DocsEditable()
  MediaStreamTrack getTrackById(String trackId) => _blink.BlinkMediaStream.instance.getTrackById_Callback_1_(this, trackId);

  @DomName('MediaStream.getTracks')
  @DocsEditable()
  @Experimental() // untriaged
  List<MediaStreamTrack> getTracks() => _blink.BlinkMediaStream.instance.getTracks_Callback_0_(this);

  @DomName('MediaStream.getVideoTracks')
  @DocsEditable()
  List<MediaStreamTrack> getVideoTracks() => _blink.BlinkMediaStream.instance.getVideoTracks_Callback_0_(this);

  @DomName('MediaStream.removeTrack')
  @DocsEditable()
  void removeTrack(MediaStreamTrack track) => _blink.BlinkMediaStream.instance.removeTrack_Callback_1_(this, track);

  @DomName('MediaStream.stop')
  @DocsEditable()
  void stop() => _blink.BlinkMediaStream.instance.stop_Callback_0_(this);

  /// 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 => true;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


@DocsEditable()
@DomName('MediaStreamEvent')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html
class MediaStreamEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MediaStreamEvent._() { throw new UnsupportedError("Not supported"); }

  /// Checks if this type is supported on the current platform.
  static bool get supported => true;

  @DomName('MediaStreamEvent.stream')
  @DocsEditable()
  MediaStream get stream => _blink.BlinkMediaStreamEvent.instance.stream_Getter_(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.


@DocsEditable()
@DomName('MediaStreamTrack')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html#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 get enabled => _blink.BlinkMediaStreamTrack.instance.enabled_Getter_(this);

  @DomName('MediaStreamTrack.enabled')
  @DocsEditable()
  void set enabled(bool value) => _blink.BlinkMediaStreamTrack.instance.enabled_Setter_(this, value);

  @DomName('MediaStreamTrack.id')
  @DocsEditable()
  String get id => _blink.BlinkMediaStreamTrack.instance.id_Getter_(this);

  @DomName('MediaStreamTrack.kind')
  @DocsEditable()
  String get kind => _blink.BlinkMediaStreamTrack.instance.kind_Getter_(this);

  @DomName('MediaStreamTrack.label')
  @DocsEditable()
  String get label => _blink.BlinkMediaStreamTrack.instance.label_Getter_(this);

  @DomName('MediaStreamTrack.muted')
  @DocsEditable()
  @Experimental() // untriaged
  bool get muted => _blink.BlinkMediaStreamTrack.instance.muted_Getter_(this);

  @DomName('MediaStreamTrack.readyState')
  @DocsEditable()
  String get readyState => _blink.BlinkMediaStreamTrack.instance.readyState_Getter_(this);

  @DomName('MediaStreamTrack.clone')
  @DocsEditable()
  @Experimental() // untriaged
  MediaStreamTrack clone() => _blink.BlinkMediaStreamTrack.instance.clone_Callback_0_(this);

  @DomName('MediaStreamTrack.getSources')
  @DocsEditable()
  @Experimental() // untriaged
  static void _getSources(MediaStreamTrackSourcesCallback callback) => _blink.BlinkMediaStreamTrack.instance.getSources_Callback_1_(callback);

  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() => _blink.BlinkMediaStreamTrack.instance.stop_Callback_0_(this);

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

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('MediaStreamTrackEvent')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html
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 => true;

  @DomName('MediaStreamTrackEvent.track')
  @DocsEditable()
  MediaStreamTrack get track => _blink.BlinkMediaStreamTrackEvent.instance.track_Getter_(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('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.

// WARNING: Do not edit - generated code.


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

  @DomName('MemoryInfo.jsHeapSizeLimit')
  @DocsEditable()
  int get jsHeapSizeLimit => _blink.BlinkMemoryInfo.instance.jsHeapSizeLimit_Getter_(this);

  @DomName('MemoryInfo.totalJSHeapSize')
  @DocsEditable()
  int get totalJSHeapSize => _blink.BlinkMemoryInfo.instance.totalJSHeapSize_Getter_(this);

  @DomName('MemoryInfo.usedJSHeapSize')
  @DocsEditable()
  int get usedJSHeapSize => _blink.BlinkMemoryInfo.instance.usedJSHeapSize_Getter_(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.


@DocsEditable()
/**
 * An HTML <menu> element.
 *
 * A <menu> element represents an unordered list of menu commands.
 *
 * See also:
 *
 *  * [Menu Element](https://developer.mozilla.org/en-US/docs/HTML/Element/menu) from MDN.
 *  * [Menu Element](http://www.w3.org/TR/html5/the-menu-element.html#the-menu-element) from the W3C.
 */
@DomName('HTMLMenuElement')
class MenuElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory MenuElement._() { throw new UnsupportedError("Not supported"); }

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

  @DomName('HTMLMenuElement.label')
  @DocsEditable()
  @Experimental() // untriaged
  String get label => _blink.BlinkHTMLMenuElement.instance.label_Getter_(this);

  @DomName('HTMLMenuElement.label')
  @DocsEditable()
  @Experimental() // untriaged
  void set label(String value) => _blink.BlinkHTMLMenuElement.instance.label_Setter_(this, value);

  @DomName('HTMLMenuElement.type')
  @DocsEditable()
  @Experimental() // untriaged
  String get type => _blink.BlinkHTMLMenuElement.instance.type_Getter_(this);

  @DomName('HTMLMenuElement.type')
  @DocsEditable()
  @Experimental() // untriaged
  void set type(String value) => _blink.BlinkHTMLMenuElement.instance.type_Setter_(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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('HTMLMenuItemElement')
@Experimental() // untriaged
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 get checked => _blink.BlinkHTMLMenuItemElement.instance.checked_Getter_(this);

  @DomName('HTMLMenuItemElement.checked')
  @DocsEditable()
  @Experimental() // untriaged
  void set checked(bool value) => _blink.BlinkHTMLMenuItemElement.instance.checked_Setter_(this, value);

  @DomName('HTMLMenuItemElement.default')
  @DocsEditable()
  @Experimental() // untriaged
  bool get defaultValue => _blink.BlinkHTMLMenuItemElement.instance.default_Getter_(this);

  @DomName('HTMLMenuItemElement.default')
  @DocsEditable()
  @Experimental() // untriaged
  void set defaultValue(bool value) => _blink.BlinkHTMLMenuItemElement.instance.default_Setter_(this, value);

  @DomName('HTMLMenuItemElement.disabled')
  @DocsEditable()
  @Experimental() // untriaged
  bool get disabled => _blink.BlinkHTMLMenuItemElement.instance.disabled_Getter_(this);

  @DomName('HTMLMenuItemElement.disabled')
  @DocsEditable()
  @Experimental() // untriaged
  void set disabled(bool value) => _blink.BlinkHTMLMenuItemElement.instance.disabled_Setter_(this, value);

  @DomName('HTMLMenuItemElement.label')
  @DocsEditable()
  @Experimental() // untriaged
  String get label => _blink.BlinkHTMLMenuItemElement.instance.label_Getter_(this);

  @DomName('HTMLMenuItemElement.label')
  @DocsEditable()
  @Experimental() // untriaged
  void set label(String value) => _blink.BlinkHTMLMenuItemElement.instance.label_Setter_(this, value);

  @DomName('HTMLMenuItemElement.type')
  @DocsEditable()
  @Experimental() // untriaged
  String get type => _blink.BlinkHTMLMenuItemElement.instance.type_Getter_(this);

  @DomName('HTMLMenuItemElement.type')
  @DocsEditable()
  @Experimental() // untriaged
  void set type(String value) => _blink.BlinkHTMLMenuItemElement.instance.type_Setter_(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.

// WARNING: Do not edit - generated code.


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

  @DomName('MessageChannel.port1')
  @DocsEditable()
  MessagePort get port1 => _blink.BlinkMessageChannel.instance.port1_Getter_(this);

  @DomName('MessageChannel.port2')
  @DocsEditable()
  MessagePort get port2 => _blink.BlinkMessageChannel.instance.port2_Getter_(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.

// WARNING: Do not edit - generated code.


@DomName('MessageEvent')
class MessageEvent extends Event {
  factory MessageEvent(String type,
      {bool canBubble: false, bool cancelable: false, Object data,
      String origin, String lastEventId,
      Window source, List messagePorts}) {
    if (source == null) {
      source = window;
    }
    var event = document._createEvent("MessageEvent");
    event._initMessageEvent(type, canBubble, cancelable, data, origin,
        lastEventId, source, messagePorts);
    return event;
  }
  // To suppress missing implicit constructor warnings.
  factory MessageEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('MessageEvent.data')
  @DocsEditable()
  Object get data => _blink.BlinkMessageEvent.instance.data_Getter_(this);

  @DomName('MessageEvent.lastEventId')
  @DocsEditable()
  @Unstable()
  String get lastEventId => _blink.BlinkMessageEvent.instance.lastEventId_Getter_(this);

  @DomName('MessageEvent.origin')
  @DocsEditable()
  String get origin => _blink.BlinkMessageEvent.instance.origin_Getter_(this);

  @DomName('MessageEvent.source')
  @DocsEditable()
  EventTarget get source => _blink.BlinkMessageEvent.instance.source_Getter_(this);

  @DomName('MessageEvent.initMessageEvent')
  @DocsEditable()
  void _initMessageEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Object dataArg, String originArg, String lastEventIdArg, Window sourceArg, List<MessagePort> messagePorts) => _blink.BlinkMessageEvent.instance.initMessageEvent_Callback_8_(this, typeArg, canBubbleArg, cancelableArg, dataArg, originArg, lastEventIdArg, sourceArg, messagePorts);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


@DocsEditable()
@DomName('MessagePort')
@Unstable()
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() => _blink.BlinkMessagePort.instance.close_Callback_0_(this);

  @DomName('MessagePort.postMessage')
  @DocsEditable()
  void postMessage(Object message, [List<MessagePort> transfer]) => _blink.BlinkMessagePort.instance.postMessage_Callback_2_(this, message, transfer);

  @DomName('MessagePort.start')
  @DocsEditable()
  void start() => _blink.BlinkMessagePort.instance.start_Callback_0_(this);

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

// WARNING: Do not edit - generated code.


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

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

  @DomName('HTMLMetaElement.content')
  @DocsEditable()
  String get content => _blink.BlinkHTMLMetaElement.instance.content_Getter_(this);

  @DomName('HTMLMetaElement.content')
  @DocsEditable()
  void set content(String value) => _blink.BlinkHTMLMetaElement.instance.content_Setter_(this, value);

  @DomName('HTMLMetaElement.httpEquiv')
  @DocsEditable()
  String get httpEquiv => _blink.BlinkHTMLMetaElement.instance.httpEquiv_Getter_(this);

  @DomName('HTMLMetaElement.httpEquiv')
  @DocsEditable()
  void set httpEquiv(String value) => _blink.BlinkHTMLMetaElement.instance.httpEquiv_Setter_(this, value);

  @DomName('HTMLMetaElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLMetaElement.instance.name_Getter_(this);

  @DomName('HTMLMetaElement.name')
  @DocsEditable()
  void set name(String value) => _blink.BlinkHTMLMetaElement.instance.name_Setter_(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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('Metadata')
// http://www.w3.org/TR/file-system-api/#the-metadata-interface
@Experimental()
class Metadata extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory Metadata._() { throw new UnsupportedError("Not supported"); }

  @DomName('Metadata.modificationTime')
  @DocsEditable()
  DateTime get modificationTime => _blink.BlinkMetadata.instance.modificationTime_Getter_(this);

  @DomName('Metadata.size')
  @DocsEditable()
  int get size => _blink.BlinkMetadata.instance.size_Getter_(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('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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('HTMLMeterElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
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 => true;

  @DomName('HTMLMeterElement.high')
  @DocsEditable()
  num get high => _blink.BlinkHTMLMeterElement.instance.high_Getter_(this);

  @DomName('HTMLMeterElement.high')
  @DocsEditable()
  void set high(num value) => _blink.BlinkHTMLMeterElement.instance.high_Setter_(this, value);

  @DomName('HTMLMeterElement.labels')
  @DocsEditable()
  @Unstable()
  List<Node> get labels => _blink.BlinkHTMLMeterElement.instance.labels_Getter_(this);

  @DomName('HTMLMeterElement.low')
  @DocsEditable()
  num get low => _blink.BlinkHTMLMeterElement.instance.low_Getter_(this);

  @DomName('HTMLMeterElement.low')
  @DocsEditable()
  void set low(num value) => _blink.BlinkHTMLMeterElement.instance.low_Setter_(this, value);

  @DomName('HTMLMeterElement.max')
  @DocsEditable()
  num get max => _blink.BlinkHTMLMeterElement.instance.max_Getter_(this);

  @DomName('HTMLMeterElement.max')
  @DocsEditable()
  void set max(num value) => _blink.BlinkHTMLMeterElement.instance.max_Setter_(this, value);

  @DomName('HTMLMeterElement.min')
  @DocsEditable()
  num get min => _blink.BlinkHTMLMeterElement.instance.min_Getter_(this);

  @DomName('HTMLMeterElement.min')
  @DocsEditable()
  void set min(num value) => _blink.BlinkHTMLMeterElement.instance.min_Setter_(this, value);

  @DomName('HTMLMeterElement.optimum')
  @DocsEditable()
  num get optimum => _blink.BlinkHTMLMeterElement.instance.optimum_Getter_(this);

  @DomName('HTMLMeterElement.optimum')
  @DocsEditable()
  void set optimum(num value) => _blink.BlinkHTMLMeterElement.instance.optimum_Setter_(this, value);

  @DomName('HTMLMeterElement.value')
  @DocsEditable()
  num get value => _blink.BlinkHTMLMeterElement.instance.value_Getter_(this);

  @DomName('HTMLMeterElement.value')
  @DocsEditable()
  void set value(num value) => _blink.BlinkHTMLMeterElement.instance.value_Setter_(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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('MIDIAccess')
// http://webaudio.github.io/web-midi-api/#midiaccess-interface
@Experimental()
class MidiAccess extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MidiAccess._() { throw new UnsupportedError("Not supported"); }

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

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

  @DomName('MIDIAccess.sysexEnabled')
  @DocsEditable()
  @Experimental() // untriaged
  bool get sysexEnabled => _blink.BlinkMIDIAccess.instance.sysexEnabled_Getter_(this);

  @DomName('MIDIAccess.inputs')
  @DocsEditable()
  List<MidiInput> inputs() => _blink.BlinkMIDIAccess.instance.inputs_Callback_0_(this);

  @DomName('MIDIAccess.outputs')
  @DocsEditable()
  List<MidiOutput> outputs() => _blink.BlinkMIDIAccess.instance.outputs_Callback_0_(this);

  /// Stream of `connect` events handled by this [MidiAccess].
  @DomName('MIDIAccess.onconnect')
  @DocsEditable()
  Stream<MidiConnectionEvent> get onConnect => connectEvent.forTarget(this);

  /// Stream of `disconnect` events handled by this [MidiAccess].
  @DomName('MIDIAccess.ondisconnect')
  @DocsEditable()
  Stream<MidiConnectionEvent> get onDisconnect => disconnectEvent.forTarget(this);

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

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('MIDIConnectionEvent')
// http://webaudio.github.io/web-midi-api/#midiconnectionevent-interface
@Experimental()
class MidiConnectionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MidiConnectionEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('MIDIConnectionEvent.port')
  @DocsEditable()
  MidiPort get port => _blink.BlinkMIDIConnectionEvent.instance.port_Getter_(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.


@DocsEditable()
@DomName('MIDIInput')
// http://webaudio.github.io/web-midi-api/#idl-def-MIDIInput
@Experimental()
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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('MIDIMessageEvent')
// http://webaudio.github.io/web-midi-api/#midimessageevent-interface
@Experimental()
class MidiMessageEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MidiMessageEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('MIDIMessageEvent.data')
  @DocsEditable()
  Uint8List get data => _blink.BlinkMIDIMessageEvent.instance.data_Getter_(this);

  @DomName('MIDIMessageEvent.receivedTime')
  @DocsEditable()
  double get receivedTime => _blink.BlinkMIDIMessageEvent.instance.receivedTime_Getter_(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.


@DocsEditable()
@DomName('MIDIOutput')
// http://webaudio.github.io/web-midi-api/#midioutput-interface
@Experimental()
class MidiOutput extends MidiPort {
  // To suppress missing implicit constructor warnings.
  factory MidiOutput._() { throw new UnsupportedError("Not supported"); }

  void send(Uint8List data, [num timestamp]) {
    if (timestamp != null) {
      _blink.BlinkMIDIOutput.instance.send_Callback_2_(this, data, timestamp);
      return;
    }
    _blink.BlinkMIDIOutput.instance.send_Callback_1_(this, data);
    return;
  }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


@DocsEditable()
@DomName('MIDIPort')
// http://webaudio.github.io/web-midi-api/#idl-def-MIDIPort
@Experimental()
class MidiPort extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MidiPort._() { throw new UnsupportedError("Not supported"); }

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

  @DomName('MIDIPort.id')
  @DocsEditable()
  String get id => _blink.BlinkMIDIPort.instance.id_Getter_(this);

  @DomName('MIDIPort.manufacturer')
  @DocsEditable()
  String get manufacturer => _blink.BlinkMIDIPort.instance.manufacturer_Getter_(this);

  @DomName('MIDIPort.name')
  @DocsEditable()
  String get name => _blink.BlinkMIDIPort.instance.name_Getter_(this);

  @DomName('MIDIPort.type')
  @DocsEditable()
  String get type => _blink.BlinkMIDIPort.instance.type_Getter_(this);

  @DomName('MIDIPort.version')
  @DocsEditable()
  String get version => _blink.BlinkMIDIPort.instance.version_Getter_(this);

  /// Stream of `disconnect` events handled by this [MidiPort].
  @DomName('MIDIPort.ondisconnect')
  @DocsEditable()
  Stream<MidiConnectionEvent> get onDisconnect => disconnectEvent.forTarget(this);

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

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('MimeType')
@Experimental() // non-standard
class MimeType extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory MimeType._() { throw new UnsupportedError("Not supported"); }

  @DomName('MimeType.description')
  @DocsEditable()
  String get description => _blink.BlinkMimeType.instance.description_Getter_(this);

  @DomName('MimeType.enabledPlugin')
  @DocsEditable()
  Plugin get enabledPlugin => _blink.BlinkMimeType.instance.enabledPlugin_Getter_(this);

  @DomName('MimeType.suffixes')
  @DocsEditable()
  String get suffixes => _blink.BlinkMimeType.instance.suffixes_Getter_(this);

  @DomName('MimeType.type')
  @DocsEditable()
  String get type => _blink.BlinkMimeType.instance.type_Getter_(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.


@DocsEditable()
@DomName('MimeTypeArray')
@Experimental() // non-standard
class MimeTypeArray extends NativeFieldWrapperClass2 with ListMixin<MimeType>, ImmutableListMixin<MimeType> implements List<MimeType> {
  // To suppress missing implicit constructor warnings.
  factory MimeTypeArray._() { throw new UnsupportedError("Not supported"); }

  @DomName('MimeTypeArray.length')
  @DocsEditable()
  int get length => _blink.BlinkMimeTypeArray.instance.length_Getter_(this);

  MimeType operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return _blink.BlinkMimeTypeArray.instance.item_Callback_1_(this, index);
  }

  MimeType _nativeIndexedGetter(int index) => _blink.BlinkMimeTypeArray.instance.item_Callback_1_(this, index);

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


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

  MimeType get first {
    if (this.length > 0) {
      return _nativeIndexedGetter(0);
    }
    throw new StateError("No elements");
  }

  MimeType get last {
    int len = this.length;
    if (len > 0) {
      return _nativeIndexedGetter(len - 1);
    }
    throw new StateError("No elements");
  }

  MimeType get single {
    int len = this.length;
    if (len == 1) {
      return _nativeIndexedGetter(0);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

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

  @DomName('MimeTypeArray.__getter__')
  @DocsEditable()
  MimeType __getter__(String name) => _blink.BlinkMimeTypeArray.instance.$__getter___Callback_1_(this, name);

  @DomName('MimeTypeArray.item')
  @DocsEditable()
  MimeType item(int index) => _blink.BlinkMimeTypeArray.instance.item_Callback_1_(this, index);

  @DomName('MimeTypeArray.namedItem')
  @DocsEditable()
  MimeType namedItem(String name) => _blink.BlinkMimeTypeArray.instance.namedItem_Callback_1_(this, 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.


@DocsEditable()
@DomName('HTMLModElement')
@Unstable()
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 get cite => _blink.BlinkHTMLModElement.instance.cite_Getter_(this);

  @DomName('HTMLModElement.cite')
  @DocsEditable()
  void set cite(String value) => _blink.BlinkHTMLModElement.instance.cite_Setter_(this, value);

  @DomName('HTMLModElement.dateTime')
  @DocsEditable()
  String get dateTime => _blink.BlinkHTMLModElement.instance.dateTime_Getter_(this);

  @DomName('HTMLModElement.dateTime')
  @DocsEditable()
  void set dateTime(String value) => _blink.BlinkHTMLModElement.instance.dateTime_Setter_(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.

// WARNING: Do not edit - generated code.


@DomName('MouseEvent')
class MouseEvent extends UIEvent {
  factory MouseEvent(String type,
      {Window view, int detail: 0, int screenX: 0, int screenY: 0,
      int clientX: 0, int clientY: 0, int button: 0, bool canBubble: true,
      bool cancelable: true, bool ctrlKey: false, bool altKey: false,
      bool shiftKey: false, bool metaKey: false, EventTarget relatedTarget}) {

    if (view == null) {
      view = window;
    }
    var event = document._createEvent('MouseEvent');
    event._initMouseEvent(type, canBubble, cancelable, view, detail,
        screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey,
        button, relatedTarget);
    return event;
  }
  // To suppress missing implicit constructor warnings.
  factory MouseEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('MouseEvent.altKey')
  @DocsEditable()
  bool get altKey => _blink.BlinkMouseEvent.instance.altKey_Getter_(this);

  @DomName('MouseEvent.button')
  @DocsEditable()
  int get button => _blink.BlinkMouseEvent.instance.button_Getter_(this);

  @DomName('MouseEvent.clientX')
  @DocsEditable()
  int get _clientX => _blink.BlinkMouseEvent.instance.clientX_Getter_(this);

  @DomName('MouseEvent.clientY')
  @DocsEditable()
  int get _clientY => _blink.BlinkMouseEvent.instance.clientY_Getter_(this);

  @DomName('MouseEvent.ctrlKey')
  @DocsEditable()
  bool get ctrlKey => _blink.BlinkMouseEvent.instance.ctrlKey_Getter_(this);

  @DomName('MouseEvent.dataTransfer')
  @DocsEditable()
  @Unstable()
  DataTransfer get dataTransfer => _blink.BlinkMouseEvent.instance.dataTransfer_Getter_(this);

  /**
   * 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
  Node get fromElement => _blink.BlinkMouseEvent.instance.fromElement_Getter_(this);

  @DomName('MouseEvent.metaKey')
  @DocsEditable()
  bool get metaKey => _blink.BlinkMouseEvent.instance.metaKey_Getter_(this);

  @DomName('MouseEvent.movementX')
  @DocsEditable()
  @Experimental() // untriaged
  int get _movementX => _blink.BlinkMouseEvent.instance.movementX_Getter_(this);

  @DomName('MouseEvent.movementY')
  @DocsEditable()
  @Experimental() // untriaged
  int get _movementY => _blink.BlinkMouseEvent.instance.movementY_Getter_(this);

  @DomName('MouseEvent.offsetX')
  @DocsEditable()
  @Unstable()
  int get _offsetX => _blink.BlinkMouseEvent.instance.offsetX_Getter_(this);

  @DomName('MouseEvent.offsetY')
  @DocsEditable()
  @Unstable()
  int get _offsetY => _blink.BlinkMouseEvent.instance.offsetY_Getter_(this);

  @DomName('MouseEvent.region')
  @DocsEditable()
  @Experimental() // untriaged
  String get region => _blink.BlinkMouseEvent.instance.region_Getter_(this);

  @DomName('MouseEvent.relatedTarget')
  @DocsEditable()
  EventTarget get relatedTarget => _blink.BlinkMouseEvent.instance.relatedTarget_Getter_(this);

  @DomName('MouseEvent.screenX')
  @DocsEditable()
  int get _screenX => _blink.BlinkMouseEvent.instance.screenX_Getter_(this);

  @DomName('MouseEvent.screenY')
  @DocsEditable()
  int get _screenY => _blink.BlinkMouseEvent.instance.screenY_Getter_(this);

  @DomName('MouseEvent.shiftKey')
  @DocsEditable()
  bool get shiftKey => _blink.BlinkMouseEvent.instance.shiftKey_Getter_(this);

  /**
   * 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
  Node get toElement => _blink.BlinkMouseEvent.instance.toElement_Getter_(this);

  @DomName('MouseEvent.webkitMovementX')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  int get _webkitMovementX => _blink.BlinkMouseEvent.instance.webkitMovementX_Getter_(this);

  @DomName('MouseEvent.webkitMovementY')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  int get _webkitMovementY => _blink.BlinkMouseEvent.instance.webkitMovementY_Getter_(this);

  @DomName('MouseEvent.initMouseEvent')
  @DocsEditable()
  void _initMouseEvent(String type, bool canBubble, bool cancelable, Window view, int detail, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, int button, EventTarget relatedTarget) => _blink.BlinkMouseEvent.instance.initMouseEvent_Callback_15_(this, type, canBubble, cancelable, view, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget);


  @deprecated
  int get clientX => client.x;
  @deprecated
  int get clientY => client.y;
  @deprecated
  int get offsetX => offset.x;
  @deprecated
  int get offsetY => offset.y;
  @deprecated
  int get movementX => movement.x;
  @deprecated
  int get movementY => movement.y;
  @deprecated
  int get screenX => screen.x;
  @deprecated
  int get screenY => screen.y;

  @DomName('MouseEvent.clientX')
  @DomName('MouseEvent.clientY')
  Point get client => new Point(_clientX, _clientY);

  @DomName('MouseEvent.movementX')
  @DomName('MouseEvent.movementY')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  Point get movement => new Point(_webkitMovementX, _webkitMovementY);

  /**
   * The coordinates of the mouse pointer in target node coordinates.
   *
   * This value may vary between platforms if the target node moves
   * after the event has fired or if the element has CSS transforms affecting
   * it.
   */
  Point get offset => new Point(_offsetX, _offsetY);

  @DomName('MouseEvent.screenX')
  @DomName('MouseEvent.screenY')
  Point get screen => new Point(_screenX, _screenY);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('MutationCallback')
typedef void MutationCallback(List<MutationRecord> mutations, MutationObserver observer);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('MutationObserver')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
class MutationObserver extends NativeFieldWrapperClass2 {

  @DomName('MutationObserver.MutationObserver')
  @DocsEditable()
  factory MutationObserver._(MutationCallback callback) => _create(callback);

  @DocsEditable()
  static MutationObserver _create(callback) => _blink.BlinkMutationObserver.instance.constructorCallback_1_(callback);

  @DomName('MutationObserver.disconnect')
  @DocsEditable()
  void disconnect() => _blink.BlinkMutationObserver.instance.disconnect_Callback_0_(this);

  @DomName('MutationObserver.observe')
  @DocsEditable()
  void _observe(Node target, Map options) => _blink.BlinkMutationObserver.instance.observe_Callback_2_(this, target, options);

  @DomName('MutationObserver.takeRecords')
  @DocsEditable()
  List<MutationRecord> takeRecords() => _blink.BlinkMutationObserver.instance.takeRecords_Callback_0_(this);

  /**
   * Checks to see if the mutation observer API is supported on the current
   * platform.
   */
  static bool get supported {
    return true;
  }

  /**
   * 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() => {};
  static _add(m, String key, value) { m[key] = value; }
  static _fixupList(list) => list;

  void _call(Node target, options) {
    _observe(target, options);
  }

  factory MutationObserver(MutationCallback callback) =>
      new MutationObserver._(_wrapBinaryZone(callback));
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

  @DomName('MutationRecord.addedNodes')
  @DocsEditable()
  List<Node> get addedNodes => _blink.BlinkMutationRecord.instance.addedNodes_Getter_(this);

  @DomName('MutationRecord.attributeName')
  @DocsEditable()
  String get attributeName => _blink.BlinkMutationRecord.instance.attributeName_Getter_(this);

  @DomName('MutationRecord.attributeNamespace')
  @DocsEditable()
  String get attributeNamespace => _blink.BlinkMutationRecord.instance.attributeNamespace_Getter_(this);

  @DomName('MutationRecord.nextSibling')
  @DocsEditable()
  Node get nextSibling => _blink.BlinkMutationRecord.instance.nextSibling_Getter_(this);

  @DomName('MutationRecord.oldValue')
  @DocsEditable()
  String get oldValue => _blink.BlinkMutationRecord.instance.oldValue_Getter_(this);

  @DomName('MutationRecord.previousSibling')
  @DocsEditable()
  Node get previousSibling => _blink.BlinkMutationRecord.instance.previousSibling_Getter_(this);

  @DomName('MutationRecord.removedNodes')
  @DocsEditable()
  List<Node> get removedNodes => _blink.BlinkMutationRecord.instance.removedNodes_Getter_(this);

  @DomName('MutationRecord.target')
  @DocsEditable()
  Node get target => _blink.BlinkMutationRecord.instance.target_Getter_(this);

  @DomName('MutationRecord.type')
  @DocsEditable()
  String get type => _blink.BlinkMutationRecord.instance.type_Getter_(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('Navigator')
class Navigator extends NativeFieldWrapperClass2 implements NavigatorCpu, NavigatorLanguage, NavigatorOnLine, NavigatorID {


  /**
   * 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
    };
    this._getUserMedia(options,
      (stream) {
        completer.complete(stream);
      },
      (error) {
        completer.completeError(error);
      });
    return completer.future;
  }


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

  @DomName('Navigator.connection')
  @DocsEditable()
  @Experimental() // untriaged
  NetworkInformation get connection => _blink.BlinkNavigator.instance.connection_Getter_(this);

  @DomName('Navigator.cookieEnabled')
  @DocsEditable()
  @Unstable()
  bool get cookieEnabled => _blink.BlinkNavigator.instance.cookieEnabled_Getter_(this);

  @DomName('Navigator.credentials')
  @DocsEditable()
  @Experimental() // untriaged
  CredentialsContainer get credentials => _blink.BlinkNavigator.instance.credentials_Getter_(this);

  @DomName('Navigator.doNotTrack')
  @DocsEditable()
  // http://www.w3.org/2011/tracking-protection/drafts/tracking-dnt.html#js-dom
  @Experimental() // experimental
  String get doNotTrack => _blink.BlinkNavigator.instance.doNotTrack_Getter_(this);

  @DomName('Navigator.geofencing')
  @DocsEditable()
  @Experimental() // untriaged
  Geofencing get geofencing => _blink.BlinkNavigator.instance.geofencing_Getter_(this);

  @DomName('Navigator.geolocation')
  @DocsEditable()
  @Unstable()
  Geolocation get geolocation => _blink.BlinkNavigator.instance.geolocation_Getter_(this);

  @DomName('Navigator.maxTouchPoints')
  @DocsEditable()
  @Experimental() // untriaged
  int get maxTouchPoints => _blink.BlinkNavigator.instance.maxTouchPoints_Getter_(this);

  @DomName('Navigator.mimeTypes')
  @DocsEditable()
  @Experimental() // nonstandard
  MimeTypeArray get mimeTypes => _blink.BlinkNavigator.instance.mimeTypes_Getter_(this);

  @DomName('Navigator.productSub')
  @DocsEditable()
  @Unstable()
  String get productSub => _blink.BlinkNavigator.instance.productSub_Getter_(this);

  @DomName('Navigator.push')
  @DocsEditable()
  @Experimental() // untriaged
  PushManager get push => _blink.BlinkNavigator.instance.push_Getter_(this);

  @DomName('Navigator.serviceWorker')
  @DocsEditable()
  @Experimental() // untriaged
  ServiceWorkerContainer get serviceWorker => _blink.BlinkNavigator.instance.serviceWorker_Getter_(this);

  @DomName('Navigator.storageQuota')
  @DocsEditable()
  @Experimental() // untriaged
  StorageQuota get storageQuota => _blink.BlinkNavigator.instance.storageQuota_Getter_(this);

  @DomName('Navigator.vendor')
  @DocsEditable()
  @Unstable()
  String get vendor => _blink.BlinkNavigator.instance.vendor_Getter_(this);

  @DomName('Navigator.vendorSub')
  @DocsEditable()
  @Unstable()
  String get vendorSub => _blink.BlinkNavigator.instance.vendorSub_Getter_(this);

  @DomName('Navigator.webkitPersistentStorage')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.w3.org/TR/quota-api/#accessing-storagequota
  DeprecatedStorageQuota get persistentStorage => _blink.BlinkNavigator.instance.webkitPersistentStorage_Getter_(this);

  @DomName('Navigator.webkitTemporaryStorage')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.w3.org/TR/quota-api/#accessing-storagequota
  DeprecatedStorageQuota get temporaryStorage => _blink.BlinkNavigator.instance.webkitTemporaryStorage_Getter_(this);

  @DomName('Navigator.getBattery')
  @DocsEditable()
  @Experimental() // untriaged
  Future getBattery() => _blink.BlinkNavigator.instance.getBattery_Callback_0_(this);

  @DomName('Navigator.getGamepads')
  @DocsEditable()
  @Experimental() // untriaged
  List<Gamepad> getGamepads() => _blink.BlinkNavigator.instance.getGamepads_Callback_0_(this);

  @DomName('Navigator.getStorageUpdates')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#navigatorstorageutils
  @Experimental()
  void getStorageUpdates() => _blink.BlinkNavigator.instance.getStorageUpdates_Callback_0_(this);

  @DomName('Navigator.isProtocolHandlerRegistered')
  @DocsEditable()
  @Experimental() // untriaged
  String isProtocolHandlerRegistered(String scheme, String url) => _blink.BlinkNavigator.instance.isProtocolHandlerRegistered_Callback_2_(this, scheme, url);

  @DomName('Navigator.registerProtocolHandler')
  @DocsEditable()
  @Unstable()
  void registerProtocolHandler(String scheme, String url, String title) => _blink.BlinkNavigator.instance.registerProtocolHandler_Callback_3_(this, scheme, url, title);

  bool sendBeacon(String url, data) {
    if ((data is String || data == null) && (url is String || url == null)) {
      return _blink.BlinkNavigator.instance.sendBeacon_Callback_2_(this, url, data);
    }
    if ((data is TypedData || data == null) && (url is String || url == null)) {
      return _blink.BlinkNavigator.instance.sendBeacon_Callback_2_(this, url, data);
    }
    if ((data is FormData || data == null) && (url is String || url == null)) {
      return _blink.BlinkNavigator.instance.sendBeacon_Callback_2_(this, url, data);
    }
    if ((data is Blob || data == null) && (url is String || url == null)) {
      return _blink.BlinkNavigator.instance.sendBeacon_Callback_2_(this, url, data);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('Navigator.unregisterProtocolHandler')
  @DocsEditable()
  @Experimental() // untriaged
  void unregisterProtocolHandler(String scheme, String url) => _blink.BlinkNavigator.instance.unregisterProtocolHandler_Callback_2_(this, scheme, url);

  @DomName('Navigator.webkitGetUserMedia')
  @DocsEditable()
  // http://dev.w3.org/2011/webrtc/editor/getusermedia.html#navigatorusermedia
  @Experimental()
  void _getUserMedia(Map options, _NavigatorUserMediaSuccessCallback successCallback, _NavigatorUserMediaErrorCallback errorCallback) => _blink.BlinkNavigator.instance.webkitGetUserMedia_Callback_3_(this, options, successCallback, errorCallback);

  @DomName('Navigator.hardwareConcurrency')
  @DocsEditable()
  @Experimental() // untriaged
  int get hardwareConcurrency => _blink.BlinkNavigator.instance.hardwareConcurrency_Getter_(this);

  @DomName('Navigator.appCodeName')
  @DocsEditable()
  @Experimental() // non-standard
  String get appCodeName => _blink.BlinkNavigator.instance.appCodeName_Getter_(this);

  @DomName('Navigator.appName')
  @DocsEditable()
  String get appName => _blink.BlinkNavigator.instance.appName_Getter_(this);

  @DomName('Navigator.appVersion')
  @DocsEditable()
  String get appVersion => _blink.BlinkNavigator.instance.appVersion_Getter_(this);

  @DomName('Navigator.dartEnabled')
  @DocsEditable()
  @Experimental() // untriaged
  bool get dartEnabled => _blink.BlinkNavigator.instance.dartEnabled_Getter_(this);

  @DomName('Navigator.platform')
  @DocsEditable()
  String get platform => _blink.BlinkNavigator.instance.platform_Getter_(this);

  @DomName('Navigator.product')
  @DocsEditable()
  @Unstable()
  String get product => _blink.BlinkNavigator.instance.product_Getter_(this);

  @DomName('Navigator.userAgent')
  @DocsEditable()
  String get userAgent => _blink.BlinkNavigator.instance.userAgent_Getter_(this);

  @DomName('Navigator.language')
  @DocsEditable()
  String get language => _blink.BlinkNavigator.instance.language_Getter_(this);

  @DomName('Navigator.languages')
  @DocsEditable()
  @Experimental() // untriaged
  List<String> get languages => _blink.BlinkNavigator.instance.languages_Getter_(this);

  @DomName('Navigator.onLine')
  @DocsEditable()
  @Unstable()
  bool get onLine => _blink.BlinkNavigator.instance.onLine_Getter_(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.


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

  @DomName('NavigatorCPU.hardwareConcurrency')
  @DocsEditable()
  @Experimental() // untriaged
  int get 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.

// WARNING: Do not edit - generated code.


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

  @DomName('NavigatorID.appCodeName')
  @DocsEditable()
  @Experimental() // untriaged
  String get appCodeName;

  @DomName('NavigatorID.appName')
  @DocsEditable()
  @Experimental() // untriaged
  String get appName;

  @DomName('NavigatorID.appVersion')
  @DocsEditable()
  @Experimental() // untriaged
  String get appVersion;

  @DomName('NavigatorID.dartEnabled')
  @DocsEditable()
  @Experimental() // untriaged
  bool get dartEnabled;

  @DomName('NavigatorID.platform')
  @DocsEditable()
  @Experimental() // untriaged
  String get platform;

  @DomName('NavigatorID.product')
  @DocsEditable()
  @Experimental() // untriaged
  String get product;

  @DomName('NavigatorID.userAgent')
  @DocsEditable()
  @Experimental() // untriaged
  String get 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.

// WARNING: Do not edit - generated code.


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

  @DomName('NavigatorLanguage.language')
  @DocsEditable()
  @Experimental() // untriaged
  String get language;

  @DomName('NavigatorLanguage.languages')
  @DocsEditable()
  @Experimental() // untriaged
  List<String> get 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.

// WARNING: Do not edit - generated code.


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

  @DomName('NavigatorOnLine.onLine')
  @DocsEditable()
  @Experimental() // untriaged
  bool get 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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('NavigatorUserMediaError')
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html#idl-def-NavigatorUserMediaError
@Experimental()
class NavigatorUserMediaError extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory NavigatorUserMediaError._() { throw new UnsupportedError("Not supported"); }

  @DomName('NavigatorUserMediaError.constraintName')
  @DocsEditable()
  String get constraintName => _blink.BlinkNavigatorUserMediaError.instance.constraintName_Getter_(this);

  @DomName('NavigatorUserMediaError.message')
  @DocsEditable()
  String get message => _blink.BlinkNavigatorUserMediaError.instance.message_Getter_(this);

  @DomName('NavigatorUserMediaError.name')
  @DocsEditable()
  String get name => _blink.BlinkNavigatorUserMediaError.instance.name_Getter_(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('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.

// WARNING: Do not edit - generated code.


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

  @DomName('NetworkInformation.type')
  @DocsEditable()
  @Experimental() // untriaged
  String get type => _blink.BlinkNetworkInformation.instance.type_Getter_(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 = _this.firstChild;
    if (result == null) throw new StateError("No elements");
    return result;
  }
  Node get last {
    Node result = _this.lastChild;
    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 _this.firstChild;
  }

  void add(Node value) {
    _this.append(value);
  }

  void addAll(Iterable<Node> iterable) {
    if (iterable is _ChildNodeListLazy) {
      _ChildNodeListLazy otherList = iterable;
      if (!identical(otherList._this, _this)) {
        // Optimized route for copying between nodes.
        for (var i = 0, len = otherList.length; i < len; ++i) {
          _this.append(otherList._this.firstChild);
        }
      }
      return;
    }
    for (Node node in iterable) {
      _this.append(node);
    }
  }

  void insert(int index, Node node) {
    if (index < 0 || index > length) {
      throw new RangeError.range(index, 0, length);
    }
    if (index == length) {
      _this.append(node);
    } else {
      _this.insertBefore(node, this[index]);
    }
  }

  void insertAll(int index, Iterable<Node> iterable) {
    if (index == length) {
      addAll(iterable);
    } else {
      var item = this[index];
      _this.insertAllBefore(iterable, item);
    }
  }

  void setAll(int index, Iterable<Node> iterable) {
    throw new UnsupportedError("Cannot setAll on Node list");
  }

  Node removeLast() {
    final result = last;
    if (result != null) {
      _this._removeChild(result);
    }
    return result;
  }

  Node removeAt(int index) {
    var result = this[index];
    if (result != null) {
      _this._removeChild(result);
    }
    return result;
  }

  bool remove(Object object) {
    if (object is! Node) return false;
    Node node = object;
    if (!identical(_this, node.parentNode)) return false;
    _this._removeChild(node);
    return true;
  }

  void _filter(bool test(Node node), bool removeMatching) {
    // This implementation of removeWhere/retainWhere is more efficient
    // than the default in ListBase. Child nodes can be removed in constant
    // time.
    Node child = _this.firstChild;
    while (child != null) {
      Node nextChild = child.nextNode;
      if (test(child) == removeMatching) {
        _this._removeChild(child);
      }
      child = nextChild;
    }
  }

  void removeWhere(bool test(Node node)) {
    _filter(test, true);
  }

  void retainWhere(bool test(Node node)) {
    _filter(test, false);
  }

  void clear() {
    _this._clearChildren();
  }

  void operator []=(int index, Node value) {
    _this._replaceChild(value, this[index]);
  }

  Iterator<Node> get iterator => _this.childNodes.iterator;

  // From List<Node>:

  // TODO(jacobr): this could be implemented for child node lists.
  // The exception we throw here is misleading.
  void sort([Comparator<Node> compare]) {
    throw new UnsupportedError("Cannot sort Node list");
  }

  void shuffle([Random random]) {
    throw new UnsupportedError("Cannot shuffle Node list");
  }

  // FIXME: implement these.
  void setRange(int start, int end, Iterable<Node> iterable,
                [int skipCount = 0]) {
    throw new UnsupportedError("Cannot setRange on Node list");
  }

  void fillRange(int start, int end, [Node fill]) {
    throw new UnsupportedError("Cannot fillRange on Node list");
  }
  // -- end List<Node> mixins.

  // TODO(jacobr): benchmark whether this is more efficient or whether caching
  // a local copy of childNodes is more efficient.
  int get length => _this.childNodes.length;

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

  Node operator[](int index) => _this.childNodes[index];

  List<Node> get rawList => _this.childNodes;
}


@DomName('Node')
class Node extends EventTarget {

  // Custom element created callback.
  Node._created() : super._created();

  /**
   * A modifiable list of this node's children.
   */
  List<Node> get nodes {
    return new _ChildNodeListLazy(this);
  }

  void set nodes(Iterable<Node> value) {
    // Copy list first since we don't want liveness during iteration.
    // TODO(jacobr): there is a better way to do this.
    List copy = new List.from(value);
    text = '';
    for (Node node in copy) {
      append(node);
    }
  }

  /**
   * Removes this node from the DOM.
   */
  @DomName('Node.removeChild')
  void remove() {
    // TODO(jacobr): should we throw an exception if parent is already null?
    // TODO(vsm): Use the native remove when available.
    if (this.parentNode != null) {
      final Node parent = this.parentNode;
      parentNode._removeChild(this);
    }
  }

  /**
   * Replaces this node with another node.
   */
  @DomName('Node.replaceChild')
  Node replaceWith(Node otherNode) {
    try {
      final Node parent = this.parentNode;
      parent._replaceChild(otherNode, this);
    } catch (e) {

    };
    return this;
  }

  /**
   * Inserts all of the nodes into this node directly before refChild.
   *
   * See also:
   *
   * * [insertBefore]
   */
  Node insertAllBefore(Iterable<Node> newNodes, Node refChild) {
    if (newNodes is _ChildNodeListLazy) {
      _ChildNodeListLazy otherList = newNodes;
      if (identical(otherList._this, this)) {
        throw new ArgumentError(newNodes);
      }

      // Optimized route for copying between nodes.
      for (var i = 0, len = otherList.length; i < len; ++i) {
        this.insertBefore(otherList._this.firstChild, refChild);
      }
    } else {
      for (var node in newNodes) {
        this.insertBefore(node, refChild);
      }
    }
  }

  void _clearChildren() {
    while (firstChild != null) {
      _removeChild(firstChild);
    }
  }

  /**
   * Print out a String representation of this Node.
   */
  String toString() => nodeValue == null ? super.toString() : nodeValue;
  // To suppress missing implicit constructor warnings.
  factory Node._() { throw new UnsupportedError("Not supported"); }

  @DomName('Node.ATTRIBUTE_NODE')
  @DocsEditable()
  static const int ATTRIBUTE_NODE = 2;

  @DomName('Node.CDATA_SECTION_NODE')
  @DocsEditable()
  static const int CDATA_SECTION_NODE = 4;

  @DomName('Node.COMMENT_NODE')
  @DocsEditable()
  static const int COMMENT_NODE = 8;

  @DomName('Node.DOCUMENT_FRAGMENT_NODE')
  @DocsEditable()
  static const int DOCUMENT_FRAGMENT_NODE = 11;

  @DomName('Node.DOCUMENT_NODE')
  @DocsEditable()
  static const int DOCUMENT_NODE = 9;

  @DomName('Node.DOCUMENT_TYPE_NODE')
  @DocsEditable()
  static const int DOCUMENT_TYPE_NODE = 10;

  @DomName('Node.ELEMENT_NODE')
  @DocsEditable()
  static const int ELEMENT_NODE = 1;

  @DomName('Node.ENTITY_NODE')
  @DocsEditable()
  static const int ENTITY_NODE = 6;

  @DomName('Node.ENTITY_REFERENCE_NODE')
  @DocsEditable()
  static const int ENTITY_REFERENCE_NODE = 5;

  @DomName('Node.NOTATION_NODE')
  @DocsEditable()
  static const int NOTATION_NODE = 12;

  @DomName('Node.PROCESSING_INSTRUCTION_NODE')
  @DocsEditable()
  static const int PROCESSING_INSTRUCTION_NODE = 7;

  @DomName('Node.TEXT_NODE')
  @DocsEditable()
  static const int TEXT_NODE = 3;

  @DomName('Node.baseURI')
  @DocsEditable()
  String get baseUri => _blink.BlinkNode.instance.baseURI_Getter_(this);

  /**
   * 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()
  List<Node> get childNodes => _blink.BlinkNode.instance.childNodes_Getter_(this);

  /**
   * 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()
  Node get firstChild => _blink.BlinkNode.instance.firstChild_Getter_(this);

  /**
   * 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()
  Node get lastChild => _blink.BlinkNode.instance.lastChild_Getter_(this);

  @DomName('Node.localName')
  @DocsEditable()
  String get _localName => _blink.BlinkNode.instance.localName_Getter_(this);

  @DomName('Node.namespaceURI')
  @DocsEditable()
  String get _namespaceUri => _blink.BlinkNode.instance.namespaceURI_Getter_(this);

  /**
   * 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()
  Node get nextNode => _blink.BlinkNode.instance.nextSibling_Getter_(this);

  /**
   * 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()
  String get nodeName => _blink.BlinkNode.instance.nodeName_Getter_(this);

  /**
   * 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()
  int get nodeType => _blink.BlinkNode.instance.nodeType_Getter_(this);

  /**
   * 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()
  String get nodeValue => _blink.BlinkNode.instance.nodeValue_Getter_(this);

  /**
   * 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()
  Document get ownerDocument => _blink.BlinkNode.instance.ownerDocument_Getter_(this);

  /**
   * 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()
  Element get parent => _blink.BlinkNode.instance.parentElement_Getter_(this);

  /**
   * 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()
  Node get parentNode => _blink.BlinkNode.instance.parentNode_Getter_(this);

  /**
   * 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()
  Node get previousNode => _blink.BlinkNode.instance.previousSibling_Getter_(this);

  /**
   * All text within this node and its decendents.
   *
   * ## Other resources
   *
   * * [Node.textContent]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent) from
   * MDN.
   */
  @DomName('Node.textContent')
  @DocsEditable()
  String get text => _blink.BlinkNode.instance.textContent_Getter_(this);

  /**
   * All text within this node and its decendents.
   *
   * ## Other resources
   *
   * * [Node.textContent]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent) from
   * MDN.
   */
  @DomName('Node.textContent')
  @DocsEditable()
  void set text(String value) => _blink.BlinkNode.instance.textContent_Setter_(this, value);

  /**
   * Adds a node to the end of the child [nodes] list of this node.
   *
   * If the node already exists in this document, it will be removed from its
   * current parent node, then added to this node.
   *
   * This method is more efficient than `nodes.add`, and is the preferred
   * way of appending a child node.
   */
  @DomName('Node.appendChild')
  @DocsEditable()
  Node append(Node newChild) => _blink.BlinkNode.instance.appendChild_Callback_1_(this, newChild);

  /**
   * Returns a copy of this node.
   *
   * If [deep] is `true`, then all of this node's children and decendents are
   * copied as well. If [deep] is `false`, then only this node is copied.
   *
   * ## Other resources
   *
   * * [Node.cloneNode]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.cloneNode) from
   * MDN.
   */
  @DomName('Node.cloneNode')
  @DocsEditable()
  Node clone(bool deep) => _blink.BlinkNode.instance.cloneNode_Callback_1_(this, deep);

  /**
   * 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) => _blink.BlinkNode.instance.contains_Callback_1_(this, other);

  /**
   * 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() => _blink.BlinkNode.instance.hasChildNodes_Callback_0_(this);

  /**
   * Inserts all of the nodes into this node directly before refChild.
   *
   * ## Other resources
   *
   * * [Node.insertBefore]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.insertBefore) from
   * MDN.
   */
  @DomName('Node.insertBefore')
  @DocsEditable()
  Node insertBefore(Node newChild, Node refChild) => _blink.BlinkNode.instance.insertBefore_Callback_2_(this, newChild, refChild);

  @DomName('Node.removeChild')
  @DocsEditable()
  Node _removeChild(Node oldChild) => _blink.BlinkNode.instance.removeChild_Callback_1_(this, oldChild);

  @DomName('Node.replaceChild')
  @DocsEditable()
  Node _replaceChild(Node newChild, Node oldChild) => _blink.BlinkNode.instance.replaceChild_Callback_2_(this, newChild, oldChild);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

  @DomName('NodeFilter.FILTER_ACCEPT')
  @DocsEditable()
  static const int FILTER_ACCEPT = 1;

  @DomName('NodeFilter.FILTER_REJECT')
  @DocsEditable()
  static const int FILTER_REJECT = 2;

  @DomName('NodeFilter.FILTER_SKIP')
  @DocsEditable()
  static const int FILTER_SKIP = 3;

  @DomName('NodeFilter.SHOW_ALL')
  @DocsEditable()
  static const int SHOW_ALL = 0xFFFFFFFF;

  @DomName('NodeFilter.SHOW_COMMENT')
  @DocsEditable()
  static const int SHOW_COMMENT = 0x00000080;

  @DomName('NodeFilter.SHOW_DOCUMENT')
  @DocsEditable()
  static const int SHOW_DOCUMENT = 0x00000100;

  @DomName('NodeFilter.SHOW_DOCUMENT_FRAGMENT')
  @DocsEditable()
  static const int SHOW_DOCUMENT_FRAGMENT = 0x00000400;

  @DomName('NodeFilter.SHOW_DOCUMENT_TYPE')
  @DocsEditable()
  static const int SHOW_DOCUMENT_TYPE = 0x00000200;

  @DomName('NodeFilter.SHOW_ELEMENT')
  @DocsEditable()
  static const int SHOW_ELEMENT = 0x00000001;

  @DomName('NodeFilter.SHOW_PROCESSING_INSTRUCTION')
  @DocsEditable()
  static const int SHOW_PROCESSING_INSTRUCTION = 0x00000040;

  @DomName('NodeFilter.SHOW_TEXT')
  @DocsEditable()
  static const int SHOW_TEXT = 0x00000004;

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


@DomName('NodeIterator')
@Unstable()
class NodeIterator extends NativeFieldWrapperClass2 {
  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()
  bool get pointerBeforeReferenceNode => _blink.BlinkNodeIterator.instance.pointerBeforeReferenceNode_Getter_(this);

  @DomName('NodeIterator.referenceNode')
  @DocsEditable()
  Node get referenceNode => _blink.BlinkNodeIterator.instance.referenceNode_Getter_(this);

  @DomName('NodeIterator.root')
  @DocsEditable()
  Node get root => _blink.BlinkNodeIterator.instance.root_Getter_(this);

  @DomName('NodeIterator.whatToShow')
  @DocsEditable()
  int get whatToShow => _blink.BlinkNodeIterator.instance.whatToShow_Getter_(this);

  @DomName('NodeIterator.detach')
  @DocsEditable()
  void detach() => _blink.BlinkNodeIterator.instance.detach_Callback_0_(this);

  @DomName('NodeIterator.nextNode')
  @DocsEditable()
  Node nextNode() => _blink.BlinkNodeIterator.instance.nextNode_Callback_0_(this);

  @DomName('NodeIterator.previousNode')
  @DocsEditable()
  Node previousNode() => _blink.BlinkNodeIterator.instance.previousNode_Callback_0_(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.


@DocsEditable()
@DomName('NodeList')
class NodeList extends NativeFieldWrapperClass2 with ListMixin<Node>, ImmutableListMixin<Node> implements List<Node> {
  // To suppress missing implicit constructor warnings.
  factory NodeList._() { throw new UnsupportedError("Not supported"); }

  @DomName('NodeList.length')
  @DocsEditable()
  int get length => _blink.BlinkNodeList.instance.length_Getter_(this);

  Node operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return _blink.BlinkNodeList.instance.item_Callback_1_(this, index);
  }

  Node _nativeIndexedGetter(int index) => _blink.BlinkNodeList.instance.item_Callback_1_(this, index);

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


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

  Node get first {
    if (this.length > 0) {
      return _nativeIndexedGetter(0);
    }
    throw new StateError("No elements");
  }

  Node get last {
    int len = this.length;
    if (len > 0) {
      return _nativeIndexedGetter(len - 1);
    }
    throw new StateError("No elements");
  }

  Node get single {
    int len = this.length;
    if (len == 1) {
      return _nativeIndexedGetter(0);
    }
    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('NodeList.item')
  @DocsEditable()
  Node _item(int index) => _blink.BlinkNodeList.instance.item_Callback_1_(this, index);

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


@DomName('Notification')
// http://www.w3.org/TR/notifications/#notification
@Experimental() // experimental
class Notification extends EventTarget {

  factory Notification(String title, {String titleDir: null, String body: null,
      String bodyDir: null, String tag: null, String iconUrl: null}) {

    var parsedOptions = {};
    if (titleDir != null) parsedOptions['titleDir'] = titleDir;
    if (body != null) parsedOptions['body'] = body;
    if (bodyDir != null) parsedOptions['bodyDir'] = bodyDir;
    if (tag != null) parsedOptions['tag'] = tag;
    if (iconUrl != null) parsedOptions['iconUrl'] = iconUrl;

    return Notification._factoryNotification(title, parsedOptions);
  }
  // To suppress missing implicit constructor warnings.
  factory Notification._() { throw new UnsupportedError("Not supported"); }

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

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

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

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

  @DomName('Notification.Notification')
  @DocsEditable()
  static Notification _factoryNotification(String title, [Map options]) {
    return _blink.BlinkNotification.instance.constructorCallback_2_(title, options);
  }

  @DomName('Notification.body')
  @DocsEditable()
  @Experimental() // untriaged
  String get body => _blink.BlinkNotification.instance.body_Getter_(this);

  @DomName('Notification.dir')
  @DocsEditable()
  @Experimental() // nonstandard
  String get dir => _blink.BlinkNotification.instance.dir_Getter_(this);

  @DomName('Notification.icon')
  @DocsEditable()
  @Experimental() // untriaged
  String get icon => _blink.BlinkNotification.instance.icon_Getter_(this);

  @DomName('Notification.lang')
  @DocsEditable()
  @Experimental() // untriaged
  String get lang => _blink.BlinkNotification.instance.lang_Getter_(this);

  @DomName('Notification.permission')
  @DocsEditable()
  String get permission => _blink.BlinkNotification.instance.permission_Getter_();

  @DomName('Notification.tag')
  @DocsEditable()
  @Experimental() // nonstandard
  String get tag => _blink.BlinkNotification.instance.tag_Getter_(this);

  @DomName('Notification.title')
  @DocsEditable()
  @Experimental() // untriaged
  String get title => _blink.BlinkNotification.instance.title_Getter_(this);

  @DomName('Notification.close')
  @DocsEditable()
  void close() => _blink.BlinkNotification.instance.close_Callback_0_(this);

  static void _requestPermission([_NotificationPermissionCallback callback]) {
    if (callback != null) {
      _blink.BlinkNotification.instance.requestPermission_Callback_1_(callback);
      return;
    }
    _blink.BlinkNotification.instance.requestPermission_Callback_0_();
    return;
  }

  static Future<String> requestPermission() {
    var completer = new Completer<String>();
    _requestPermission(
        (value) { completer.complete(value); });
    return completer.future;
  }

  /// Stream of `click` events handled by this [Notification].
  @DomName('Notification.onclick')
  @DocsEditable()
  Stream<Event> get onClick => clickEvent.forTarget(this);

  /// Stream of `close` events handled by this [Notification].
  @DomName('Notification.onclose')
  @DocsEditable()
  Stream<Event> get onClose => closeEvent.forTarget(this);

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

  /// Stream of `show` events handled by this [Notification].
  @DomName('Notification.onshow')
  @DocsEditable()
  Stream<Event> get onShow => showEvent.forTarget(this);

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

// WARNING: Do not edit - generated code.


@DomName('NotificationPermissionCallback')
// http://www.w3.org/TR/notifications/#notificationpermissioncallback
@Experimental()
typedef void _NotificationPermissionCallback(String permission);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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

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

  @DomName('HTMLOListElement.reversed')
  @DocsEditable()
  bool get reversed => _blink.BlinkHTMLOListElement.instance.reversed_Getter_(this);

  @DomName('HTMLOListElement.reversed')
  @DocsEditable()
  void set reversed(bool value) => _blink.BlinkHTMLOListElement.instance.reversed_Setter_(this, value);

  @DomName('HTMLOListElement.start')
  @DocsEditable()
  int get start => _blink.BlinkHTMLOListElement.instance.start_Getter_(this);

  @DomName('HTMLOListElement.start')
  @DocsEditable()
  void set start(int value) => _blink.BlinkHTMLOListElement.instance.start_Setter_(this, value);

  @DomName('HTMLOListElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLOListElement.instance.type_Getter_(this);

  @DomName('HTMLOListElement.type')
  @DocsEditable()
  void set type(String value) => _blink.BlinkHTMLOListElement.instance.type_Setter_(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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('HTMLObjectElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
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 => true;

  @DomName('HTMLObjectElement.data')
  @DocsEditable()
  String get data => _blink.BlinkHTMLObjectElement.instance.data_Getter_(this);

  @DomName('HTMLObjectElement.data')
  @DocsEditable()
  void set data(String value) => _blink.BlinkHTMLObjectElement.instance.data_Setter_(this, value);

  @DomName('HTMLObjectElement.form')
  @DocsEditable()
  FormElement get form => _blink.BlinkHTMLObjectElement.instance.form_Getter_(this);

  @DomName('HTMLObjectElement.height')
  @DocsEditable()
  String get height => _blink.BlinkHTMLObjectElement.instance.height_Getter_(this);

  @DomName('HTMLObjectElement.height')
  @DocsEditable()
  void set height(String value) => _blink.BlinkHTMLObjectElement.instance.height_Setter_(this, value);

  @DomName('HTMLObjectElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String get integrity => _blink.BlinkHTMLObjectElement.instance.integrity_Getter_(this);

  @DomName('HTMLObjectElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  void set integrity(String value) => _blink.BlinkHTMLObjectElement.instance.integrity_Setter_(this, value);

  @DomName('HTMLObjectElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLObjectElement.instance.name_Getter_(this);

  @DomName('HTMLObjectElement.name')
  @DocsEditable()
  void set name(String value) => _blink.BlinkHTMLObjectElement.instance.name_Setter_(this, value);

  @DomName('HTMLObjectElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLObjectElement.instance.type_Getter_(this);

  @DomName('HTMLObjectElement.type')
  @DocsEditable()
  void set type(String value) => _blink.BlinkHTMLObjectElement.instance.type_Setter_(this, value);

  @DomName('HTMLObjectElement.useMap')
  @DocsEditable()
  String get useMap => _blink.BlinkHTMLObjectElement.instance.useMap_Getter_(this);

  @DomName('HTMLObjectElement.useMap')
  @DocsEditable()
  void set useMap(String value) => _blink.BlinkHTMLObjectElement.instance.useMap_Setter_(this, value);

  @DomName('HTMLObjectElement.validationMessage')
  @DocsEditable()
  String get validationMessage => _blink.BlinkHTMLObjectElement.instance.validationMessage_Getter_(this);

  @DomName('HTMLObjectElement.validity')
  @DocsEditable()
  ValidityState get validity => _blink.BlinkHTMLObjectElement.instance.validity_Getter_(this);

  @DomName('HTMLObjectElement.width')
  @DocsEditable()
  String get width => _blink.BlinkHTMLObjectElement.instance.width_Getter_(this);

  @DomName('HTMLObjectElement.width')
  @DocsEditable()
  void set width(String value) => _blink.BlinkHTMLObjectElement.instance.width_Setter_(this, value);

  @DomName('HTMLObjectElement.willValidate')
  @DocsEditable()
  bool get willValidate => _blink.BlinkHTMLObjectElement.instance.willValidate_Getter_(this);

  @DomName('HTMLObjectElement.__getter__')
  @DocsEditable()
  bool __getter__(index_OR_name) => _blink.BlinkHTMLObjectElement.instance.$__getter___Callback_1_(this, index_OR_name);

  @DomName('HTMLObjectElement.__setter__')
  @DocsEditable()
  void __setter__(index_OR_name, Node value) => _blink.BlinkHTMLObjectElement.instance.$__setter___Callback_2_(this, index_OR_name, value);

  @DomName('HTMLObjectElement.checkValidity')
  @DocsEditable()
  bool checkValidity() => _blink.BlinkHTMLObjectElement.instance.checkValidity_Callback_0_(this);

  @DomName('HTMLObjectElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) => _blink.BlinkHTMLObjectElement.instance.setCustomValidity_Callback_1_(this, 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.


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

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

  @DomName('HTMLOptGroupElement.disabled')
  @DocsEditable()
  bool get disabled => _blink.BlinkHTMLOptGroupElement.instance.disabled_Getter_(this);

  @DomName('HTMLOptGroupElement.disabled')
  @DocsEditable()
  void set disabled(bool value) => _blink.BlinkHTMLOptGroupElement.instance.disabled_Setter_(this, value);

  @DomName('HTMLOptGroupElement.label')
  @DocsEditable()
  String get label => _blink.BlinkHTMLOptGroupElement.instance.label_Getter_(this);

  @DomName('HTMLOptGroupElement.label')
  @DocsEditable()
  void set label(String value) => _blink.BlinkHTMLOptGroupElement.instance.label_Setter_(this, value);

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


@DomName('HTMLOptionElement')
class OptionElement extends HtmlElement {
  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]) {
    return _blink.BlinkHTMLOptionElement.instance.constructorCallback_4_(data, value, defaultSelected, selected);
  }
  /**
   * 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 get defaultSelected => _blink.BlinkHTMLOptionElement.instance.defaultSelected_Getter_(this);

  @DomName('HTMLOptionElement.defaultSelected')
  @DocsEditable()
  void set defaultSelected(bool value) => _blink.BlinkHTMLOptionElement.instance.defaultSelected_Setter_(this, value);

  @DomName('HTMLOptionElement.disabled')
  @DocsEditable()
  bool get disabled => _blink.BlinkHTMLOptionElement.instance.disabled_Getter_(this);

  @DomName('HTMLOptionElement.disabled')
  @DocsEditable()
  void set disabled(bool value) => _blink.BlinkHTMLOptionElement.instance.disabled_Setter_(this, value);

  @DomName('HTMLOptionElement.form')
  @DocsEditable()
  FormElement get form => _blink.BlinkHTMLOptionElement.instance.form_Getter_(this);

  @DomName('HTMLOptionElement.index')
  @DocsEditable()
  int get index => _blink.BlinkHTMLOptionElement.instance.index_Getter_(this);

  @DomName('HTMLOptionElement.label')
  @DocsEditable()
  String get label => _blink.BlinkHTMLOptionElement.instance.label_Getter_(this);

  @DomName('HTMLOptionElement.label')
  @DocsEditable()
  void set label(String value) => _blink.BlinkHTMLOptionElement.instance.label_Setter_(this, value);

  @DomName('HTMLOptionElement.selected')
  @DocsEditable()
  bool get selected => _blink.BlinkHTMLOptionElement.instance.selected_Getter_(this);

  @DomName('HTMLOptionElement.selected')
  @DocsEditable()
  void set selected(bool value) => _blink.BlinkHTMLOptionElement.instance.selected_Setter_(this, value);

  @DomName('HTMLOptionElement.value')
  @DocsEditable()
  String get value => _blink.BlinkHTMLOptionElement.instance.value_Getter_(this);

  @DomName('HTMLOptionElement.value')
  @DocsEditable()
  void set value(String value) => _blink.BlinkHTMLOptionElement.instance.value_Setter_(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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('HTMLOutputElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
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 => true;

  @DomName('HTMLOutputElement.defaultValue')
  @DocsEditable()
  String get defaultValue => _blink.BlinkHTMLOutputElement.instance.defaultValue_Getter_(this);

  @DomName('HTMLOutputElement.defaultValue')
  @DocsEditable()
  void set defaultValue(String value) => _blink.BlinkHTMLOutputElement.instance.defaultValue_Setter_(this, value);

  @DomName('HTMLOutputElement.form')
  @DocsEditable()
  FormElement get form => _blink.BlinkHTMLOutputElement.instance.form_Getter_(this);

  @DomName('HTMLOutputElement.htmlFor')
  @DocsEditable()
  DomSettableTokenList get htmlFor => _blink.BlinkHTMLOutputElement.instance.htmlFor_Getter_(this);

  @DomName('HTMLOutputElement.labels')
  @DocsEditable()
  @Unstable()
  List<Node> get labels => _blink.BlinkHTMLOutputElement.instance.labels_Getter_(this);

  @DomName('HTMLOutputElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLOutputElement.instance.name_Getter_(this);

  @DomName('HTMLOutputElement.name')
  @DocsEditable()
  void set name(String value) => _blink.BlinkHTMLOutputElement.instance.name_Setter_(this, value);

  @DomName('HTMLOutputElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLOutputElement.instance.type_Getter_(this);

  @DomName('HTMLOutputElement.validationMessage')
  @DocsEditable()
  String get validationMessage => _blink.BlinkHTMLOutputElement.instance.validationMessage_Getter_(this);

  @DomName('HTMLOutputElement.validity')
  @DocsEditable()
  ValidityState get validity => _blink.BlinkHTMLOutputElement.instance.validity_Getter_(this);

  @DomName('HTMLOutputElement.value')
  @DocsEditable()
  String get value => _blink.BlinkHTMLOutputElement.instance.value_Getter_(this);

  @DomName('HTMLOutputElement.value')
  @DocsEditable()
  void set value(String value) => _blink.BlinkHTMLOutputElement.instance.value_Setter_(this, value);

  @DomName('HTMLOutputElement.willValidate')
  @DocsEditable()
  bool get willValidate => _blink.BlinkHTMLOutputElement.instance.willValidate_Getter_(this);

  @DomName('HTMLOutputElement.checkValidity')
  @DocsEditable()
  bool checkValidity() => _blink.BlinkHTMLOutputElement.instance.checkValidity_Callback_0_(this);

  @DomName('HTMLOutputElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) => _blink.BlinkHTMLOutputElement.instance.setCustomValidity_Callback_1_(this, 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.


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

  @DomName('OverflowEvent.BOTH')
  @DocsEditable()
  static const int BOTH = 2;

  @DomName('OverflowEvent.HORIZONTAL')
  @DocsEditable()
  static const int HORIZONTAL = 0;

  @DomName('OverflowEvent.VERTICAL')
  @DocsEditable()
  static const int VERTICAL = 1;

  @DomName('OverflowEvent.horizontalOverflow')
  @DocsEditable()
  bool get horizontalOverflow => _blink.BlinkOverflowEvent.instance.horizontalOverflow_Getter_(this);

  @DomName('OverflowEvent.orient')
  @DocsEditable()
  int get orient => _blink.BlinkOverflowEvent.instance.orient_Getter_(this);

  @DomName('OverflowEvent.verticalOverflow')
  @DocsEditable()
  bool get verticalOverflow => _blink.BlinkOverflowEvent.instance.verticalOverflow_Getter_(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.


@DocsEditable()
@DomName('PageTransitionEvent')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html#pagetransitionevent
@Experimental()
class PageTransitionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory PageTransitionEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('PageTransitionEvent.persisted')
  @DocsEditable()
  bool get persisted => _blink.BlinkPageTransitionEvent.instance.persisted_Getter_(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.


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

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

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

// WARNING: Do not edit - generated code.


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

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

  @DomName('HTMLParamElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLParamElement.instance.name_Getter_(this);

  @DomName('HTMLParamElement.name')
  @DocsEditable()
  void set name(String value) => _blink.BlinkHTMLParamElement.instance.name_Setter_(this, value);

  @DomName('HTMLParamElement.value')
  @DocsEditable()
  String get value => _blink.BlinkHTMLParamElement.instance.value_Getter_(this);

  @DomName('HTMLParamElement.value')
  @DocsEditable()
  void set value(String value) => _blink.BlinkHTMLParamElement.instance.value_Setter_(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.

// WARNING: Do not edit - generated code.


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

  @DomName('ParentNode.childElementCount')
  @DocsEditable()
  @Experimental() // untriaged
  int get _childElementCount;

  @DomName('ParentNode.children')
  @DocsEditable()
  @Experimental() // untriaged
  List<Node> get _children;

  @DomName('ParentNode.firstElementChild')
  @DocsEditable()
  @Experimental() // untriaged
  Element get _firstElementChild;

  @DomName('ParentNode.lastElementChild')
  @DocsEditable()
  @Experimental() // untriaged
  Element get _lastElementChild;

  @DomName('ParentNode.querySelector')
  @DocsEditable()
  @Experimental() // untriaged
  Element querySelector(String selectors);

  @DomName('ParentNode.querySelectorAll')
  @DocsEditable()
  @Experimental() // untriaged
  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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('Path2D')
@Experimental() // untriaged
class Path2D extends NativeFieldWrapperClass2 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 _blink.BlinkPath2D.instance.constructorCallback_0_();
    }
    if ((path_OR_text is Path2D || path_OR_text == null)) {
      return _blink.BlinkPath2D.instance.constructorCallback_1_(path_OR_text);
    }
    if ((path_OR_text is String || path_OR_text == null)) {
      return _blink.BlinkPath2D.instance.constructorCallback_1_(path_OR_text);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  void addPath(Path2D path, [Matrix transform]) {
    if (transform != null) {
      _blink.BlinkPath2D.instance.addPath_Callback_2_(this, path, transform);
      return;
    }
    _blink.BlinkPath2D.instance.addPath_Callback_1_(this, path);
    return;
  }

  @DomName('Path2D.arc')
  @DocsEditable()
  @Experimental() // untriaged
  void arc(num x, num y, num radius, num startAngle, num endAngle, bool anticlockwise) => _blink.BlinkPath2D.instance.arc_Callback_6_(this, x, y, radius, startAngle, endAngle, anticlockwise);

  @DomName('Path2D.arcTo')
  @DocsEditable()
  @Experimental() // untriaged
  void arcTo(num x1, num y1, num x2, num y2, num radius) => _blink.BlinkPath2D.instance.arcTo_Callback_5_(this, x1, y1, x2, y2, radius);

  @DomName('Path2D.bezierCurveTo')
  @DocsEditable()
  @Experimental() // untriaged
  void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y, num x, num y) => _blink.BlinkPath2D.instance.bezierCurveTo_Callback_6_(this, cp1x, cp1y, cp2x, cp2y, x, y);

  @DomName('Path2D.closePath')
  @DocsEditable()
  @Experimental() // untriaged
  void closePath() => _blink.BlinkPath2D.instance.closePath_Callback_0_(this);

  @DomName('Path2D.ellipse')
  @DocsEditable()
  @Experimental() // untriaged
  void ellipse(num x, num y, num radiusX, num radiusY, num rotation, num startAngle, num endAngle, bool anticlockwise) => _blink.BlinkPath2D.instance.ellipse_Callback_8_(this, x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise);

  @DomName('Path2D.lineTo')
  @DocsEditable()
  @Experimental() // untriaged
  void lineTo(num x, num y) => _blink.BlinkPath2D.instance.lineTo_Callback_2_(this, x, y);

  @DomName('Path2D.moveTo')
  @DocsEditable()
  @Experimental() // untriaged
  void moveTo(num x, num y) => _blink.BlinkPath2D.instance.moveTo_Callback_2_(this, x, y);

  @DomName('Path2D.quadraticCurveTo')
  @DocsEditable()
  @Experimental() // untriaged
  void quadraticCurveTo(num cpx, num cpy, num x, num y) => _blink.BlinkPath2D.instance.quadraticCurveTo_Callback_4_(this, cpx, cpy, x, y);

  @DomName('Path2D.rect')
  @DocsEditable()
  @Experimental() // untriaged
  void rect(num x, num y, num width, num height) => _blink.BlinkPath2D.instance.rect_Callback_4_(this, x, y, width, height);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


@DocsEditable()
@DomName('Performance')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE)
class Performance extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory Performance._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `resourcetimingbufferfull` events to event
   * handlers that are not necessarily instances of [Performance].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Performance.webkitresourcetimingbufferfullEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.w3c-test.org/webperf/specs/ResourceTiming/#performanceresourcetiming-methods
  static const EventStreamProvider<Event> resourceTimingBufferFullEvent = const EventStreamProvider<Event>('webkitresourcetimingbufferfull');

  /// Checks if this type is supported on the current platform.
  static bool get supported => true;

  @DomName('Performance.memory')
  @DocsEditable()
  @Experimental() // nonstandard
  MemoryInfo get memory => _blink.BlinkPerformance.instance.memory_Getter_(this);

  @DomName('Performance.navigation')
  @DocsEditable()
  PerformanceNavigation get navigation => _blink.BlinkPerformance.instance.navigation_Getter_(this);

  @DomName('Performance.timing')
  @DocsEditable()
  PerformanceTiming get timing => _blink.BlinkPerformance.instance.timing_Getter_(this);

  @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) => _blink.BlinkPerformance.instance.clearMarks_Callback_1_(this, markName);

  @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) => _blink.BlinkPerformance.instance.clearMeasures_Callback_1_(this, measureName);

  @DomName('Performance.getEntries')
  @DocsEditable()
  // http://www.w3.org/TR/performance-timeline/#sec-window.performance-attribute
  @Experimental()
  List<PerformanceEntry> getEntries() => _blink.BlinkPerformance.instance.getEntries_Callback_0_(this);

  @DomName('Performance.getEntriesByName')
  @DocsEditable()
  // http://www.w3.org/TR/performance-timeline/#sec-window.performance-attribute
  @Experimental()
  List<PerformanceEntry> getEntriesByName(String name, String entryType) => _blink.BlinkPerformance.instance.getEntriesByName_Callback_2_(this, name, entryType);

  @DomName('Performance.getEntriesByType')
  @DocsEditable()
  // http://www.w3.org/TR/performance-timeline/#sec-window.performance-attribute
  @Experimental()
  List<PerformanceEntry> getEntriesByType(String entryType) => _blink.BlinkPerformance.instance.getEntriesByType_Callback_1_(this, entryType);

  @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) => _blink.BlinkPerformance.instance.mark_Callback_1_(this, markName);

  @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) => _blink.BlinkPerformance.instance.measure_Callback_3_(this, measureName, startMark, endMark);

  @DomName('Performance.now')
  @DocsEditable()
  double now() => _blink.BlinkPerformance.instance.now_Callback_0_(this);

  @DomName('Performance.webkitClearResourceTimings')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.w3c-test.org/webperf/specs/ResourceTiming/#extensions-performance-interface
  void clearResourceTimings() => _blink.BlinkPerformance.instance.webkitClearResourceTimings_Callback_0_(this);

  @DomName('Performance.webkitSetResourceTimingBufferSize')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.w3c-test.org/webperf/specs/ResourceTiming/#performanceresourcetiming-methods
  void setResourceTimingBufferSize(int maxSize) => _blink.BlinkPerformance.instance.webkitSetResourceTimingBufferSize_Callback_1_(this, maxSize);

  /// Stream of `resourcetimingbufferfull` events handled by this [Performance].
  @DomName('Performance.onwebkitresourcetimingbufferfull')
  @DocsEditable()
  // http://www.w3c-test.org/webperf/specs/ResourceTiming/#performanceresourcetiming-methods
  @Experimental()
  Stream<Event> get onResourceTimingBufferFull => resourceTimingBufferFullEvent.forTarget(this);

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

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('PerformanceEntry')
// http://www.w3.org/TR/performance-timeline/#sec-PerformanceEntry-interface
@Experimental()
class PerformanceEntry extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory PerformanceEntry._() { throw new UnsupportedError("Not supported"); }

  @DomName('PerformanceEntry.duration')
  @DocsEditable()
  double get duration => _blink.BlinkPerformanceEntry.instance.duration_Getter_(this);

  @DomName('PerformanceEntry.entryType')
  @DocsEditable()
  String get entryType => _blink.BlinkPerformanceEntry.instance.entryType_Getter_(this);

  @DomName('PerformanceEntry.name')
  @DocsEditable()
  String get name => _blink.BlinkPerformanceEntry.instance.name_Getter_(this);

  @DomName('PerformanceEntry.startTime')
  @DocsEditable()
  double get startTime => _blink.BlinkPerformanceEntry.instance.startTime_Getter_(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.


@DocsEditable()
@DomName('PerformanceMark')
// http://www.w3.org/TR/user-timing/#performancemark
@Experimental()
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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('PerformanceMeasure')
// http://www.w3.org/TR/user-timing/#performancemeasure
@Experimental()
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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('PerformanceNavigation')
@Unstable()
class PerformanceNavigation extends NativeFieldWrapperClass2 {
  // 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()
  int get redirectCount => _blink.BlinkPerformanceNavigation.instance.redirectCount_Getter_(this);

  @DomName('PerformanceNavigation.type')
  @DocsEditable()
  int get type => _blink.BlinkPerformanceNavigation.instance.type_Getter_(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.


@DocsEditable()
@DomName('PerformanceResourceTiming')
// http://www.w3c-test.org/webperf/specs/ResourceTiming/#performanceresourcetiming
@Experimental()
class PerformanceResourceTiming extends PerformanceEntry {
  // To suppress missing implicit constructor warnings.
  factory PerformanceResourceTiming._() { throw new UnsupportedError("Not supported"); }

  @DomName('PerformanceResourceTiming.connectEnd')
  @DocsEditable()
  double get connectEnd => _blink.BlinkPerformanceResourceTiming.instance.connectEnd_Getter_(this);

  @DomName('PerformanceResourceTiming.connectStart')
  @DocsEditable()
  double get connectStart => _blink.BlinkPerformanceResourceTiming.instance.connectStart_Getter_(this);

  @DomName('PerformanceResourceTiming.domainLookupEnd')
  @DocsEditable()
  double get domainLookupEnd => _blink.BlinkPerformanceResourceTiming.instance.domainLookupEnd_Getter_(this);

  @DomName('PerformanceResourceTiming.domainLookupStart')
  @DocsEditable()
  double get domainLookupStart => _blink.BlinkPerformanceResourceTiming.instance.domainLookupStart_Getter_(this);

  @DomName('PerformanceResourceTiming.fetchStart')
  @DocsEditable()
  double get fetchStart => _blink.BlinkPerformanceResourceTiming.instance.fetchStart_Getter_(this);

  @DomName('PerformanceResourceTiming.initiatorType')
  @DocsEditable()
  String get initiatorType => _blink.BlinkPerformanceResourceTiming.instance.initiatorType_Getter_(this);

  @DomName('PerformanceResourceTiming.redirectEnd')
  @DocsEditable()
  double get redirectEnd => _blink.BlinkPerformanceResourceTiming.instance.redirectEnd_Getter_(this);

  @DomName('PerformanceResourceTiming.redirectStart')
  @DocsEditable()
  double get redirectStart => _blink.BlinkPerformanceResourceTiming.instance.redirectStart_Getter_(this);

  @DomName('PerformanceResourceTiming.requestStart')
  @DocsEditable()
  @Experimental() // nonstandard
  double get requestStart => _blink.BlinkPerformanceResourceTiming.instance.requestStart_Getter_(this);

  @DomName('PerformanceResourceTiming.responseEnd')
  @DocsEditable()
  @Experimental() // nonstandard
  double get responseEnd => _blink.BlinkPerformanceResourceTiming.instance.responseEnd_Getter_(this);

  @DomName('PerformanceResourceTiming.responseStart')
  @DocsEditable()
  @Experimental() // nonstandard
  double get responseStart => _blink.BlinkPerformanceResourceTiming.instance.responseStart_Getter_(this);

  @DomName('PerformanceResourceTiming.secureConnectionStart')
  @DocsEditable()
  double get secureConnectionStart => _blink.BlinkPerformanceResourceTiming.instance.secureConnectionStart_Getter_(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.


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

  @DomName('PerformanceTiming.connectEnd')
  @DocsEditable()
  int get connectEnd => _blink.BlinkPerformanceTiming.instance.connectEnd_Getter_(this);

  @DomName('PerformanceTiming.connectStart')
  @DocsEditable()
  int get connectStart => _blink.BlinkPerformanceTiming.instance.connectStart_Getter_(this);

  @DomName('PerformanceTiming.domComplete')
  @DocsEditable()
  int get domComplete => _blink.BlinkPerformanceTiming.instance.domComplete_Getter_(this);

  @DomName('PerformanceTiming.domContentLoadedEventEnd')
  @DocsEditable()
  int get domContentLoadedEventEnd => _blink.BlinkPerformanceTiming.instance.domContentLoadedEventEnd_Getter_(this);

  @DomName('PerformanceTiming.domContentLoadedEventStart')
  @DocsEditable()
  int get domContentLoadedEventStart => _blink.BlinkPerformanceTiming.instance.domContentLoadedEventStart_Getter_(this);

  @DomName('PerformanceTiming.domInteractive')
  @DocsEditable()
  int get domInteractive => _blink.BlinkPerformanceTiming.instance.domInteractive_Getter_(this);

  @DomName('PerformanceTiming.domLoading')
  @DocsEditable()
  int get domLoading => _blink.BlinkPerformanceTiming.instance.domLoading_Getter_(this);

  @DomName('PerformanceTiming.domainLookupEnd')
  @DocsEditable()
  int get domainLookupEnd => _blink.BlinkPerformanceTiming.instance.domainLookupEnd_Getter_(this);

  @DomName('PerformanceTiming.domainLookupStart')
  @DocsEditable()
  int get domainLookupStart => _blink.BlinkPerformanceTiming.instance.domainLookupStart_Getter_(this);

  @DomName('PerformanceTiming.fetchStart')
  @DocsEditable()
  int get fetchStart => _blink.BlinkPerformanceTiming.instance.fetchStart_Getter_(this);

  @DomName('PerformanceTiming.loadEventEnd')
  @DocsEditable()
  int get loadEventEnd => _blink.BlinkPerformanceTiming.instance.loadEventEnd_Getter_(this);

  @DomName('PerformanceTiming.loadEventStart')
  @DocsEditable()
  int get loadEventStart => _blink.BlinkPerformanceTiming.instance.loadEventStart_Getter_(this);

  @DomName('PerformanceTiming.navigationStart')
  @DocsEditable()
  int get navigationStart => _blink.BlinkPerformanceTiming.instance.navigationStart_Getter_(this);

  @DomName('PerformanceTiming.redirectEnd')
  @DocsEditable()
  int get redirectEnd => _blink.BlinkPerformanceTiming.instance.redirectEnd_Getter_(this);

  @DomName('PerformanceTiming.redirectStart')
  @DocsEditable()
  int get redirectStart => _blink.BlinkPerformanceTiming.instance.redirectStart_Getter_(this);

  @DomName('PerformanceTiming.requestStart')
  @DocsEditable()
  int get requestStart => _blink.BlinkPerformanceTiming.instance.requestStart_Getter_(this);

  @DomName('PerformanceTiming.responseEnd')
  @DocsEditable()
  int get responseEnd => _blink.BlinkPerformanceTiming.instance.responseEnd_Getter_(this);

  @DomName('PerformanceTiming.responseStart')
  @DocsEditable()
  int get responseStart => _blink.BlinkPerformanceTiming.instance.responseStart_Getter_(this);

  @DomName('PerformanceTiming.secureConnectionStart')
  @DocsEditable()
  int get secureConnectionStart => _blink.BlinkPerformanceTiming.instance.secureConnectionStart_Getter_(this);

  @DomName('PerformanceTiming.unloadEventEnd')
  @DocsEditable()
  int get unloadEventEnd => _blink.BlinkPerformanceTiming.instance.unloadEventEnd_Getter_(this);

  @DomName('PerformanceTiming.unloadEventStart')
  @DocsEditable()
  int get unloadEventStart => _blink.BlinkPerformanceTiming.instance.unloadEventStart_Getter_(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.


@DocsEditable()
@DomName('HTMLPictureElement')
@Experimental() // untriaged
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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('Plugin')
@Experimental() // non-standard
class Plugin extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory Plugin._() { throw new UnsupportedError("Not supported"); }

  @DomName('Plugin.description')
  @DocsEditable()
  String get description => _blink.BlinkPlugin.instance.description_Getter_(this);

  @DomName('Plugin.filename')
  @DocsEditable()
  String get filename => _blink.BlinkPlugin.instance.filename_Getter_(this);

  @DomName('Plugin.length')
  @DocsEditable()
  int get length => _blink.BlinkPlugin.instance.length_Getter_(this);

  @DomName('Plugin.name')
  @DocsEditable()
  String get name => _blink.BlinkPlugin.instance.name_Getter_(this);

  @DomName('Plugin.__getter__')
  @DocsEditable()
  MimeType __getter__(String name) => _blink.BlinkPlugin.instance.$__getter___Callback_1_(this, name);

  @DomName('Plugin.item')
  @DocsEditable()
  MimeType item(int index) => _blink.BlinkPlugin.instance.item_Callback_1_(this, index);

  @DomName('Plugin.namedItem')
  @DocsEditable()
  MimeType namedItem(String name) => _blink.BlinkPlugin.instance.namedItem_Callback_1_(this, 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.


@DocsEditable()
@DomName('PluginArray')
@Experimental() // non-standard
class PluginArray extends NativeFieldWrapperClass2 with ListMixin<Plugin>, ImmutableListMixin<Plugin> implements List<Plugin> {
  // To suppress missing implicit constructor warnings.
  factory PluginArray._() { throw new UnsupportedError("Not supported"); }

  @DomName('PluginArray.length')
  @DocsEditable()
  int get length => _blink.BlinkPluginArray.instance.length_Getter_(this);

  Plugin operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return _blink.BlinkPluginArray.instance.item_Callback_1_(this, index);
  }

  Plugin _nativeIndexedGetter(int index) => _blink.BlinkPluginArray.instance.item_Callback_1_(this, index);

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


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

  Plugin get first {
    if (this.length > 0) {
      return _nativeIndexedGetter(0);
    }
    throw new StateError("No elements");
  }

  Plugin get last {
    int len = this.length;
    if (len > 0) {
      return _nativeIndexedGetter(len - 1);
    }
    throw new StateError("No elements");
  }

  Plugin get single {
    int len = this.length;
    if (len == 1) {
      return _nativeIndexedGetter(0);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

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

  @DomName('PluginArray.__getter__')
  @DocsEditable()
  Plugin __getter__(String name) => _blink.BlinkPluginArray.instance.$__getter___Callback_1_(this, name);

  @DomName('PluginArray.item')
  @DocsEditable()
  Plugin item(int index) => _blink.BlinkPluginArray.instance.item_Callback_1_(this, index);

  @DomName('PluginArray.namedItem')
  @DocsEditable()
  Plugin namedItem(String name) => _blink.BlinkPluginArray.instance.namedItem_Callback_1_(this, name);

  @DomName('PluginArray.refresh')
  @DocsEditable()
  void refresh(bool reload) => _blink.BlinkPluginArray.instance.refresh_Callback_1_(this, reload);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


@DocsEditable()
@DomName('PopStateEvent')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
class PopStateEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory PopStateEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('PopStateEvent.state')
  @DocsEditable()
  Object get state => _blink.BlinkPopStateEvent.instance.state_Getter_(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('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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('PositionError')
@Unstable()
class PositionError extends NativeFieldWrapperClass2 {
  // 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()
  int get code => _blink.BlinkPositionError.instance.code_Getter_(this);

  @DomName('PositionError.message')
  @DocsEditable()
  String get message => _blink.BlinkPositionError.instance.message_Getter_(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('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.

// WARNING: Do not edit - generated code.


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

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

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

// WARNING: Do not edit - generated code.


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

  @DomName('ProcessingInstruction.sheet')
  @DocsEditable()
  @Experimental() // non-standard
  StyleSheet get sheet => _blink.BlinkProcessingInstruction.instance.sheet_Getter_(this);

  @DomName('ProcessingInstruction.target')
  @DocsEditable()
  String get target => _blink.BlinkProcessingInstruction.instance.target_Getter_(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.


@DocsEditable()
@DomName('HTMLProgressElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
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 => true;

  @DomName('HTMLProgressElement.labels')
  @DocsEditable()
  @Unstable()
  List<Node> get labels => _blink.BlinkHTMLProgressElement.instance.labels_Getter_(this);

  @DomName('HTMLProgressElement.max')
  @DocsEditable()
  num get max => _blink.BlinkHTMLProgressElement.instance.max_Getter_(this);

  @DomName('HTMLProgressElement.max')
  @DocsEditable()
  void set max(num value) => _blink.BlinkHTMLProgressElement.instance.max_Setter_(this, value);

  @DomName('HTMLProgressElement.position')
  @DocsEditable()
  double get position => _blink.BlinkHTMLProgressElement.instance.position_Getter_(this);

  @DomName('HTMLProgressElement.value')
  @DocsEditable()
  num get value => _blink.BlinkHTMLProgressElement.instance.value_Getter_(this);

  @DomName('HTMLProgressElement.value')
  @DocsEditable()
  void set value(num value) => _blink.BlinkHTMLProgressElement.instance.value_Setter_(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.

// WARNING: Do not edit - generated code.


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

  @DomName('ProgressEvent.lengthComputable')
  @DocsEditable()
  bool get lengthComputable => _blink.BlinkProgressEvent.instance.lengthComputable_Getter_(this);

  @DomName('ProgressEvent.loaded')
  @DocsEditable()
  int get loaded => _blink.BlinkProgressEvent.instance.loaded_Getter_(this);

  @DomName('ProgressEvent.total')
  @DocsEditable()
  int get total => _blink.BlinkProgressEvent.instance.total_Getter_(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.


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

  @DomName('PushEvent.data')
  @DocsEditable()
  @Experimental() // untriaged
  String get data => _blink.BlinkPushEvent.instance.data_Getter_(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.


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

  @DomName('PushManager.register')
  @DocsEditable()
  @Experimental() // untriaged
  Future register(String senderId) => _blink.BlinkPushManager.instance.register_Callback_1_(this, senderId);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

  @DomName('PushRegistration.pushEndpoint')
  @DocsEditable()
  @Experimental() // untriaged
  String get pushEndpoint => _blink.BlinkPushRegistration.instance.pushEndpoint_Getter_(this);

  @DomName('PushRegistration.pushRegistrationId')
  @DocsEditable()
  @Experimental() // untriaged
  String get pushRegistrationId => _blink.BlinkPushRegistration.instance.pushRegistrationId_Getter_(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.


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

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

  @DomName('HTMLQuoteElement.cite')
  @DocsEditable()
  String get cite => _blink.BlinkHTMLQuoteElement.instance.cite_Getter_(this);

  @DomName('HTMLQuoteElement.cite')
  @DocsEditable()
  void set cite(String value) => _blink.BlinkHTMLQuoteElement.instance.cite_Setter_(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.

// WARNING: Do not edit - generated code.


@DomName('RTCErrorCallback')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#rtcerror
@Experimental()
typedef void _RtcErrorCallback(String errorInformation);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('RTCSessionDescriptionCallback')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCSessionDescription
@Experimental()
typedef void _RtcSessionDescriptionCallback(RtcSessionDescription sdp);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('RTCStatsCallback')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCStatsCallback
@Experimental()
typedef void RtcStatsCallback(RtcStatsResponse response);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('Range')
@Unstable()
class Range extends NativeFieldWrapperClass2 {
  factory Range() => document.createRange();

  factory Range.fromPoint(Point point) =>
      document._caretRangeFromPoint(point.x, point.y);
  // To suppress missing implicit constructor warnings.
  factory Range._() { throw new UnsupportedError("Not supported"); }

  @DomName('Range.END_TO_END')
  @DocsEditable()
  static const int END_TO_END = 2;

  @DomName('Range.END_TO_START')
  @DocsEditable()
  static const int END_TO_START = 3;

  @DomName('Range.NODE_AFTER')
  @DocsEditable()
  @Experimental() // nonstandard
  static const int NODE_AFTER = 1;

  @DomName('Range.NODE_BEFORE')
  @DocsEditable()
  @Experimental() // nonstandard
  static const int NODE_BEFORE = 0;

  @DomName('Range.NODE_BEFORE_AND_AFTER')
  @DocsEditable()
  @Experimental() // nonstandard
  static const int NODE_BEFORE_AND_AFTER = 2;

  @DomName('Range.NODE_INSIDE')
  @DocsEditable()
  @Experimental() // nonstandard
  static const int NODE_INSIDE = 3;

  @DomName('Range.START_TO_END')
  @DocsEditable()
  static const int START_TO_END = 1;

  @DomName('Range.START_TO_START')
  @DocsEditable()
  static const int START_TO_START = 0;

  @DomName('Range.collapsed')
  @DocsEditable()
  bool get collapsed => _blink.BlinkRange.instance.collapsed_Getter_(this);

  @DomName('Range.commonAncestorContainer')
  @DocsEditable()
  Node get commonAncestorContainer => _blink.BlinkRange.instance.commonAncestorContainer_Getter_(this);

  @DomName('Range.endContainer')
  @DocsEditable()
  Node get endContainer => _blink.BlinkRange.instance.endContainer_Getter_(this);

  @DomName('Range.endOffset')
  @DocsEditable()
  int get endOffset => _blink.BlinkRange.instance.endOffset_Getter_(this);

  @DomName('Range.startContainer')
  @DocsEditable()
  Node get startContainer => _blink.BlinkRange.instance.startContainer_Getter_(this);

  @DomName('Range.startOffset')
  @DocsEditable()
  int get startOffset => _blink.BlinkRange.instance.startOffset_Getter_(this);

  @DomName('Range.cloneContents')
  @DocsEditable()
  DocumentFragment cloneContents() => _blink.BlinkRange.instance.cloneContents_Callback_0_(this);

  @DomName('Range.cloneRange')
  @DocsEditable()
  Range cloneRange() => _blink.BlinkRange.instance.cloneRange_Callback_0_(this);

  void collapse([bool toStart]) {
    if (toStart != null) {
      _blink.BlinkRange.instance.collapse_Callback_1_(this, toStart);
      return;
    }
    _blink.BlinkRange.instance.collapse_Callback_0_(this);
    return;
  }

  @DomName('Range.comparePoint')
  @DocsEditable()
  int comparePoint(Node refNode, int offset) => _blink.BlinkRange.instance.comparePoint_Callback_2_(this, refNode, offset);

  @DomName('Range.createContextualFragment')
  @DocsEditable()
  DocumentFragment createContextualFragment(String html) => _blink.BlinkRange.instance.createContextualFragment_Callback_1_(this, html);

  @DomName('Range.deleteContents')
  @DocsEditable()
  void deleteContents() => _blink.BlinkRange.instance.deleteContents_Callback_0_(this);

  @DomName('Range.detach')
  @DocsEditable()
  void detach() => _blink.BlinkRange.instance.detach_Callback_0_(this);

  @DomName('Range.expand')
  @DocsEditable()
  @Experimental() // non-standard
  void expand(String unit) => _blink.BlinkRange.instance.expand_Callback_1_(this, unit);

  @DomName('Range.extractContents')
  @DocsEditable()
  DocumentFragment extractContents() => _blink.BlinkRange.instance.extractContents_Callback_0_(this);

  @DomName('Range.getBoundingClientRect')
  @DocsEditable()
  Rectangle getBoundingClientRect() => _blink.BlinkRange.instance.getBoundingClientRect_Callback_0_(this);

  @DomName('Range.getClientRects')
  @DocsEditable()
  List<Rectangle> getClientRects() => _blink.BlinkRange.instance.getClientRects_Callback_0_(this);

  @DomName('Range.insertNode')
  @DocsEditable()
  void insertNode(Node newNode) => _blink.BlinkRange.instance.insertNode_Callback_1_(this, newNode);

  @DomName('Range.isPointInRange')
  @DocsEditable()
  bool isPointInRange(Node refNode, int offset) => _blink.BlinkRange.instance.isPointInRange_Callback_2_(this, refNode, offset);

  @DomName('Range.selectNode')
  @DocsEditable()
  void selectNode(Node refNode) => _blink.BlinkRange.instance.selectNode_Callback_1_(this, refNode);

  @DomName('Range.selectNodeContents')
  @DocsEditable()
  void selectNodeContents(Node refNode) => _blink.BlinkRange.instance.selectNodeContents_Callback_1_(this, refNode);

  @DomName('Range.setEnd')
  @DocsEditable()
  void setEnd(Node refNode, int offset) => _blink.BlinkRange.instance.setEnd_Callback_2_(this, refNode, offset);

  @DomName('Range.setEndAfter')
  @DocsEditable()
  void setEndAfter(Node refNode) => _blink.BlinkRange.instance.setEndAfter_Callback_1_(this, refNode);

  @DomName('Range.setEndBefore')
  @DocsEditable()
  void setEndBefore(Node refNode) => _blink.BlinkRange.instance.setEndBefore_Callback_1_(this, refNode);

  @DomName('Range.setStart')
  @DocsEditable()
  void setStart(Node refNode, int offset) => _blink.BlinkRange.instance.setStart_Callback_2_(this, refNode, offset);

  @DomName('Range.setStartAfter')
  @DocsEditable()
  void setStartAfter(Node refNode) => _blink.BlinkRange.instance.setStartAfter_Callback_1_(this, refNode);

  @DomName('Range.setStartBefore')
  @DocsEditable()
  void setStartBefore(Node refNode) => _blink.BlinkRange.instance.setStartBefore_Callback_1_(this, refNode);

  @DomName('Range.surroundContents')
  @DocsEditable()
  void surroundContents(Node newParent) => _blink.BlinkRange.instance.surroundContents_Callback_1_(this, newParent);


  /**
   * Checks if createContextualFragment is supported.
   *
   * See also:
   *
   * * [createContextualFragment]
   */
  static bool get supportsCreateContextualFragment => true;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


@DocsEditable()
@DomName('ReadableStream')
@Experimental() // untriaged
class ReadableStream extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory ReadableStream._() { 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.

// WARNING: Do not edit - generated code.


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

  @DomName('RelatedEvent.relatedTarget')
  @DocsEditable()
  @Experimental() // untriaged
  EventTarget get relatedTarget => _blink.BlinkRelatedEvent.instance.relatedTarget_Getter_(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('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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('ResourceProgressEvent')
// https://chromiumcodereview.appspot.com/14773025/
@deprecated // experimental
class ResourceProgressEvent extends ProgressEvent {
  // To suppress missing implicit constructor warnings.
  factory ResourceProgressEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('ResourceProgressEvent.url')
  @DocsEditable()
  String get url => _blink.BlinkResourceProgressEvent.instance.url_Getter_(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.


@DocsEditable()
@DomName('RTCDataChannel')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCDataChannel
@Experimental()
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 get binaryType => _blink.BlinkRTCDataChannel.instance.binaryType_Getter_(this);

  @DomName('RTCDataChannel.binaryType')
  @DocsEditable()
  void set binaryType(String value) => _blink.BlinkRTCDataChannel.instance.binaryType_Setter_(this, value);

  @DomName('RTCDataChannel.bufferedAmount')
  @DocsEditable()
  int get bufferedAmount => _blink.BlinkRTCDataChannel.instance.bufferedAmount_Getter_(this);

  @DomName('RTCDataChannel.id')
  @DocsEditable()
  @Experimental() // untriaged
  int get id => _blink.BlinkRTCDataChannel.instance.id_Getter_(this);

  @DomName('RTCDataChannel.label')
  @DocsEditable()
  String get label => _blink.BlinkRTCDataChannel.instance.label_Getter_(this);

  @DomName('RTCDataChannel.maxRetransmitTime')
  @DocsEditable()
  @Experimental() // untriaged
  int get maxRetransmitTime => _blink.BlinkRTCDataChannel.instance.maxRetransmitTime_Getter_(this);

  @DomName('RTCDataChannel.maxRetransmits')
  @DocsEditable()
  @Experimental() // untriaged
  int get maxRetransmits => _blink.BlinkRTCDataChannel.instance.maxRetransmits_Getter_(this);

  @DomName('RTCDataChannel.negotiated')
  @DocsEditable()
  @Experimental() // untriaged
  bool get negotiated => _blink.BlinkRTCDataChannel.instance.negotiated_Getter_(this);

  @DomName('RTCDataChannel.ordered')
  @DocsEditable()
  @Experimental() // untriaged
  bool get ordered => _blink.BlinkRTCDataChannel.instance.ordered_Getter_(this);

  @DomName('RTCDataChannel.protocol')
  @DocsEditable()
  @Experimental() // untriaged
  String get protocol => _blink.BlinkRTCDataChannel.instance.protocol_Getter_(this);

  @DomName('RTCDataChannel.readyState')
  @DocsEditable()
  String get readyState => _blink.BlinkRTCDataChannel.instance.readyState_Getter_(this);

  @DomName('RTCDataChannel.reliable')
  @DocsEditable()
  bool get reliable => _blink.BlinkRTCDataChannel.instance.reliable_Getter_(this);

  @DomName('RTCDataChannel.close')
  @DocsEditable()
  void close() => _blink.BlinkRTCDataChannel.instance.close_Callback_0_(this);

  void send(data) {
    if ((data is String || data == null)) {
      _blink.BlinkRTCDataChannel.instance.send_Callback_1_(this, data);
      return;
    }
    if ((data is Blob || data == null)) {
      _blink.BlinkRTCDataChannel.instance.send_Callback_1_(this, data);
      return;
    }
    if ((data is TypedData || data == null)) {
      _blink.BlinkRTCDataChannel.instance.send_Callback_1_(this, data);
      return;
    }
    if ((data is ByteBuffer || data == null)) {
      _blink.BlinkRTCDataChannel.instance.send_Callback_1_(this, data);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('RTCDataChannel.sendBlob')
  @DocsEditable()
  void sendBlob(Blob data) => _blink.BlinkRTCDataChannel.instance.send_Callback_1_(this, data);

  @DomName('RTCDataChannel.sendByteBuffer')
  @DocsEditable()
  void sendByteBuffer(ByteBuffer data) => _blink.BlinkRTCDataChannel.instance.send_Callback_1_(this, data);

  @DomName('RTCDataChannel.sendString')
  @DocsEditable()
  void sendString(String data) => _blink.BlinkRTCDataChannel.instance.send_Callback_1_(this, data);

  @DomName('RTCDataChannel.sendTypedData')
  @DocsEditable()
  void sendTypedData(TypedData data) => _blink.BlinkRTCDataChannel.instance.send_Callback_1_(this, data);

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

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('RTCDataChannelEvent')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#rtcdatachannelevent
@Experimental()
class RtcDataChannelEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory RtcDataChannelEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('RTCDataChannelEvent.channel')
  @DocsEditable()
  RtcDataChannel get channel => _blink.BlinkRTCDataChannelEvent.instance.channel_Getter_(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.


@DocsEditable()
@DomName('RTCDTMFSender')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCDTMFSender
@Experimental()
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');

  @DomName('RTCDTMFSender.canInsertDTMF')
  @DocsEditable()
  bool get canInsertDtmf => _blink.BlinkRTCDTMFSender.instance.canInsertDTMF_Getter_(this);

  @DomName('RTCDTMFSender.duration')
  @DocsEditable()
  int get duration => _blink.BlinkRTCDTMFSender.instance.duration_Getter_(this);

  @DomName('RTCDTMFSender.interToneGap')
  @DocsEditable()
  int get interToneGap => _blink.BlinkRTCDTMFSender.instance.interToneGap_Getter_(this);

  @DomName('RTCDTMFSender.toneBuffer')
  @DocsEditable()
  String get toneBuffer => _blink.BlinkRTCDTMFSender.instance.toneBuffer_Getter_(this);

  @DomName('RTCDTMFSender.track')
  @DocsEditable()
  MediaStreamTrack get track => _blink.BlinkRTCDTMFSender.instance.track_Getter_(this);

  void insertDtmf(String tones, [int duration, int interToneGap]) {
    if (interToneGap != null) {
      _blink.BlinkRTCDTMFSender.instance.insertDTMF_Callback_3_(this, tones, duration, interToneGap);
      return;
    }
    if (duration != null) {
      _blink.BlinkRTCDTMFSender.instance.insertDTMF_Callback_2_(this, tones, duration);
      return;
    }
    _blink.BlinkRTCDTMFSender.instance.insertDTMF_Callback_1_(this, tones);
    return;
  }

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

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('RTCDTMFToneChangeEvent')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCDTMFToneChangeEvent
@Experimental()
class RtcDtmfToneChangeEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory RtcDtmfToneChangeEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('RTCDTMFToneChangeEvent.tone')
  @DocsEditable()
  String get tone => _blink.BlinkRTCDTMFToneChangeEvent.instance.tone_Getter_(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.


@DocsEditable()
@DomName('RTCIceCandidate')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCIceCandidate
class RtcIceCandidate extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory RtcIceCandidate._() { throw new UnsupportedError("Not supported"); }

  @DomName('RTCIceCandidate.RTCIceCandidate')
  @DocsEditable()
  factory RtcIceCandidate(Map dictionary) {
    return _blink.BlinkRTCIceCandidate.instance.constructorCallback_1_(dictionary);
  }

  @DomName('RTCIceCandidate.candidate')
  @DocsEditable()
  String get candidate => _blink.BlinkRTCIceCandidate.instance.candidate_Getter_(this);

  @DomName('RTCIceCandidate.candidate')
  @DocsEditable()
  void set candidate(String value) => _blink.BlinkRTCIceCandidate.instance.candidate_Setter_(this, value);

  @DomName('RTCIceCandidate.sdpMLineIndex')
  @DocsEditable()
  int get sdpMLineIndex => _blink.BlinkRTCIceCandidate.instance.sdpMLineIndex_Getter_(this);

  @DomName('RTCIceCandidate.sdpMLineIndex')
  @DocsEditable()
  void set sdpMLineIndex(int value) => _blink.BlinkRTCIceCandidate.instance.sdpMLineIndex_Setter_(this, value);

  @DomName('RTCIceCandidate.sdpMid')
  @DocsEditable()
  String get sdpMid => _blink.BlinkRTCIceCandidate.instance.sdpMid_Getter_(this);

  @DomName('RTCIceCandidate.sdpMid')
  @DocsEditable()
  void set sdpMid(String value) => _blink.BlinkRTCIceCandidate.instance.sdpMid_Setter_(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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('RTCIceCandidateEvent')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#rtcicecandidate-type
@Experimental()
class RtcIceCandidateEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory RtcIceCandidateEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('RTCIceCandidateEvent.candidate')
  @DocsEditable()
  RtcIceCandidate get candidate => _blink.BlinkRTCIceCandidateEvent.instance.candidate_Getter_(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('RTCPeerConnection')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCPeerConnection
class RtcPeerConnection extends EventTarget {

  /**
   * Checks if Real Time Communication (RTC) APIs are supported and enabled on
   * the current platform.
   */
  static bool get supported => true;
  Future<RtcSessionDescription> createOffer([Map mediaConstraints]) {
    var completer = new Completer<RtcSessionDescription>();
    _createOffer(
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); }, mediaConstraints);
    return completer.future;
  }

  Future<RtcSessionDescription> createAnswer([Map mediaConstraints]) {
    var completer = new Completer<RtcSessionDescription>();
    _createAnswer(
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); }, mediaConstraints);
    return completer.future;
  }

  @DomName('RTCPeerConnection.getStats')
  Future<RtcStatsResponse> getStats(MediaStreamTrack selector) {
    var completer = new Completer<RtcStatsResponse>();
    _getStats((value) { completer.complete(value); }, selector);
    return completer.future;
  }
  // To suppress missing implicit constructor warnings.
  factory RtcPeerConnection._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `addstream` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCPeerConnection.addstreamEvent')
  @DocsEditable()
  static const EventStreamProvider<MediaStreamEvent> addStreamEvent = const EventStreamProvider<MediaStreamEvent>('addstream');

  /**
   * Static factory designed to expose `datachannel` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCPeerConnection.datachannelEvent')
  @DocsEditable()
  static const EventStreamProvider<RtcDataChannelEvent> dataChannelEvent = const EventStreamProvider<RtcDataChannelEvent>('datachannel');

  /**
   * Static factory designed to expose `icecandidate` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCPeerConnection.icecandidateEvent')
  @DocsEditable()
  static const EventStreamProvider<RtcIceCandidateEvent> iceCandidateEvent = const EventStreamProvider<RtcIceCandidateEvent>('icecandidate');

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

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

  /**
   * Static factory designed to expose `removestream` events to event
   * handlers that are not necessarily instances of [RtcPeerConnection].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('RTCPeerConnection.removestreamEvent')
  @DocsEditable()
  static const EventStreamProvider<MediaStreamEvent> removeStreamEvent = const EventStreamProvider<MediaStreamEvent>('removestream');

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

  @DomName('RTCPeerConnection.RTCPeerConnection')
  @DocsEditable()
  factory RtcPeerConnection(Map rtcConfiguration, [Map mediaConstraints]) {
    if (mediaConstraints != null) {
      return _blink.BlinkRTCPeerConnection.instance.constructorCallback_2_(rtcConfiguration, mediaConstraints);
    }
    return _blink.BlinkRTCPeerConnection.instance.constructorCallback_1_(rtcConfiguration);
  }

  @DomName('RTCPeerConnection.iceConnectionState')
  @DocsEditable()
  String get iceConnectionState => _blink.BlinkRTCPeerConnection.instance.iceConnectionState_Getter_(this);

  @DomName('RTCPeerConnection.iceGatheringState')
  @DocsEditable()
  String get iceGatheringState => _blink.BlinkRTCPeerConnection.instance.iceGatheringState_Getter_(this);

  @DomName('RTCPeerConnection.localDescription')
  @DocsEditable()
  RtcSessionDescription get localDescription => _blink.BlinkRTCPeerConnection.instance.localDescription_Getter_(this);

  @DomName('RTCPeerConnection.remoteDescription')
  @DocsEditable()
  RtcSessionDescription get remoteDescription => _blink.BlinkRTCPeerConnection.instance.remoteDescription_Getter_(this);

  @DomName('RTCPeerConnection.signalingState')
  @DocsEditable()
  String get signalingState => _blink.BlinkRTCPeerConnection.instance.signalingState_Getter_(this);

  @DomName('RTCPeerConnection.addIceCandidate')
  @DocsEditable()
  void addIceCandidate(RtcIceCandidate candidate, VoidCallback successCallback, _RtcErrorCallback failureCallback) => _blink.BlinkRTCPeerConnection.instance.addIceCandidate_Callback_3_(this, candidate, successCallback, failureCallback);

  void addStream(MediaStream stream, [Map mediaConstraints]) {
    if (mediaConstraints != null) {
      _blink.BlinkRTCPeerConnection.instance.addStream_Callback_2_(this, stream, mediaConstraints);
      return;
    }
    _blink.BlinkRTCPeerConnection.instance.addStream_Callback_1_(this, stream);
    return;
  }

  @DomName('RTCPeerConnection.close')
  @DocsEditable()
  void close() => _blink.BlinkRTCPeerConnection.instance.close_Callback_0_(this);

  void _createAnswer(_RtcSessionDescriptionCallback successCallback, [_RtcErrorCallback failureCallback, Map mediaConstraints]) {
    if (mediaConstraints != null) {
      _blink.BlinkRTCPeerConnection.instance.createAnswer_Callback_3_(this, successCallback, failureCallback, mediaConstraints);
      return;
    }
    _blink.BlinkRTCPeerConnection.instance.createAnswer_Callback_2_(this, successCallback, failureCallback);
    return;
  }

  @DomName('RTCPeerConnection.createDTMFSender')
  @DocsEditable()
  RtcDtmfSender createDtmfSender(MediaStreamTrack track) => _blink.BlinkRTCPeerConnection.instance.createDTMFSender_Callback_1_(this, track);

  RtcDataChannel createDataChannel(String label, [Map options]) {
    if (options != null) {
      return _blink.BlinkRTCPeerConnection.instance.createDataChannel_Callback_2_(this, label, options);
    }
    return _blink.BlinkRTCPeerConnection.instance.createDataChannel_Callback_1_(this, label);
  }

  void _createOffer(_RtcSessionDescriptionCallback successCallback, [_RtcErrorCallback failureCallback, Map rtcOfferOptions]) {
    if (rtcOfferOptions != null) {
      _blink.BlinkRTCPeerConnection.instance.createOffer_Callback_3_(this, successCallback, failureCallback, rtcOfferOptions);
      return;
    }
    _blink.BlinkRTCPeerConnection.instance.createOffer_Callback_2_(this, successCallback, failureCallback);
    return;
  }

  @DomName('RTCPeerConnection.getLocalStreams')
  @DocsEditable()
  List<MediaStream> getLocalStreams() => _blink.BlinkRTCPeerConnection.instance.getLocalStreams_Callback_0_(this);

  @DomName('RTCPeerConnection.getRemoteStreams')
  @DocsEditable()
  List<MediaStream> getRemoteStreams() => _blink.BlinkRTCPeerConnection.instance.getRemoteStreams_Callback_0_(this);

  @DomName('RTCPeerConnection.getStats')
  @DocsEditable()
  void _getStats(RtcStatsCallback successCallback, MediaStreamTrack selector) => _blink.BlinkRTCPeerConnection.instance.getStats_Callback_2_(this, successCallback, selector);

  @DomName('RTCPeerConnection.getStreamById')
  @DocsEditable()
  MediaStream getStreamById(String streamId) => _blink.BlinkRTCPeerConnection.instance.getStreamById_Callback_1_(this, streamId);

  @DomName('RTCPeerConnection.removeStream')
  @DocsEditable()
  void removeStream(MediaStream stream) => _blink.BlinkRTCPeerConnection.instance.removeStream_Callback_1_(this, stream);

  @DomName('RTCPeerConnection.setLocalDescription')
  @DocsEditable()
  void _setLocalDescription(RtcSessionDescription description, [VoidCallback successCallback, _RtcErrorCallback failureCallback]) => _blink.BlinkRTCPeerConnection.instance.setLocalDescription_Callback_3_(this, description, successCallback, failureCallback);

  Future setLocalDescription(RtcSessionDescription description) {
    var completer = new Completer();
    _setLocalDescription(description,
        () { completer.complete(); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  @DomName('RTCPeerConnection.setRemoteDescription')
  @DocsEditable()
  void _setRemoteDescription(RtcSessionDescription description, [VoidCallback successCallback, _RtcErrorCallback failureCallback]) => _blink.BlinkRTCPeerConnection.instance.setRemoteDescription_Callback_3_(this, description, successCallback, failureCallback);

  Future setRemoteDescription(RtcSessionDescription description) {
    var completer = new Completer();
    _setRemoteDescription(description,
        () { completer.complete(); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  void updateIce([Map configuration, Map mediaConstraints]) {
    if (mediaConstraints != null) {
      _blink.BlinkRTCPeerConnection.instance.updateIce_Callback_2_(this, configuration, mediaConstraints);
      return;
    }
    if (configuration != null) {
      _blink.BlinkRTCPeerConnection.instance.updateIce_Callback_1_(this, configuration);
      return;
    }
    _blink.BlinkRTCPeerConnection.instance.updateIce_Callback_0_(this);
    return;
  }

  /// 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) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


@DocsEditable()
@DomName('RTCSessionDescription')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCSessionDescription
class RtcSessionDescription extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory RtcSessionDescription._() { throw new UnsupportedError("Not supported"); }

  @DomName('RTCSessionDescription.RTCSessionDescription')
  @DocsEditable()
  factory RtcSessionDescription([Map descriptionInitDict]) {
    if (descriptionInitDict != null) {
      return _blink.BlinkRTCSessionDescription.instance.constructorCallback_1_(descriptionInitDict);
    }
    return _blink.BlinkRTCSessionDescription.instance.constructorCallback_0_();
  }

  @DomName('RTCSessionDescription.sdp')
  @DocsEditable()
  String get sdp => _blink.BlinkRTCSessionDescription.instance.sdp_Getter_(this);

  @DomName('RTCSessionDescription.sdp')
  @DocsEditable()
  void set sdp(String value) => _blink.BlinkRTCSessionDescription.instance.sdp_Setter_(this, value);

  @DomName('RTCSessionDescription.type')
  @DocsEditable()
  String get type => _blink.BlinkRTCSessionDescription.instance.type_Getter_(this);

  @DomName('RTCSessionDescription.type')
  @DocsEditable()
  void set type(String value) => _blink.BlinkRTCSessionDescription.instance.type_Setter_(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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('RTCStatsReport')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCStatsReport
@Experimental()
class RtcStatsReport extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory RtcStatsReport._() { throw new UnsupportedError("Not supported"); }

  @DomName('RTCStatsReport.id')
  @DocsEditable()
  String get id => _blink.BlinkRTCStatsReport.instance.id_Getter_(this);

  @DomName('RTCStatsReport.local')
  @DocsEditable()
  RtcStatsReport get local => _blink.BlinkRTCStatsReport.instance.local_Getter_(this);

  @DomName('RTCStatsReport.remote')
  @DocsEditable()
  RtcStatsReport get remote => _blink.BlinkRTCStatsReport.instance.remote_Getter_(this);

  @DomName('RTCStatsReport.timestamp')
  @DocsEditable()
  DateTime get timestamp => _blink.BlinkRTCStatsReport.instance.timestamp_Getter_(this);

  @DomName('RTCStatsReport.type')
  @DocsEditable()
  String get type => _blink.BlinkRTCStatsReport.instance.type_Getter_(this);

  @DomName('RTCStatsReport.names')
  @DocsEditable()
  List<String> names() => _blink.BlinkRTCStatsReport.instance.names_Callback_0_(this);

  @DomName('RTCStatsReport.stat')
  @DocsEditable()
  String stat(String name) => _blink.BlinkRTCStatsReport.instance.stat_Callback_1_(this, 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.


@DocsEditable()
@DomName('RTCStatsResponse')
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#widl-RTCStatsReport-RTCStats-getter-DOMString-id
@Experimental()
class RtcStatsResponse extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory RtcStatsResponse._() { throw new UnsupportedError("Not supported"); }

  @DomName('RTCStatsResponse.__getter__')
  @DocsEditable()
  RtcStatsReport __getter__(String name) => _blink.BlinkRTCStatsResponse.instance.$__getter___Callback_1_(this, name);

  @DomName('RTCStatsResponse.namedItem')
  @DocsEditable()
  RtcStatsReport namedItem(String name) => _blink.BlinkRTCStatsResponse.instance.namedItem_Callback_1_(this, name);

  @DomName('RTCStatsResponse.result')
  @DocsEditable()
  List<RtcStatsReport> result() => _blink.BlinkRTCStatsResponse.instance.result_Callback_0_(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('Screen')
class Screen extends NativeFieldWrapperClass2 {

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

  @DomName('Screen.availHeight')
  @DocsEditable()
  int get _availHeight => _blink.BlinkScreen.instance.availHeight_Getter_(this);

  @DomName('Screen.availLeft')
  @DocsEditable()
  @Experimental() // nonstandard
  int get _availLeft => _blink.BlinkScreen.instance.availLeft_Getter_(this);

  @DomName('Screen.availTop')
  @DocsEditable()
  @Experimental() // nonstandard
  int get _availTop => _blink.BlinkScreen.instance.availTop_Getter_(this);

  @DomName('Screen.availWidth')
  @DocsEditable()
  int get _availWidth => _blink.BlinkScreen.instance.availWidth_Getter_(this);

  @DomName('Screen.colorDepth')
  @DocsEditable()
  int get colorDepth => _blink.BlinkScreen.instance.colorDepth_Getter_(this);

  @DomName('Screen.height')
  @DocsEditable()
  int get height => _blink.BlinkScreen.instance.height_Getter_(this);

  @DomName('Screen.orientation')
  @DocsEditable()
  @Experimental() // untriaged
  ScreenOrientation get orientation => _blink.BlinkScreen.instance.orientation_Getter_(this);

  @DomName('Screen.pixelDepth')
  @DocsEditable()
  int get pixelDepth => _blink.BlinkScreen.instance.pixelDepth_Getter_(this);

  @DomName('Screen.width')
  @DocsEditable()
  int get width => _blink.BlinkScreen.instance.width_Getter_(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.


@DocsEditable()
@DomName('ScreenOrientation')
@Experimental() // untriaged
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
  int get angle => _blink.BlinkScreenOrientation.instance.angle_Getter_(this);

  @DomName('ScreenOrientation.type')
  @DocsEditable()
  @Experimental() // untriaged
  String get type => _blink.BlinkScreenOrientation.instance.type_Getter_(this);

  @DomName('ScreenOrientation.lock')
  @DocsEditable()
  @Experimental() // untriaged
  Future lock(String orientation) => _blink.BlinkScreenOrientation.instance.lock_Callback_1_(this, orientation);

  @DomName('ScreenOrientation.unlock')
  @DocsEditable()
  @Experimental() // untriaged
  void unlock() => _blink.BlinkScreenOrientation.instance.unlock_Callback_0_(this);

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

// WARNING: Do not edit - generated code.


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

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

  @DomName('HTMLScriptElement.async')
  @DocsEditable()
  bool get async => _blink.BlinkHTMLScriptElement.instance.async_Getter_(this);

  @DomName('HTMLScriptElement.async')
  @DocsEditable()
  void set async(bool value) => _blink.BlinkHTMLScriptElement.instance.async_Setter_(this, value);

  @DomName('HTMLScriptElement.charset')
  @DocsEditable()
  String get charset => _blink.BlinkHTMLScriptElement.instance.charset_Getter_(this);

  @DomName('HTMLScriptElement.charset')
  @DocsEditable()
  void set charset(String value) => _blink.BlinkHTMLScriptElement.instance.charset_Setter_(this, value);

  @DomName('HTMLScriptElement.crossOrigin')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#attr-script-crossorigin
  @Experimental()
  String get crossOrigin => _blink.BlinkHTMLScriptElement.instance.crossOrigin_Getter_(this);

  @DomName('HTMLScriptElement.crossOrigin')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#attr-script-crossorigin
  @Experimental()
  void set crossOrigin(String value) => _blink.BlinkHTMLScriptElement.instance.crossOrigin_Setter_(this, value);

  @DomName('HTMLScriptElement.defer')
  @DocsEditable()
  bool get defer => _blink.BlinkHTMLScriptElement.instance.defer_Getter_(this);

  @DomName('HTMLScriptElement.defer')
  @DocsEditable()
  void set defer(bool value) => _blink.BlinkHTMLScriptElement.instance.defer_Setter_(this, value);

  @DomName('HTMLScriptElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String get integrity => _blink.BlinkHTMLScriptElement.instance.integrity_Getter_(this);

  @DomName('HTMLScriptElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  void set integrity(String value) => _blink.BlinkHTMLScriptElement.instance.integrity_Setter_(this, value);

  @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 get nonce => _blink.BlinkHTMLScriptElement.instance.nonce_Getter_(this);

  @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()
  void set nonce(String value) => _blink.BlinkHTMLScriptElement.instance.nonce_Setter_(this, value);

  @DomName('HTMLScriptElement.src')
  @DocsEditable()
  String get src => _blink.BlinkHTMLScriptElement.instance.src_Getter_(this);

  @DomName('HTMLScriptElement.src')
  @DocsEditable()
  void set src(String value) => _blink.BlinkHTMLScriptElement.instance.src_Setter_(this, value);

  @DomName('HTMLScriptElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLScriptElement.instance.type_Getter_(this);

  @DomName('HTMLScriptElement.type')
  @DocsEditable()
  void set type(String value) => _blink.BlinkHTMLScriptElement.instance.type_Setter_(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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('SecurityPolicyViolationEvent')
// https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#securitypolicyviolationevent-events
@Experimental()
class SecurityPolicyViolationEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory SecurityPolicyViolationEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('SecurityPolicyViolationEvent.blockedURI')
  @DocsEditable()
  String get blockedUri => _blink.BlinkSecurityPolicyViolationEvent.instance.blockedURI_Getter_(this);

  @DomName('SecurityPolicyViolationEvent.columnNumber')
  @DocsEditable()
  int get columnNumber => _blink.BlinkSecurityPolicyViolationEvent.instance.columnNumber_Getter_(this);

  @DomName('SecurityPolicyViolationEvent.documentURI')
  @DocsEditable()
  String get documentUri => _blink.BlinkSecurityPolicyViolationEvent.instance.documentURI_Getter_(this);

  @DomName('SecurityPolicyViolationEvent.effectiveDirective')
  @DocsEditable()
  String get effectiveDirective => _blink.BlinkSecurityPolicyViolationEvent.instance.effectiveDirective_Getter_(this);

  @DomName('SecurityPolicyViolationEvent.lineNumber')
  @DocsEditable()
  int get lineNumber => _blink.BlinkSecurityPolicyViolationEvent.instance.lineNumber_Getter_(this);

  @DomName('SecurityPolicyViolationEvent.originalPolicy')
  @DocsEditable()
  String get originalPolicy => _blink.BlinkSecurityPolicyViolationEvent.instance.originalPolicy_Getter_(this);

  @DomName('SecurityPolicyViolationEvent.referrer')
  @DocsEditable()
  String get referrer => _blink.BlinkSecurityPolicyViolationEvent.instance.referrer_Getter_(this);

  @DomName('SecurityPolicyViolationEvent.sourceFile')
  @DocsEditable()
  String get sourceFile => _blink.BlinkSecurityPolicyViolationEvent.instance.sourceFile_Getter_(this);

  @DomName('SecurityPolicyViolationEvent.statusCode')
  @DocsEditable()
  @Experimental() // untriaged
  int get statusCode => _blink.BlinkSecurityPolicyViolationEvent.instance.statusCode_Getter_(this);

  @DomName('SecurityPolicyViolationEvent.violatedDirective')
  @DocsEditable()
  String get violatedDirective => _blink.BlinkSecurityPolicyViolationEvent.instance.violatedDirective_Getter_(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('HTMLSelectElement')
class SelectElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory SelectElement._() { throw new UnsupportedError("Not supported"); }

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

  @DomName('HTMLSelectElement.autofocus')
  @DocsEditable()
  bool get autofocus => _blink.BlinkHTMLSelectElement.instance.autofocus_Getter_(this);

  @DomName('HTMLSelectElement.autofocus')
  @DocsEditable()
  void set autofocus(bool value) => _blink.BlinkHTMLSelectElement.instance.autofocus_Setter_(this, value);

  @DomName('HTMLSelectElement.disabled')
  @DocsEditable()
  bool get disabled => _blink.BlinkHTMLSelectElement.instance.disabled_Getter_(this);

  @DomName('HTMLSelectElement.disabled')
  @DocsEditable()
  void set disabled(bool value) => _blink.BlinkHTMLSelectElement.instance.disabled_Setter_(this, value);

  @DomName('HTMLSelectElement.form')
  @DocsEditable()
  FormElement get form => _blink.BlinkHTMLSelectElement.instance.form_Getter_(this);

  @DomName('HTMLSelectElement.labels')
  @DocsEditable()
  @Unstable()
  List<Node> get labels => _blink.BlinkHTMLSelectElement.instance.labels_Getter_(this);

  @DomName('HTMLSelectElement.length')
  @DocsEditable()
  int get length => _blink.BlinkHTMLSelectElement.instance.length_Getter_(this);

  @DomName('HTMLSelectElement.length')
  @DocsEditable()
  void set length(int value) => _blink.BlinkHTMLSelectElement.instance.length_Setter_(this, value);

  @DomName('HTMLSelectElement.multiple')
  @DocsEditable()
  bool get multiple => _blink.BlinkHTMLSelectElement.instance.multiple_Getter_(this);

  @DomName('HTMLSelectElement.multiple')
  @DocsEditable()
  void set multiple(bool value) => _blink.BlinkHTMLSelectElement.instance.multiple_Setter_(this, value);

  @DomName('HTMLSelectElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLSelectElement.instance.name_Getter_(this);

  @DomName('HTMLSelectElement.name')
  @DocsEditable()
  void set name(String value) => _blink.BlinkHTMLSelectElement.instance.name_Setter_(this, value);

  @DomName('HTMLSelectElement.required')
  @DocsEditable()
  bool get required => _blink.BlinkHTMLSelectElement.instance.required_Getter_(this);

  @DomName('HTMLSelectElement.required')
  @DocsEditable()
  void set required(bool value) => _blink.BlinkHTMLSelectElement.instance.required_Setter_(this, value);

  @DomName('HTMLSelectElement.selectedIndex')
  @DocsEditable()
  int get selectedIndex => _blink.BlinkHTMLSelectElement.instance.selectedIndex_Getter_(this);

  @DomName('HTMLSelectElement.selectedIndex')
  @DocsEditable()
  void set selectedIndex(int value) => _blink.BlinkHTMLSelectElement.instance.selectedIndex_Setter_(this, value);

  @DomName('HTMLSelectElement.size')
  @DocsEditable()
  int get size => _blink.BlinkHTMLSelectElement.instance.size_Getter_(this);

  @DomName('HTMLSelectElement.size')
  @DocsEditable()
  void set size(int value) => _blink.BlinkHTMLSelectElement.instance.size_Setter_(this, value);

  @DomName('HTMLSelectElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLSelectElement.instance.type_Getter_(this);

  @DomName('HTMLSelectElement.validationMessage')
  @DocsEditable()
  String get validationMessage => _blink.BlinkHTMLSelectElement.instance.validationMessage_Getter_(this);

  @DomName('HTMLSelectElement.validity')
  @DocsEditable()
  ValidityState get validity => _blink.BlinkHTMLSelectElement.instance.validity_Getter_(this);

  @DomName('HTMLSelectElement.value')
  @DocsEditable()
  String get value => _blink.BlinkHTMLSelectElement.instance.value_Getter_(this);

  @DomName('HTMLSelectElement.value')
  @DocsEditable()
  void set value(String value) => _blink.BlinkHTMLSelectElement.instance.value_Setter_(this, value);

  @DomName('HTMLSelectElement.willValidate')
  @DocsEditable()
  bool get willValidate => _blink.BlinkHTMLSelectElement.instance.willValidate_Getter_(this);

  @DomName('HTMLSelectElement.__setter__')
  @DocsEditable()
  void __setter__(int index, OptionElement value) => _blink.BlinkHTMLSelectElement.instance.$__setter___Callback_2_(this, index, value);

  @DomName('HTMLSelectElement.add')
  @DocsEditable()
  @Experimental() // untriaged
  void add(HtmlElement element, int before) => _blink.BlinkHTMLSelectElement.instance.add_Callback_2_(this, element, before);

  @DomName('HTMLSelectElement.checkValidity')
  @DocsEditable()
  bool checkValidity() => _blink.BlinkHTMLSelectElement.instance.checkValidity_Callback_0_(this);

  @DomName('HTMLSelectElement.item')
  @DocsEditable()
  Element item(int index) => _blink.BlinkHTMLSelectElement.instance.item_Callback_1_(this, index);

  @DomName('HTMLSelectElement.namedItem')
  @DocsEditable()
  Element namedItem(String name) => _blink.BlinkHTMLSelectElement.instance.namedItem_Callback_1_(this, name);

  @DomName('HTMLSelectElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) => _blink.BlinkHTMLSelectElement.instance.setCustomValidity_Callback_1_(this, error);


  // Override default options, since IE returns SelectElement itself and it
  // does not operate as a List.
  List<OptionElement> get options {
    var options = this.querySelectorAll('option').where(
        (e) => e is OptionElement).toList();
    return new UnmodifiableListView(options);
  }

  List<OptionElement> get selectedOptions {
    // IE does not change the selected flag for single-selection items.
    if (this.multiple) {
      var options = this.options.where((o) => o.selected).toList();
      return new UnmodifiableListView(options);
    } else {
      return [this.options[this.selectedIndex]];
    }
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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

  @DomName('Selection.anchorNode')
  @DocsEditable()
  Node get anchorNode => _blink.BlinkSelection.instance.anchorNode_Getter_(this);

  @DomName('Selection.anchorOffset')
  @DocsEditable()
  int get anchorOffset => _blink.BlinkSelection.instance.anchorOffset_Getter_(this);

  @DomName('Selection.baseNode')
  @DocsEditable()
  @Experimental() // non-standard
  Node get baseNode => _blink.BlinkSelection.instance.baseNode_Getter_(this);

  @DomName('Selection.baseOffset')
  @DocsEditable()
  @Experimental() // non-standard
  int get baseOffset => _blink.BlinkSelection.instance.baseOffset_Getter_(this);

  @DomName('Selection.extentNode')
  @DocsEditable()
  @Experimental() // non-standard
  Node get extentNode => _blink.BlinkSelection.instance.extentNode_Getter_(this);

  @DomName('Selection.extentOffset')
  @DocsEditable()
  @Experimental() // non-standard
  int get extentOffset => _blink.BlinkSelection.instance.extentOffset_Getter_(this);

  @DomName('Selection.focusNode')
  @DocsEditable()
  Node get focusNode => _blink.BlinkSelection.instance.focusNode_Getter_(this);

  @DomName('Selection.focusOffset')
  @DocsEditable()
  int get focusOffset => _blink.BlinkSelection.instance.focusOffset_Getter_(this);

  @DomName('Selection.isCollapsed')
  @DocsEditable()
  bool get isCollapsed => _blink.BlinkSelection.instance.isCollapsed_Getter_(this);

  @DomName('Selection.rangeCount')
  @DocsEditable()
  int get rangeCount => _blink.BlinkSelection.instance.rangeCount_Getter_(this);

  @DomName('Selection.type')
  @DocsEditable()
  @Experimental() // non-standard
  String get type => _blink.BlinkSelection.instance.type_Getter_(this);

  @DomName('Selection.addRange')
  @DocsEditable()
  void addRange(Range range) => _blink.BlinkSelection.instance.addRange_Callback_1_(this, range);

  void collapse(Node node, [int offset]) {
    if (offset != null) {
      _blink.BlinkSelection.instance.collapse_Callback_2_(this, node, offset);
      return;
    }
    _blink.BlinkSelection.instance.collapse_Callback_1_(this, node);
    return;
  }

  @DomName('Selection.collapseToEnd')
  @DocsEditable()
  void collapseToEnd() => _blink.BlinkSelection.instance.collapseToEnd_Callback_0_(this);

  @DomName('Selection.collapseToStart')
  @DocsEditable()
  void collapseToStart() => _blink.BlinkSelection.instance.collapseToStart_Callback_0_(this);

  @DomName('Selection.containsNode')
  @DocsEditable()
  @Experimental() // non-standard
  bool containsNode(Node node, bool allowPartial) => _blink.BlinkSelection.instance.containsNode_Callback_2_(this, node, allowPartial);

  @DomName('Selection.deleteFromDocument')
  @DocsEditable()
  void deleteFromDocument() => _blink.BlinkSelection.instance.deleteFromDocument_Callback_0_(this);

  @DomName('Selection.empty')
  @DocsEditable()
  @Experimental() // non-standard
  void empty() => _blink.BlinkSelection.instance.empty_Callback_0_(this);

  void extend(Node node, [int offset]) {
    if (offset != null) {
      _blink.BlinkSelection.instance.extend_Callback_2_(this, node, offset);
      return;
    }
    _blink.BlinkSelection.instance.extend_Callback_1_(this, node);
    return;
  }

  @DomName('Selection.getRangeAt')
  @DocsEditable()
  Range getRangeAt(int index) => _blink.BlinkSelection.instance.getRangeAt_Callback_1_(this, index);

  @DomName('Selection.modify')
  @DocsEditable()
  @Experimental() // non-standard
  void modify(String alter, String direction, String granularity) => _blink.BlinkSelection.instance.modify_Callback_3_(this, alter, direction, granularity);

  @DomName('Selection.removeAllRanges')
  @DocsEditable()
  void removeAllRanges() => _blink.BlinkSelection.instance.removeAllRanges_Callback_0_(this);

  @DomName('Selection.selectAllChildren')
  @DocsEditable()
  void selectAllChildren(Node node) => _blink.BlinkSelection.instance.selectAllChildren_Callback_1_(this, node);

  @DomName('Selection.setBaseAndExtent')
  @DocsEditable()
  @Experimental() // non-standard
  void setBaseAndExtent(Node baseNode, int baseOffset, Node extentNode, int extentOffset) => _blink.BlinkSelection.instance.setBaseAndExtent_Callback_4_(this, baseNode, baseOffset, extentNode, extentOffset);

  void setPosition(Node node, [int offset]) {
    if (offset != null) {
      _blink.BlinkSelection.instance.setPosition_Callback_2_(this, node, offset);
      return;
    }
    _blink.BlinkSelection.instance.setPosition_Callback_1_(this, node);
    return;
  }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

  @DomName('ServiceWorkerClient.id')
  @DocsEditable()
  @Experimental() // untriaged
  int get id => _blink.BlinkServiceWorkerClient.instance.id_Getter_(this);

  @DomName('ServiceWorkerClient.postMessage')
  @DocsEditable()
  @Experimental() // untriaged
  void postMessage(/*SerializedScriptValue*/ message, [List<MessagePort> transfer]) => _blink.BlinkServiceWorkerClient.instance.postMessage_Callback_2_(this, message, transfer);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

  @DomName('ServiceWorkerClients.getServiced')
  @DocsEditable()
  @Experimental() // untriaged
  Future getServiced() => _blink.BlinkServiceWorkerClients.instance.getServiced_Callback_0_(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.


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

  @DomName('ServiceWorkerContainer.active')
  @DocsEditable()
  @Experimental() // untriaged
  _ServiceWorker get active => _blink.BlinkServiceWorkerContainer.instance.active_Getter_(this);

  @DomName('ServiceWorkerContainer.controller')
  @DocsEditable()
  @Experimental() // untriaged
  _ServiceWorker get controller => _blink.BlinkServiceWorkerContainer.instance.controller_Getter_(this);

  @DomName('ServiceWorkerContainer.installing')
  @DocsEditable()
  @Experimental() // untriaged
  _ServiceWorker get installing => _blink.BlinkServiceWorkerContainer.instance.installing_Getter_(this);

  @DomName('ServiceWorkerContainer.ready')
  @DocsEditable()
  @Experimental() // untriaged
  Future get ready => _blink.BlinkServiceWorkerContainer.instance.ready_Getter_(this);

  @DomName('ServiceWorkerContainer.waiting')
  @DocsEditable()
  @Experimental() // untriaged
  _ServiceWorker get waiting => _blink.BlinkServiceWorkerContainer.instance.waiting_Getter_(this);

  Future register(String url, [Map options]) {
    if (options != null) {
      return _blink.BlinkServiceWorkerContainer.instance.register_Callback_2_(this, url, options);
    }
    return _blink.BlinkServiceWorkerContainer.instance.register_Callback_1_(this, url);
  }

  Future unregister([String scope]) {
    if (scope != null) {
      return _blink.BlinkServiceWorkerContainer.instance.unregister_Callback_1_(this, scope);
    }
    return _blink.BlinkServiceWorkerContainer.instance.unregister_Callback_0_(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.


@DocsEditable()
@DomName('ServiceWorkerGlobalScope')
@Experimental() // untriaged
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
  ServiceWorkerClients get clients => _blink.BlinkServiceWorkerGlobalScope.instance.clients_Getter_(this);

  @DomName('ServiceWorkerGlobalScope.nativeCaches')
  @DocsEditable()
  @Experimental() // untriaged
  CacheStorage get nativeCaches => _blink.BlinkServiceWorkerGlobalScope.instance.nativeCaches_Getter_(this);

  @DomName('ServiceWorkerGlobalScope.scope')
  @DocsEditable()
  @Experimental() // untriaged
  String get scope => _blink.BlinkServiceWorkerGlobalScope.instance.scope_Getter_(this);

  Future _fetch(request, [Map requestInitDict]) {
    if ((request is String || request == null) && requestInitDict == null) {
      return _blink.BlinkServiceWorkerGlobalScope.instance.fetch_Callback_1_(this, request);
    }
    if ((requestInitDict is Map || requestInitDict == null) && (request is String || request == null)) {
      return _blink.BlinkServiceWorkerGlobalScope.instance.fetch_Callback_2_(this, request, requestInitDict);
    }
    if ((request is _Request || request == null) && requestInitDict == null) {
      return _blink.BlinkServiceWorkerGlobalScope.instance.fetch_Callback_1_(this, request);
    }
    if ((requestInitDict is Map || requestInitDict == null) && (request is _Request || request == null)) {
      return _blink.BlinkServiceWorkerGlobalScope.instance.fetch_Callback_2_(this, request, requestInitDict);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('ServiceWorkerGlobalScope.onmessage')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

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

// WARNING: Do not edit - generated code.


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

  @DomName('ServiceWorkerRegistration.active')
  @DocsEditable()
  @Experimental() // untriaged
  _ServiceWorker get active => _blink.BlinkServiceWorkerRegistration.instance.active_Getter_(this);

  @DomName('ServiceWorkerRegistration.installing')
  @DocsEditable()
  @Experimental() // untriaged
  _ServiceWorker get installing => _blink.BlinkServiceWorkerRegistration.instance.installing_Getter_(this);

  @DomName('ServiceWorkerRegistration.scope')
  @DocsEditable()
  @Experimental() // untriaged
  String get scope => _blink.BlinkServiceWorkerRegistration.instance.scope_Getter_(this);

  @DomName('ServiceWorkerRegistration.waiting')
  @DocsEditable()
  @Experimental() // untriaged
  _ServiceWorker get waiting => _blink.BlinkServiceWorkerRegistration.instance.waiting_Getter_(this);

  @DomName('ServiceWorkerRegistration.unregister')
  @DocsEditable()
  @Experimental() // untriaged
  Future unregister() => _blink.BlinkServiceWorkerRegistration.instance.unregister_Callback_0_(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.


@DocsEditable()
@DomName('HTMLShadowElement')
@SupportedBrowser(SupportedBrowser.CHROME, '26')
@Experimental()
// https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#shadow-element
class ShadowElement extends HtmlElement {
  // 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 => true;

  @DomName('HTMLShadowElement.getDistributedNodes')
  @DocsEditable()
  @Experimental() // untriaged
  List<Node> getDistributedNodes() => _blink.BlinkHTMLShadowElement.instance.getDistributedNodes_Callback_0_(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('ShadowRoot')
@SupportedBrowser(SupportedBrowser.CHROME, '26')
@Experimental()
// https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#api-shadow-root
class ShadowRoot extends DocumentFragment {
  // To suppress missing implicit constructor warnings.
  factory ShadowRoot._() { throw new UnsupportedError("Not supported"); }

  @DomName('ShadowRoot.activeElement')
  @DocsEditable()
  Element get activeElement => _blink.BlinkShadowRoot.instance.activeElement_Getter_(this);

  @DomName('ShadowRoot.host')
  @DocsEditable()
  @Experimental() // untriaged
  Element get host => _blink.BlinkShadowRoot.instance.host_Getter_(this);

  @DomName('ShadowRoot.innerHTML')
  @DocsEditable()
  String get innerHtml => _blink.BlinkShadowRoot.instance.innerHTML_Getter_(this);

  @DomName('ShadowRoot.innerHTML')
  @DocsEditable()
  void set innerHtml(String value) => _blink.BlinkShadowRoot.instance.innerHTML_Setter_(this, value);

  @DomName('ShadowRoot.olderShadowRoot')
  @DocsEditable()
  @Experimental() // untriaged
  ShadowRoot get olderShadowRoot => _blink.BlinkShadowRoot.instance.olderShadowRoot_Getter_(this);

  @DomName('ShadowRoot.styleSheets')
  @DocsEditable()
  @Experimental() // untriaged
  List<StyleSheet> get styleSheets => _blink.BlinkShadowRoot.instance.styleSheets_Getter_(this);

  @DomName('ShadowRoot.cloneNode')
  @DocsEditable()
  Node clone(bool deep) => _blink.BlinkShadowRoot.instance.cloneNode_Callback_1_(this, deep);

  @DomName('ShadowRoot.elementFromPoint')
  @DocsEditable()
  Element elementFromPoint(int x, int y) => _blink.BlinkShadowRoot.instance.elementFromPoint_Callback_2_(this, x, y);

  @DomName('ShadowRoot.getElementById')
  @DocsEditable()
  Element getElementById(String elementId) => _blink.BlinkShadowRoot.instance.getElementById_Callback_1_(this, elementId);

  @DomName('ShadowRoot.getElementsByClassName')
  @DocsEditable()
  List<Node> getElementsByClassName(String className) => _blink.BlinkShadowRoot.instance.getElementsByClassName_Callback_1_(this, className);

  @DomName('ShadowRoot.getElementsByTagName')
  @DocsEditable()
  List<Node> getElementsByTagName(String tagName) => _blink.BlinkShadowRoot.instance.getElementsByTagName_Callback_1_(this, tagName);

  @DomName('ShadowRoot.getSelection')
  @DocsEditable()
  Selection getSelection() => _blink.BlinkShadowRoot.instance.getSelection_Callback_0_(this);

  static final bool supported = true;

  static bool _shadowRootDeprecationReported = false;
  static void _shadowRootDeprecationReport() {
    if (!_shadowRootDeprecationReported) {
      window.console.warn('''
ShadowRoot.resetStyleInheritance and ShadowRoot.applyAuthorStyles now deprecated in dart:html.
Please remove them from your code.
''');
      _shadowRootDeprecationReported = true;
    }
  }

  @deprecated
  bool get resetStyleInheritance {
    _shadowRootDeprecationReport();
    // Default value from when it was specified.
    return false;
  }

  @deprecated
  void set resetStyleInheritance(bool value) {
    _shadowRootDeprecationReport();
  }

  @deprecated
  bool get applyAuthorStyles {
    _shadowRootDeprecationReport();
    // Default value from when it was specified.
    return false;
  }

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

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('SharedWorker')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#shared-workers-and-the-sharedworker-interface
@Experimental()
class SharedWorker extends EventTarget implements AbstractWorker {
  // 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]) {
    return _blink.BlinkSharedWorker.instance.constructorCallback_2_(scriptURL, name);
  }

  @DomName('SharedWorker.port')
  @DocsEditable()
  MessagePort get port => _blink.BlinkSharedWorker.instance.port_Getter_(this);

  @DomName('SharedWorker.workerStart')
  @DocsEditable()
  @Experimental() // untriaged
  double get workerStart => _blink.BlinkSharedWorker.instance.workerStart_Getter_(this);

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

// WARNING: Do not edit - generated code.


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

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

  @DomName('SharedWorkerGlobalScope.name')
  @DocsEditable()
  @Experimental() // untriaged
  String get name => _blink.BlinkSharedWorkerGlobalScope.instance.name_Getter_(this);

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

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('SourceBuffer')
// https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#sourcebuffer
@Experimental()
class SourceBuffer extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory SourceBuffer._() { throw new UnsupportedError("Not supported"); }

  @DomName('SourceBuffer.appendWindowEnd')
  @DocsEditable()
  @Experimental() // untriaged
  num get appendWindowEnd => _blink.BlinkSourceBuffer.instance.appendWindowEnd_Getter_(this);

  @DomName('SourceBuffer.appendWindowEnd')
  @DocsEditable()
  @Experimental() // untriaged
  void set appendWindowEnd(num value) => _blink.BlinkSourceBuffer.instance.appendWindowEnd_Setter_(this, value);

  @DomName('SourceBuffer.appendWindowStart')
  @DocsEditable()
  @Experimental() // untriaged
  num get appendWindowStart => _blink.BlinkSourceBuffer.instance.appendWindowStart_Getter_(this);

  @DomName('SourceBuffer.appendWindowStart')
  @DocsEditable()
  @Experimental() // untriaged
  void set appendWindowStart(num value) => _blink.BlinkSourceBuffer.instance.appendWindowStart_Setter_(this, value);

  @DomName('SourceBuffer.buffered')
  @DocsEditable()
  TimeRanges get buffered => _blink.BlinkSourceBuffer.instance.buffered_Getter_(this);

  @DomName('SourceBuffer.mode')
  @DocsEditable()
  @Experimental() // untriaged
  String get mode => _blink.BlinkSourceBuffer.instance.mode_Getter_(this);

  @DomName('SourceBuffer.mode')
  @DocsEditable()
  @Experimental() // untriaged
  void set mode(String value) => _blink.BlinkSourceBuffer.instance.mode_Setter_(this, value);

  @DomName('SourceBuffer.timestampOffset')
  @DocsEditable()
  num get timestampOffset => _blink.BlinkSourceBuffer.instance.timestampOffset_Getter_(this);

  @DomName('SourceBuffer.timestampOffset')
  @DocsEditable()
  void set timestampOffset(num value) => _blink.BlinkSourceBuffer.instance.timestampOffset_Setter_(this, value);

  @DomName('SourceBuffer.updating')
  @DocsEditable()
  @Experimental() // untriaged
  bool get updating => _blink.BlinkSourceBuffer.instance.updating_Getter_(this);

  @DomName('SourceBuffer.abort')
  @DocsEditable()
  void abort() => _blink.BlinkSourceBuffer.instance.abort_Callback_0_(this);

  @DomName('SourceBuffer.appendBuffer')
  @DocsEditable()
  @Experimental() // untriaged
  void appendBuffer(ByteBuffer data) => _blink.BlinkSourceBuffer.instance.appendBuffer_Callback_1_(this, data);

  void appendStream(FileStream stream, [int maxSize]) {
    if (maxSize != null) {
      _blink.BlinkSourceBuffer.instance.appendStream_Callback_2_(this, stream, maxSize);
      return;
    }
    _blink.BlinkSourceBuffer.instance.appendStream_Callback_1_(this, stream);
    return;
  }

  @DomName('SourceBuffer.appendTypedData')
  @DocsEditable()
  @Experimental() // untriaged
  void appendTypedData(TypedData data) => _blink.BlinkSourceBuffer.instance.appendBuffer_Callback_1_(this, data);

  @DomName('SourceBuffer.remove')
  @DocsEditable()
  @Experimental() // untriaged
  void remove(num start, num end) => _blink.BlinkSourceBuffer.instance.remove_Callback_2_(this, start, end);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


@DocsEditable()
@DomName('SourceBufferList')
// https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#sourcebufferlist
@Experimental()
class SourceBufferList extends EventTarget with ListMixin<SourceBuffer>, ImmutableListMixin<SourceBuffer> implements List<SourceBuffer> {
  // To suppress missing implicit constructor warnings.
  factory SourceBufferList._() { throw new UnsupportedError("Not supported"); }

  @DomName('SourceBufferList.length')
  @DocsEditable()
  int get length => _blink.BlinkSourceBufferList.instance.length_Getter_(this);

  SourceBuffer operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return _blink.BlinkSourceBufferList.instance.item_Callback_1_(this, index);
  }

  SourceBuffer _nativeIndexedGetter(int index) => _blink.BlinkSourceBufferList.instance.item_Callback_1_(this, index);

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


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

  SourceBuffer get first {
    if (this.length > 0) {
      return _nativeIndexedGetter(0);
    }
    throw new StateError("No elements");
  }

  SourceBuffer get last {
    int len = this.length;
    if (len > 0) {
      return _nativeIndexedGetter(len - 1);
    }
    throw new StateError("No elements");
  }

  SourceBuffer get single {
    int len = this.length;
    if (len == 1) {
      return _nativeIndexedGetter(0);
    }
    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) => _blink.BlinkSourceBufferList.instance.item_Callback_1_(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.


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

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

  @DomName('HTMLSourceElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String get integrity => _blink.BlinkHTMLSourceElement.instance.integrity_Getter_(this);

  @DomName('HTMLSourceElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  void set integrity(String value) => _blink.BlinkHTMLSourceElement.instance.integrity_Setter_(this, value);

  @DomName('HTMLSourceElement.media')
  @DocsEditable()
  String get media => _blink.BlinkHTMLSourceElement.instance.media_Getter_(this);

  @DomName('HTMLSourceElement.media')
  @DocsEditable()
  void set media(String value) => _blink.BlinkHTMLSourceElement.instance.media_Setter_(this, value);

  @DomName('HTMLSourceElement.sizes')
  @DocsEditable()
  @Experimental() // untriaged
  String get sizes => _blink.BlinkHTMLSourceElement.instance.sizes_Getter_(this);

  @DomName('HTMLSourceElement.sizes')
  @DocsEditable()
  @Experimental() // untriaged
  void set sizes(String value) => _blink.BlinkHTMLSourceElement.instance.sizes_Setter_(this, value);

  @DomName('HTMLSourceElement.src')
  @DocsEditable()
  String get src => _blink.BlinkHTMLSourceElement.instance.src_Getter_(this);

  @DomName('HTMLSourceElement.src')
  @DocsEditable()
  void set src(String value) => _blink.BlinkHTMLSourceElement.instance.src_Setter_(this, value);

  @DomName('HTMLSourceElement.srcset')
  @DocsEditable()
  @Experimental() // untriaged
  String get srcset => _blink.BlinkHTMLSourceElement.instance.srcset_Getter_(this);

  @DomName('HTMLSourceElement.srcset')
  @DocsEditable()
  @Experimental() // untriaged
  void set srcset(String value) => _blink.BlinkHTMLSourceElement.instance.srcset_Setter_(this, value);

  @DomName('HTMLSourceElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLSourceElement.instance.type_Getter_(this);

  @DomName('HTMLSourceElement.type')
  @DocsEditable()
  void set type(String value) => _blink.BlinkHTMLSourceElement.instance.type_Setter_(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.

// WARNING: Do not edit - generated code.


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

  @DomName('SourceInfo.facing')
  @DocsEditable()
  @Experimental() // untriaged
  String get facing => _blink.BlinkSourceInfo.instance.facing_Getter_(this);

  @DomName('SourceInfo.id')
  @DocsEditable()
  @Experimental() // untriaged
  String get id => _blink.BlinkSourceInfo.instance.id_Getter_(this);

  @DomName('SourceInfo.kind')
  @DocsEditable()
  @Experimental() // untriaged
  String get kind => _blink.BlinkSourceInfo.instance.kind_Getter_(this);

  @DomName('SourceInfo.label')
  @DocsEditable()
  @Experimental() // untriaged
  String get label => _blink.BlinkSourceInfo.instance.label_Getter_(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.


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

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

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

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('SpeechGrammar')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#dfn-speechgrammar
@Experimental()
class SpeechGrammar extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory SpeechGrammar._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechGrammar.SpeechGrammar')
  @DocsEditable()
  factory SpeechGrammar() {
    return _blink.BlinkSpeechGrammar.instance.constructorCallback_0_();
  }

  @DomName('SpeechGrammar.src')
  @DocsEditable()
  String get src => _blink.BlinkSpeechGrammar.instance.src_Getter_(this);

  @DomName('SpeechGrammar.src')
  @DocsEditable()
  void set src(String value) => _blink.BlinkSpeechGrammar.instance.src_Setter_(this, value);

  @DomName('SpeechGrammar.weight')
  @DocsEditable()
  num get weight => _blink.BlinkSpeechGrammar.instance.weight_Getter_(this);

  @DomName('SpeechGrammar.weight')
  @DocsEditable()
  void set weight(num value) => _blink.BlinkSpeechGrammar.instance.weight_Setter_(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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('SpeechGrammarList')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#dfn-speechgrammarlist
@Experimental()
class SpeechGrammarList extends NativeFieldWrapperClass2 with ListMixin<SpeechGrammar>, ImmutableListMixin<SpeechGrammar> implements List<SpeechGrammar> {
  // To suppress missing implicit constructor warnings.
  factory SpeechGrammarList._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechGrammarList.SpeechGrammarList')
  @DocsEditable()
  factory SpeechGrammarList() {
    return _blink.BlinkSpeechGrammarList.instance.constructorCallback_0_();
  }

  @DomName('SpeechGrammarList.length')
  @DocsEditable()
  int get length => _blink.BlinkSpeechGrammarList.instance.length_Getter_(this);

  SpeechGrammar operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return _blink.BlinkSpeechGrammarList.instance.item_Callback_1_(this, index);
  }

  SpeechGrammar _nativeIndexedGetter(int index) => _blink.BlinkSpeechGrammarList.instance.item_Callback_1_(this, index);

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


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

  SpeechGrammar get first {
    if (this.length > 0) {
      return _nativeIndexedGetter(0);
    }
    throw new StateError("No elements");
  }

  SpeechGrammar get last {
    int len = this.length;
    if (len > 0) {
      return _nativeIndexedGetter(len - 1);
    }
    throw new StateError("No elements");
  }

  SpeechGrammar get single {
    int len = this.length;
    if (len == 1) {
      return _nativeIndexedGetter(0);
    }
    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.

  void addFromString(String string, [num weight]) {
    if (weight != null) {
      _blink.BlinkSpeechGrammarList.instance.addFromString_Callback_2_(this, string, weight);
      return;
    }
    _blink.BlinkSpeechGrammarList.instance.addFromString_Callback_1_(this, string);
    return;
  }

  void addFromUri(String src, [num weight]) {
    if (weight != null) {
      _blink.BlinkSpeechGrammarList.instance.addFromUri_Callback_2_(this, src, weight);
      return;
    }
    _blink.BlinkSpeechGrammarList.instance.addFromUri_Callback_1_(this, src);
    return;
  }

  @DomName('SpeechGrammarList.item')
  @DocsEditable()
  SpeechGrammar item(int index) => _blink.BlinkSpeechGrammarList.instance.item_Callback_1_(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.


@DocsEditable()
@DomName('SpeechRecognition')
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechreco-section
class SpeechRecognition extends EventTarget {
  // 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');

  @DomName('SpeechRecognition.SpeechRecognition')
  @DocsEditable()
  factory SpeechRecognition() {
    return _blink.BlinkSpeechRecognition.instance.constructorCallback_0_();
  }

  /// Checks if this type is supported on the current platform.
  static bool get supported => true;

  @DomName('SpeechRecognition.continuous')
  @DocsEditable()
  bool get continuous => _blink.BlinkSpeechRecognition.instance.continuous_Getter_(this);

  @DomName('SpeechRecognition.continuous')
  @DocsEditable()
  void set continuous(bool value) => _blink.BlinkSpeechRecognition.instance.continuous_Setter_(this, value);

  @DomName('SpeechRecognition.grammars')
  @DocsEditable()
  SpeechGrammarList get grammars => _blink.BlinkSpeechRecognition.instance.grammars_Getter_(this);

  @DomName('SpeechRecognition.grammars')
  @DocsEditable()
  void set grammars(SpeechGrammarList value) => _blink.BlinkSpeechRecognition.instance.grammars_Setter_(this, value);

  @DomName('SpeechRecognition.interimResults')
  @DocsEditable()
  bool get interimResults => _blink.BlinkSpeechRecognition.instance.interimResults_Getter_(this);

  @DomName('SpeechRecognition.interimResults')
  @DocsEditable()
  void set interimResults(bool value) => _blink.BlinkSpeechRecognition.instance.interimResults_Setter_(this, value);

  @DomName('SpeechRecognition.lang')
  @DocsEditable()
  String get lang => _blink.BlinkSpeechRecognition.instance.lang_Getter_(this);

  @DomName('SpeechRecognition.lang')
  @DocsEditable()
  void set lang(String value) => _blink.BlinkSpeechRecognition.instance.lang_Setter_(this, value);

  @DomName('SpeechRecognition.maxAlternatives')
  @DocsEditable()
  int get maxAlternatives => _blink.BlinkSpeechRecognition.instance.maxAlternatives_Getter_(this);

  @DomName('SpeechRecognition.maxAlternatives')
  @DocsEditable()
  void set maxAlternatives(int value) => _blink.BlinkSpeechRecognition.instance.maxAlternatives_Setter_(this, value);

  @DomName('SpeechRecognition.abort')
  @DocsEditable()
  void abort() => _blink.BlinkSpeechRecognition.instance.abort_Callback_0_(this);

  @DomName('SpeechRecognition.start')
  @DocsEditable()
  void start() => _blink.BlinkSpeechRecognition.instance.start_Callback_0_(this);

  @DomName('SpeechRecognition.stop')
  @DocsEditable()
  void stop() => _blink.BlinkSpeechRecognition.instance.stop_Callback_0_(this);

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

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


@DocsEditable()
@DomName('SpeechRecognitionAlternative')
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechrecognitionalternative
class SpeechRecognitionAlternative extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionAlternative._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechRecognitionAlternative.confidence')
  @DocsEditable()
  double get confidence => _blink.BlinkSpeechRecognitionAlternative.instance.confidence_Getter_(this);

  @DomName('SpeechRecognitionAlternative.transcript')
  @DocsEditable()
  String get transcript => _blink.BlinkSpeechRecognitionAlternative.instance.transcript_Getter_(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.


@DocsEditable()
@DomName('SpeechRecognitionError')
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechreco-error
class SpeechRecognitionError extends Event {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionError._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechRecognitionError.error')
  @DocsEditable()
  String get error => _blink.BlinkSpeechRecognitionError.instance.error_Getter_(this);

  @DomName('SpeechRecognitionError.message')
  @DocsEditable()
  String get message => _blink.BlinkSpeechRecognitionError.instance.message_Getter_(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.


@DocsEditable()
@DomName('SpeechRecognitionEvent')
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechreco-event
class SpeechRecognitionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechRecognitionEvent.emma')
  @DocsEditable()
  Document get emma => _blink.BlinkSpeechRecognitionEvent.instance.emma_Getter_(this);

  @DomName('SpeechRecognitionEvent.interpretation')
  @DocsEditable()
  Document get interpretation => _blink.BlinkSpeechRecognitionEvent.instance.interpretation_Getter_(this);

  @DomName('SpeechRecognitionEvent.resultIndex')
  @DocsEditable()
  int get resultIndex => _blink.BlinkSpeechRecognitionEvent.instance.resultIndex_Getter_(this);

  @DomName('SpeechRecognitionEvent.results')
  @DocsEditable()
  List<SpeechRecognitionResult> get results => _blink.BlinkSpeechRecognitionEvent.instance.results_Getter_(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.


@DocsEditable()
@DomName('SpeechRecognitionResult')
@SupportedBrowser(SupportedBrowser.CHROME, '25')
@Experimental()
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechrecognitionresult
class SpeechRecognitionResult extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionResult._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechRecognitionResult.isFinal')
  @DocsEditable()
  bool get isFinal => _blink.BlinkSpeechRecognitionResult.instance.isFinal_Getter_(this);

  @DomName('SpeechRecognitionResult.length')
  @DocsEditable()
  int get length => _blink.BlinkSpeechRecognitionResult.instance.length_Getter_(this);

  @DomName('SpeechRecognitionResult.item')
  @DocsEditable()
  SpeechRecognitionAlternative item(int index) => _blink.BlinkSpeechRecognitionResult.instance.item_Callback_1_(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.


@DocsEditable()
@DomName('SpeechSynthesis')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section
@Experimental()
class SpeechSynthesis extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory SpeechSynthesis._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechSynthesis.paused')
  @DocsEditable()
  bool get paused => _blink.BlinkSpeechSynthesis.instance.paused_Getter_(this);

  @DomName('SpeechSynthesis.pending')
  @DocsEditable()
  bool get pending => _blink.BlinkSpeechSynthesis.instance.pending_Getter_(this);

  @DomName('SpeechSynthesis.speaking')
  @DocsEditable()
  bool get speaking => _blink.BlinkSpeechSynthesis.instance.speaking_Getter_(this);

  @DomName('SpeechSynthesis.cancel')
  @DocsEditable()
  void cancel() => _blink.BlinkSpeechSynthesis.instance.cancel_Callback_0_(this);

  @DomName('SpeechSynthesis.getVoices')
  @DocsEditable()
  List<SpeechSynthesisVoice> getVoices() => _blink.BlinkSpeechSynthesis.instance.getVoices_Callback_0_(this);

  @DomName('SpeechSynthesis.pause')
  @DocsEditable()
  void pause() => _blink.BlinkSpeechSynthesis.instance.pause_Callback_0_(this);

  @DomName('SpeechSynthesis.resume')
  @DocsEditable()
  void resume() => _blink.BlinkSpeechSynthesis.instance.resume_Callback_0_(this);

  @DomName('SpeechSynthesis.speak')
  @DocsEditable()
  void speak(SpeechSynthesisUtterance utterance) => _blink.BlinkSpeechSynthesis.instance.speak_Callback_1_(this, 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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('SpeechSynthesisEvent')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section
@Experimental()
class SpeechSynthesisEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory SpeechSynthesisEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechSynthesisEvent.charIndex')
  @DocsEditable()
  int get charIndex => _blink.BlinkSpeechSynthesisEvent.instance.charIndex_Getter_(this);

  @DomName('SpeechSynthesisEvent.elapsedTime')
  @DocsEditable()
  double get elapsedTime => _blink.BlinkSpeechSynthesisEvent.instance.elapsedTime_Getter_(this);

  @DomName('SpeechSynthesisEvent.name')
  @DocsEditable()
  String get name => _blink.BlinkSpeechSynthesisEvent.instance.name_Getter_(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.


@DocsEditable()
@DomName('SpeechSynthesisUtterance')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section
@Experimental()
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]) {
    return _blink.BlinkSpeechSynthesisUtterance.instance.constructorCallback_1_(text);
  }

  @DomName('SpeechSynthesisUtterance.lang')
  @DocsEditable()
  String get lang => _blink.BlinkSpeechSynthesisUtterance.instance.lang_Getter_(this);

  @DomName('SpeechSynthesisUtterance.lang')
  @DocsEditable()
  void set lang(String value) => _blink.BlinkSpeechSynthesisUtterance.instance.lang_Setter_(this, value);

  @DomName('SpeechSynthesisUtterance.pitch')
  @DocsEditable()
  num get pitch => _blink.BlinkSpeechSynthesisUtterance.instance.pitch_Getter_(this);

  @DomName('SpeechSynthesisUtterance.pitch')
  @DocsEditable()
  void set pitch(num value) => _blink.BlinkSpeechSynthesisUtterance.instance.pitch_Setter_(this, value);

  @DomName('SpeechSynthesisUtterance.rate')
  @DocsEditable()
  num get rate => _blink.BlinkSpeechSynthesisUtterance.instance.rate_Getter_(this);

  @DomName('SpeechSynthesisUtterance.rate')
  @DocsEditable()
  void set rate(num value) => _blink.BlinkSpeechSynthesisUtterance.instance.rate_Setter_(this, value);

  @DomName('SpeechSynthesisUtterance.text')
  @DocsEditable()
  String get text => _blink.BlinkSpeechSynthesisUtterance.instance.text_Getter_(this);

  @DomName('SpeechSynthesisUtterance.text')
  @DocsEditable()
  void set text(String value) => _blink.BlinkSpeechSynthesisUtterance.instance.text_Setter_(this, value);

  @DomName('SpeechSynthesisUtterance.voice')
  @DocsEditable()
  SpeechSynthesisVoice get voice => _blink.BlinkSpeechSynthesisUtterance.instance.voice_Getter_(this);

  @DomName('SpeechSynthesisUtterance.voice')
  @DocsEditable()
  void set voice(SpeechSynthesisVoice value) => _blink.BlinkSpeechSynthesisUtterance.instance.voice_Setter_(this, value);

  @DomName('SpeechSynthesisUtterance.volume')
  @DocsEditable()
  num get volume => _blink.BlinkSpeechSynthesisUtterance.instance.volume_Getter_(this);

  @DomName('SpeechSynthesisUtterance.volume')
  @DocsEditable()
  void set volume(num value) => _blink.BlinkSpeechSynthesisUtterance.instance.volume_Setter_(this, value);

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

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('SpeechSynthesisVoice')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section
@Experimental()
class SpeechSynthesisVoice extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory SpeechSynthesisVoice._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechSynthesisVoice.default')
  @DocsEditable()
  bool get defaultValue => _blink.BlinkSpeechSynthesisVoice.instance.default_Getter_(this);

  @DomName('SpeechSynthesisVoice.lang')
  @DocsEditable()
  String get lang => _blink.BlinkSpeechSynthesisVoice.instance.lang_Getter_(this);

  @DomName('SpeechSynthesisVoice.localService')
  @DocsEditable()
  bool get localService => _blink.BlinkSpeechSynthesisVoice.instance.localService_Getter_(this);

  @DomName('SpeechSynthesisVoice.name')
  @DocsEditable()
  String get name => _blink.BlinkSpeechSynthesisVoice.instance.name_Getter_(this);

  @DomName('SpeechSynthesisVoice.voiceURI')
  @DocsEditable()
  String get voiceUri => _blink.BlinkSpeechSynthesisVoice.instance.voiceURI_Getter_(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.


/**
 * The type used by the
 * [Window.localStorage] and [Window.sessionStorage] properties.
 * Storage is implemented as a Map&lt;String, String>.
 *
 * To store and get values, use Dart's built-in map syntax:
 *
 *     window.localStorage['key1'] = 'val1';
 *     window.localStorage['key2'] = 'val2';
 *     window.localStorage['key3'] = 'val3';
 *     assert(window.localStorage['key3'] == 'val3');
 *
 * You can use [Map](http://api.dartlang.org/dart_core/Map.html) APIs
 * such as containsValue(), clear(), and length:
 *
 *     assert(window.localStorage.containsValue('does not exist') == false);
 *     window.localStorage.clear();
 *     assert(window.localStorage.length == 0);
 *
 * For more examples of using this API, see
 * [localstorage_test.dart](http://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/tests/html/localstorage_test.dart).
 * For details on using the Map API, see the
 * [Maps](http://www.dartlang.org/docs/library-tour/#maps-aka-dictionaries-or-hashes)
 * section of the library tour.
 */
@DomName('Storage')
@Unstable()
class Storage extends NativeFieldWrapperClass2
    implements Map<String, String> {

  void addAll(Map<String, String> other) {
    other.forEach((k, v) { this[k] = v; });
  }

  // TODO(nweiz): update this when maps support lazy iteration
  bool containsValue(String value) => values.any((e) => e == value);

  bool containsKey(String key) => _getItem(key) != null;

  String operator [](String key) => _getItem(key);

  void operator []=(String key, String value) { _setItem(key, value); }

  String putIfAbsent(String key, String ifAbsent()) {
    if (!containsKey(key)) this[key] = ifAbsent();
    return this[key];
  }

  String remove(String key) {
    final value = this[key];
    _removeItem(key);
    return value;
  }

  void clear() => _clear();

  void forEach(void f(String key, String value)) {
    for (var i = 0; true; i++) {
      final key = _key(i);
      if (key == null) return;

      f(key, this[key]);
    }
  }

  Iterable<String> get keys {
    final keys = [];
    forEach((k, v) => keys.add(k));
    return keys;
  }

  Iterable<String> get values {
    final values = [];
    forEach((k, v) => values.add(v));
    return values;
  }

  int get length => _length;

  bool get isEmpty => _key(0) == null;

  bool get isNotEmpty => !isEmpty;
  // To suppress missing implicit constructor warnings.
  factory Storage._() { throw new UnsupportedError("Not supported"); }

  @DomName('Storage.length')
  @DocsEditable()
  int get _length => _blink.BlinkStorage.instance.length_Getter_(this);

  bool __delete__(index_OR_name) {
    if ((index_OR_name is int || index_OR_name == null)) {
      return _blink.BlinkStorage.instance.$__delete___Callback_1_(this, index_OR_name);
    }
    if ((index_OR_name is String || index_OR_name == null)) {
      return _blink.BlinkStorage.instance.$__delete___Callback_1_(this, index_OR_name);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  String __getter__(index_OR_name) {
    if ((index_OR_name is int || index_OR_name == null)) {
      return _blink.BlinkStorage.instance.$__getter___Callback_1_(this, index_OR_name);
    }
    if ((index_OR_name is String || index_OR_name == null)) {
      return _blink.BlinkStorage.instance.$__getter___Callback_1_(this, index_OR_name);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  void __setter__(index_OR_name, String value) {
    if ((value is String || value == null) && (index_OR_name is int || index_OR_name == null)) {
      _blink.BlinkStorage.instance.$__setter___Callback_2_(this, index_OR_name, value);
      return;
    }
    if ((value is String || value == null) && (index_OR_name is String || index_OR_name == null)) {
      _blink.BlinkStorage.instance.$__setter___Callback_2_(this, index_OR_name, value);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('Storage.clear')
  @DocsEditable()
  void _clear() => _blink.BlinkStorage.instance.clear_Callback_0_(this);

  @DomName('Storage.getItem')
  @DocsEditable()
  String _getItem(String key) => _blink.BlinkStorage.instance.getItem_Callback_1_(this, key);

  @DomName('Storage.key')
  @DocsEditable()
  String _key(int index) => _blink.BlinkStorage.instance.key_Callback_1_(this, index);

  @DomName('Storage.removeItem')
  @DocsEditable()
  void _removeItem(String key) => _blink.BlinkStorage.instance.removeItem_Callback_1_(this, key);

  @DomName('Storage.setItem')
  @DocsEditable()
  void _setItem(String key, String data) => _blink.BlinkStorage.instance.setItem_Callback_2_(this, key, 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.

// WARNING: Do not edit - generated code.


@DomName('StorageErrorCallback')
// http://www.w3.org/TR/quota-api/#storageerrorcallback-callback
@Experimental()
typedef void StorageErrorCallback(DomError error);
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('StorageEvent')
@Unstable()
class StorageEvent extends Event {
  factory StorageEvent(String type,
    {bool canBubble: false, bool cancelable: false, String key, String oldValue,
    String newValue, String url, Storage storageArea}) {

    var e = document._createEvent("StorageEvent");
    e._initStorageEvent(type, canBubble, cancelable, key, oldValue,
        newValue, url, storageArea);
    return e;
  }
  // To suppress missing implicit constructor warnings.
  factory StorageEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('StorageEvent.key')
  @DocsEditable()
  String get key => _blink.BlinkStorageEvent.instance.key_Getter_(this);

  @DomName('StorageEvent.newValue')
  @DocsEditable()
  String get newValue => _blink.BlinkStorageEvent.instance.newValue_Getter_(this);

  @DomName('StorageEvent.oldValue')
  @DocsEditable()
  String get oldValue => _blink.BlinkStorageEvent.instance.oldValue_Getter_(this);

  @DomName('StorageEvent.storageArea')
  @DocsEditable()
  Storage get storageArea => _blink.BlinkStorageEvent.instance.storageArea_Getter_(this);

  @DomName('StorageEvent.url')
  @DocsEditable()
  String get url => _blink.BlinkStorageEvent.instance.url_Getter_(this);

  @DomName('StorageEvent.initStorageEvent')
  @DocsEditable()
  void _initStorageEvent(String typeArg, bool canBubbleArg, bool cancelableArg, String keyArg, String oldValueArg, String newValueArg, String urlArg, Storage storageAreaArg) => _blink.BlinkStorageEvent.instance.initStorageEvent_Callback_8_(this, typeArg, canBubbleArg, cancelableArg, keyArg, oldValueArg, newValueArg, urlArg, storageAreaArg);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


@DocsEditable()
@DomName('StorageInfo')
// http://www.w3.org/TR/file-system-api/
@Experimental()
class StorageInfo extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory StorageInfo._() { throw new UnsupportedError("Not supported"); }

  @DomName('StorageInfo.quota')
  @DocsEditable()
  @Experimental() // untriaged
  int get quota => _blink.BlinkStorageInfo.instance.quota_Getter_(this);

  @DomName('StorageInfo.usage')
  @DocsEditable()
  @Experimental() // untriaged
  int get usage => _blink.BlinkStorageInfo.instance.usage_Getter_(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.


@DocsEditable()
@DomName('StorageQuota')
// http://www.w3.org/TR/quota-api/#idl-def-StorageQuota
@Experimental()
class StorageQuota extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory StorageQuota._() { throw new UnsupportedError("Not supported"); }

  @DomName('StorageQuota.supportedTypes')
  @DocsEditable()
  @Experimental() // untriaged
  List<String> get supportedTypes => _blink.BlinkStorageQuota.instance.supportedTypes_Getter_(this);

  @DomName('StorageQuota.queryInfo')
  @DocsEditable()
  @Experimental() // untriaged
  Future queryInfo(String type) => _blink.BlinkStorageQuota.instance.queryInfo_Callback_1_(this, type);

  @DomName('StorageQuota.requestPersistentQuota')
  @DocsEditable()
  @Experimental() // untriaged
  Future requestPersistentQuota(int newQuota) => _blink.BlinkStorageQuota.instance.requestPersistentQuota_Callback_1_(this, newQuota);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.

// WARNING: Do not edit - generated code.


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

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

  @DomName('HTMLStyleElement.disabled')
  @DocsEditable()
  bool get disabled => _blink.BlinkHTMLStyleElement.instance.disabled_Getter_(this);

  @DomName('HTMLStyleElement.disabled')
  @DocsEditable()
  void set disabled(bool value) => _blink.BlinkHTMLStyleElement.instance.disabled_Setter_(this, value);

  @DomName('HTMLStyleElement.media')
  @DocsEditable()
  String get media => _blink.BlinkHTMLStyleElement.instance.media_Getter_(this);

  @DomName('HTMLStyleElement.media')
  @DocsEditable()
  void set media(String value) => _blink.BlinkHTMLStyleElement.instance.media_Setter_(this, value);

  @DomName('HTMLStyleElement.sheet')
  @DocsEditable()
  StyleSheet get sheet => _blink.BlinkHTMLStyleElement.instance.sheet_Getter_(this);

  @DomName('HTMLStyleElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLStyleElement.instance.type_Getter_(this);

  @DomName('HTMLStyleElement.type')
  @DocsEditable()
  void set type(String value) => _blink.BlinkHTMLStyleElement.instance.type_Setter_(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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('StyleMedia')
// http://developer.apple.com/library/safari/#documentation/SafariDOMAdditions/Reference/StyleMedia/StyleMedia/StyleMedia.html
@Experimental() // nonstandard
class StyleMedia extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory StyleMedia._() { throw new UnsupportedError("Not supported"); }

  @DomName('StyleMedia.type')
  @DocsEditable()
  String get type => _blink.BlinkStyleMedia.instance.type_Getter_(this);

  @DomName('StyleMedia.matchMedium')
  @DocsEditable()
  bool matchMedium(String mediaquery) => _blink.BlinkStyleMedia.instance.matchMedium_Callback_1_(this, mediaquery);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

  @DomName('StyleSheet.disabled')
  @DocsEditable()
  bool get disabled => _blink.BlinkStyleSheet.instance.disabled_Getter_(this);

  @DomName('StyleSheet.disabled')
  @DocsEditable()
  void set disabled(bool value) => _blink.BlinkStyleSheet.instance.disabled_Setter_(this, value);

  @DomName('StyleSheet.href')
  @DocsEditable()
  String get href => _blink.BlinkStyleSheet.instance.href_Getter_(this);

  @DomName('StyleSheet.media')
  @DocsEditable()
  MediaList get media => _blink.BlinkStyleSheet.instance.media_Getter_(this);

  @DomName('StyleSheet.ownerNode')
  @DocsEditable()
  Node get ownerNode => _blink.BlinkStyleSheet.instance.ownerNode_Getter_(this);

  @DomName('StyleSheet.parentStyleSheet')
  @DocsEditable()
  StyleSheet get parentStyleSheet => _blink.BlinkStyleSheet.instance.parentStyleSheet_Getter_(this);

  @DomName('StyleSheet.title')
  @DocsEditable()
  String get title => _blink.BlinkStyleSheet.instance.title_Getter_(this);

  @DomName('StyleSheet.type')
  @DocsEditable()
  String get type => _blink.BlinkStyleSheet.instance.type_Getter_(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.


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

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

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

// WARNING: Do not edit - generated code.


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

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

  @DomName('HTMLTableCellElement.cellIndex')
  @DocsEditable()
  int get cellIndex => _blink.BlinkHTMLTableCellElement.instance.cellIndex_Getter_(this);

  @DomName('HTMLTableCellElement.colSpan')
  @DocsEditable()
  int get colSpan => _blink.BlinkHTMLTableCellElement.instance.colSpan_Getter_(this);

  @DomName('HTMLTableCellElement.colSpan')
  @DocsEditable()
  void set colSpan(int value) => _blink.BlinkHTMLTableCellElement.instance.colSpan_Setter_(this, value);

  @DomName('HTMLTableCellElement.headers')
  @DocsEditable()
  String get headers => _blink.BlinkHTMLTableCellElement.instance.headers_Getter_(this);

  @DomName('HTMLTableCellElement.headers')
  @DocsEditable()
  void set headers(String value) => _blink.BlinkHTMLTableCellElement.instance.headers_Setter_(this, value);

  @DomName('HTMLTableCellElement.rowSpan')
  @DocsEditable()
  int get rowSpan => _blink.BlinkHTMLTableCellElement.instance.rowSpan_Getter_(this);

  @DomName('HTMLTableCellElement.rowSpan')
  @DocsEditable()
  void set rowSpan(int value) => _blink.BlinkHTMLTableCellElement.instance.rowSpan_Setter_(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.

// WARNING: Do not edit - generated code.


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

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

  @DomName('HTMLTableColElement.span')
  @DocsEditable()
  int get span => _blink.BlinkHTMLTableColElement.instance.span_Getter_(this);

  @DomName('HTMLTableColElement.span')
  @DocsEditable()
  void set span(int value) => _blink.BlinkHTMLTableColElement.instance.span_Setter_(this, value);

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


@DocsEditable()
@DomName('HTMLTableElement')
class TableElement extends HtmlElement {

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


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

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

  @DomName('HTMLTableElement.caption')
  @DocsEditable()
  TableCaptionElement get caption => _blink.BlinkHTMLTableElement.instance.caption_Getter_(this);

  @DomName('HTMLTableElement.caption')
  @DocsEditable()
  void set caption(TableCaptionElement value) => _blink.BlinkHTMLTableElement.instance.caption_Setter_(this, value);

  @DomName('HTMLTableElement.rows')
  @DocsEditable()
  List<Node> get _rows => _blink.BlinkHTMLTableElement.instance.rows_Getter_(this);

  @DomName('HTMLTableElement.tBodies')
  @DocsEditable()
  List<Node> get _tBodies => _blink.BlinkHTMLTableElement.instance.tBodies_Getter_(this);

  @DomName('HTMLTableElement.tFoot')
  @DocsEditable()
  TableSectionElement get tFoot => _blink.BlinkHTMLTableElement.instance.tFoot_Getter_(this);

  @DomName('HTMLTableElement.tFoot')
  @DocsEditable()
  void set tFoot(TableSectionElement value) => _blink.BlinkHTMLTableElement.instance.tFoot_Setter_(this, value);

  @DomName('HTMLTableElement.tHead')
  @DocsEditable()
  TableSectionElement get tHead => _blink.BlinkHTMLTableElement.instance.tHead_Getter_(this);

  @DomName('HTMLTableElement.tHead')
  @DocsEditable()
  void set tHead(TableSectionElement value) => _blink.BlinkHTMLTableElement.instance.tHead_Setter_(this, value);

  @DomName('HTMLTableElement.createCaption')
  @DocsEditable()
  HtmlElement _createCaption() => _blink.BlinkHTMLTableElement.instance.createCaption_Callback_0_(this);

  @DomName('HTMLTableElement.createTBody')
  @DocsEditable()
  HtmlElement _createTBody() => _blink.BlinkHTMLTableElement.instance.createTBody_Callback_0_(this);

  @DomName('HTMLTableElement.createTFoot')
  @DocsEditable()
  HtmlElement _createTFoot() => _blink.BlinkHTMLTableElement.instance.createTFoot_Callback_0_(this);

  @DomName('HTMLTableElement.createTHead')
  @DocsEditable()
  HtmlElement _createTHead() => _blink.BlinkHTMLTableElement.instance.createTHead_Callback_0_(this);

  @DomName('HTMLTableElement.deleteCaption')
  @DocsEditable()
  void deleteCaption() => _blink.BlinkHTMLTableElement.instance.deleteCaption_Callback_0_(this);

  @DomName('HTMLTableElement.deleteRow')
  @DocsEditable()
  void deleteRow(int index) => _blink.BlinkHTMLTableElement.instance.deleteRow_Callback_1_(this, index);

  @DomName('HTMLTableElement.deleteTFoot')
  @DocsEditable()
  void deleteTFoot() => _blink.BlinkHTMLTableElement.instance.deleteTFoot_Callback_0_(this);

  @DomName('HTMLTableElement.deleteTHead')
  @DocsEditable()
  void deleteTHead() => _blink.BlinkHTMLTableElement.instance.deleteTHead_Callback_0_(this);

  HtmlElement _insertRow([int index]) {
    if (index != null) {
      return _blink.BlinkHTMLTableElement.instance.insertRow_Callback_1_(this, index);
    }
    return _blink.BlinkHTMLTableElement.instance.insertRow_Callback_0_(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('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);


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

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

  @DomName('HTMLTableRowElement.cells')
  @DocsEditable()
  List<Node> get _cells => _blink.BlinkHTMLTableRowElement.instance.cells_Getter_(this);

  @DomName('HTMLTableRowElement.rowIndex')
  @DocsEditable()
  int get rowIndex => _blink.BlinkHTMLTableRowElement.instance.rowIndex_Getter_(this);

  @DomName('HTMLTableRowElement.sectionRowIndex')
  @DocsEditable()
  int get sectionRowIndex => _blink.BlinkHTMLTableRowElement.instance.sectionRowIndex_Getter_(this);

  @DomName('HTMLTableRowElement.deleteCell')
  @DocsEditable()
  void deleteCell(int index) => _blink.BlinkHTMLTableRowElement.instance.deleteCell_Callback_1_(this, index);

  HtmlElement _insertCell([int index]) {
    if (index != null) {
      return _blink.BlinkHTMLTableRowElement.instance.insertCell_Callback_1_(this, index);
    }
    return _blink.BlinkHTMLTableRowElement.instance.insertCell_Callback_0_(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('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);


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

  @DomName('HTMLTableSectionElement.rows')
  @DocsEditable()
  List<Node> get _rows => _blink.BlinkHTMLTableSectionElement.instance.rows_Getter_(this);

  @DomName('HTMLTableSectionElement.deleteRow')
  @DocsEditable()
  void deleteRow(int index) => _blink.BlinkHTMLTableSectionElement.instance.deleteRow_Callback_1_(this, index);

  HtmlElement _insertRow([int index]) {
    if (index != null) {
      return _blink.BlinkHTMLTableSectionElement.instance.insertRow_Callback_1_(this, index);
    }
    return _blink.BlinkHTMLTableSectionElement.instance.insertRow_Callback_0_(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.

// WARNING: Do not edit - generated code.


@Experimental()
@DomName('HTMLTemplateElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#template-element
class TemplateElement extends HtmlElement {
  // 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 => true;

  @DomName('HTMLTemplateElement.content')
  @DocsEditable()
  DocumentFragment get content => _blink.BlinkHTMLTemplateElement.instance.content_Getter_(this);


  /**
   * An override to place the contents into content rather than as child nodes.
   *
   * See also:
   *
   * * <https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#innerhtml-on-templates>
   */
  void setInnerHtml(String html,
    {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    text = null;
    var fragment = createFragment(
        html, validator: validator, treeSanitizer: treeSanitizer);

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

// WARNING: Do not edit - generated code.


@DomName('Text')
class Text extends CharacterData {
  factory Text(String data) => document._createTextNode(data);
  // To suppress missing implicit constructor warnings.
  factory Text._() { throw new UnsupportedError("Not supported"); }

  @DomName('Text.wholeText')
  @DocsEditable()
  String get wholeText => _blink.BlinkText.instance.wholeText_Getter_(this);

  @DomName('Text.getDestinationInsertionPoints')
  @DocsEditable()
  @Experimental() // untriaged
  List<Node> getDestinationInsertionPoints() => _blink.BlinkText.instance.getDestinationInsertionPoints_Callback_0_(this);

  @DomName('Text.splitText')
  @DocsEditable()
  Text splitText(int offset) => _blink.BlinkText.instance.splitText_Callback_1_(this, offset);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

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

  @DomName('HTMLTextAreaElement.autofocus')
  @DocsEditable()
  bool get autofocus => _blink.BlinkHTMLTextAreaElement.instance.autofocus_Getter_(this);

  @DomName('HTMLTextAreaElement.autofocus')
  @DocsEditable()
  void set autofocus(bool value) => _blink.BlinkHTMLTextAreaElement.instance.autofocus_Setter_(this, value);

  @DomName('HTMLTextAreaElement.cols')
  @DocsEditable()
  int get cols => _blink.BlinkHTMLTextAreaElement.instance.cols_Getter_(this);

  @DomName('HTMLTextAreaElement.cols')
  @DocsEditable()
  void set cols(int value) => _blink.BlinkHTMLTextAreaElement.instance.cols_Setter_(this, value);

  @DomName('HTMLTextAreaElement.defaultValue')
  @DocsEditable()
  String get defaultValue => _blink.BlinkHTMLTextAreaElement.instance.defaultValue_Getter_(this);

  @DomName('HTMLTextAreaElement.defaultValue')
  @DocsEditable()
  void set defaultValue(String value) => _blink.BlinkHTMLTextAreaElement.instance.defaultValue_Setter_(this, value);

  @DomName('HTMLTextAreaElement.dirName')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#dom-textarea-dirname
  @Experimental()
  String get dirName => _blink.BlinkHTMLTextAreaElement.instance.dirName_Getter_(this);

  @DomName('HTMLTextAreaElement.dirName')
  @DocsEditable()
  // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#dom-textarea-dirname
  @Experimental()
  void set dirName(String value) => _blink.BlinkHTMLTextAreaElement.instance.dirName_Setter_(this, value);

  @DomName('HTMLTextAreaElement.disabled')
  @DocsEditable()
  bool get disabled => _blink.BlinkHTMLTextAreaElement.instance.disabled_Getter_(this);

  @DomName('HTMLTextAreaElement.disabled')
  @DocsEditable()
  void set disabled(bool value) => _blink.BlinkHTMLTextAreaElement.instance.disabled_Setter_(this, value);

  @DomName('HTMLTextAreaElement.form')
  @DocsEditable()
  FormElement get form => _blink.BlinkHTMLTextAreaElement.instance.form_Getter_(this);

  @DomName('HTMLTextAreaElement.inputMode')
  @DocsEditable()
  @Experimental() // untriaged
  String get inputMode => _blink.BlinkHTMLTextAreaElement.instance.inputMode_Getter_(this);

  @DomName('HTMLTextAreaElement.inputMode')
  @DocsEditable()
  @Experimental() // untriaged
  void set inputMode(String value) => _blink.BlinkHTMLTextAreaElement.instance.inputMode_Setter_(this, value);

  @DomName('HTMLTextAreaElement.labels')
  @DocsEditable()
  @Unstable()
  List<Node> get labels => _blink.BlinkHTMLTextAreaElement.instance.labels_Getter_(this);

  @DomName('HTMLTextAreaElement.maxLength')
  @DocsEditable()
  int get maxLength => _blink.BlinkHTMLTextAreaElement.instance.maxLength_Getter_(this);

  @DomName('HTMLTextAreaElement.maxLength')
  @DocsEditable()
  void set maxLength(int value) => _blink.BlinkHTMLTextAreaElement.instance.maxLength_Setter_(this, value);

  @DomName('HTMLTextAreaElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLTextAreaElement.instance.name_Getter_(this);

  @DomName('HTMLTextAreaElement.name')
  @DocsEditable()
  void set name(String value) => _blink.BlinkHTMLTextAreaElement.instance.name_Setter_(this, value);

  @DomName('HTMLTextAreaElement.placeholder')
  @DocsEditable()
  String get placeholder => _blink.BlinkHTMLTextAreaElement.instance.placeholder_Getter_(this);

  @DomName('HTMLTextAreaElement.placeholder')
  @DocsEditable()
  void set placeholder(String value) => _blink.BlinkHTMLTextAreaElement.instance.placeholder_Setter_(this, value);

  @DomName('HTMLTextAreaElement.readOnly')
  @DocsEditable()
  bool get readOnly => _blink.BlinkHTMLTextAreaElement.instance.readOnly_Getter_(this);

  @DomName('HTMLTextAreaElement.readOnly')
  @DocsEditable()
  void set readOnly(bool value) => _blink.BlinkHTMLTextAreaElement.instance.readOnly_Setter_(this, value);

  @DomName('HTMLTextAreaElement.required')
  @DocsEditable()
  bool get required => _blink.BlinkHTMLTextAreaElement.instance.required_Getter_(this);

  @DomName('HTMLTextAreaElement.required')
  @DocsEditable()
  void set required(bool value) => _blink.BlinkHTMLTextAreaElement.instance.required_Setter_(this, value);

  @DomName('HTMLTextAreaElement.rows')
  @DocsEditable()
  int get rows => _blink.BlinkHTMLTextAreaElement.instance.rows_Getter_(this);

  @DomName('HTMLTextAreaElement.rows')
  @DocsEditable()
  void set rows(int value) => _blink.BlinkHTMLTextAreaElement.instance.rows_Setter_(this, value);

  @DomName('HTMLTextAreaElement.selectionDirection')
  @DocsEditable()
  String get selectionDirection => _blink.BlinkHTMLTextAreaElement.instance.selectionDirection_Getter_(this);

  @DomName('HTMLTextAreaElement.selectionDirection')
  @DocsEditable()
  void set selectionDirection(String value) => _blink.BlinkHTMLTextAreaElement.instance.selectionDirection_Setter_(this, value);

  @DomName('HTMLTextAreaElement.selectionEnd')
  @DocsEditable()
  int get selectionEnd => _blink.BlinkHTMLTextAreaElement.instance.selectionEnd_Getter_(this);

  @DomName('HTMLTextAreaElement.selectionEnd')
  @DocsEditable()
  void set selectionEnd(int value) => _blink.BlinkHTMLTextAreaElement.instance.selectionEnd_Setter_(this, value);

  @DomName('HTMLTextAreaElement.selectionStart')
  @DocsEditable()
  int get selectionStart => _blink.BlinkHTMLTextAreaElement.instance.selectionStart_Getter_(this);

  @DomName('HTMLTextAreaElement.selectionStart')
  @DocsEditable()
  void set selectionStart(int value) => _blink.BlinkHTMLTextAreaElement.instance.selectionStart_Setter_(this, value);

  @DomName('HTMLTextAreaElement.textLength')
  @DocsEditable()
  int get textLength => _blink.BlinkHTMLTextAreaElement.instance.textLength_Getter_(this);

  @DomName('HTMLTextAreaElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLTextAreaElement.instance.type_Getter_(this);

  @DomName('HTMLTextAreaElement.validationMessage')
  @DocsEditable()
  String get validationMessage => _blink.BlinkHTMLTextAreaElement.instance.validationMessage_Getter_(this);

  @DomName('HTMLTextAreaElement.validity')
  @DocsEditable()
  ValidityState get validity => _blink.BlinkHTMLTextAreaElement.instance.validity_Getter_(this);

  @DomName('HTMLTextAreaElement.value')
  @DocsEditable()
  String get value => _blink.BlinkHTMLTextAreaElement.instance.value_Getter_(this);

  @DomName('HTMLTextAreaElement.value')
  @DocsEditable()
  void set value(String value) => _blink.BlinkHTMLTextAreaElement.instance.value_Setter_(this, value);

  @DomName('HTMLTextAreaElement.willValidate')
  @DocsEditable()
  bool get willValidate => _blink.BlinkHTMLTextAreaElement.instance.willValidate_Getter_(this);

  @DomName('HTMLTextAreaElement.wrap')
  @DocsEditable()
  String get wrap => _blink.BlinkHTMLTextAreaElement.instance.wrap_Getter_(this);

  @DomName('HTMLTextAreaElement.wrap')
  @DocsEditable()
  void set wrap(String value) => _blink.BlinkHTMLTextAreaElement.instance.wrap_Setter_(this, value);

  @DomName('HTMLTextAreaElement.checkValidity')
  @DocsEditable()
  bool checkValidity() => _blink.BlinkHTMLTextAreaElement.instance.checkValidity_Callback_0_(this);

  @DomName('HTMLTextAreaElement.select')
  @DocsEditable()
  void select() => _blink.BlinkHTMLTextAreaElement.instance.select_Callback_0_(this);

  @DomName('HTMLTextAreaElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) => _blink.BlinkHTMLTextAreaElement.instance.setCustomValidity_Callback_1_(this, error);

  void setRangeText(String replacement, {int start, int end, String selectionMode}) {
    if ((replacement is String || replacement == null) && start == null && end == null && selectionMode == null) {
      _blink.BlinkHTMLTextAreaElement.instance.setRangeText_Callback_1_(this, replacement);
      return;
    }
    if ((selectionMode is String || selectionMode == null) && (end is int || end == null) && (start is int || start == null) && (replacement is String || replacement == null)) {
      _blink.BlinkHTMLTextAreaElement.instance.setRangeText_Callback_4_(this, replacement, start, end, selectionMode);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  void setSelectionRange(int start, int end, [String direction]) {
    if (direction != null) {
      _blink.BlinkHTMLTextAreaElement.instance.setSelectionRange_Callback_3_(this, start, end, direction);
      return;
    }
    _blink.BlinkHTMLTextAreaElement.instance.setSelectionRange_Callback_2_(this, start, end);
    return;
  }

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

// WARNING: Do not edit - generated code.


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

  @DomName('TextEvent.data')
  @DocsEditable()
  String get data => _blink.BlinkTextEvent.instance.data_Getter_(this);

  @DomName('TextEvent.initTextEvent')
  @DocsEditable()
  void _initTextEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Window viewArg, String dataArg) => _blink.BlinkTextEvent.instance.initTextEvent_Callback_5_(this, typeArg, canBubbleArg, cancelableArg, viewArg, dataArg);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

  @DomName('TextMetrics.actualBoundingBoxAscent')
  @DocsEditable()
  @Experimental() // untriaged
  double get actualBoundingBoxAscent => _blink.BlinkTextMetrics.instance.actualBoundingBoxAscent_Getter_(this);

  @DomName('TextMetrics.actualBoundingBoxDescent')
  @DocsEditable()
  @Experimental() // untriaged
  double get actualBoundingBoxDescent => _blink.BlinkTextMetrics.instance.actualBoundingBoxDescent_Getter_(this);

  @DomName('TextMetrics.actualBoundingBoxLeft')
  @DocsEditable()
  @Experimental() // untriaged
  double get actualBoundingBoxLeft => _blink.BlinkTextMetrics.instance.actualBoundingBoxLeft_Getter_(this);

  @DomName('TextMetrics.actualBoundingBoxRight')
  @DocsEditable()
  @Experimental() // untriaged
  double get actualBoundingBoxRight => _blink.BlinkTextMetrics.instance.actualBoundingBoxRight_Getter_(this);

  @DomName('TextMetrics.alphabeticBaseline')
  @DocsEditable()
  @Experimental() // untriaged
  double get alphabeticBaseline => _blink.BlinkTextMetrics.instance.alphabeticBaseline_Getter_(this);

  @DomName('TextMetrics.emHeightAscent')
  @DocsEditable()
  @Experimental() // untriaged
  double get emHeightAscent => _blink.BlinkTextMetrics.instance.emHeightAscent_Getter_(this);

  @DomName('TextMetrics.emHeightDescent')
  @DocsEditable()
  @Experimental() // untriaged
  double get emHeightDescent => _blink.BlinkTextMetrics.instance.emHeightDescent_Getter_(this);

  @DomName('TextMetrics.fontBoundingBoxAscent')
  @DocsEditable()
  @Experimental() // untriaged
  double get fontBoundingBoxAscent => _blink.BlinkTextMetrics.instance.fontBoundingBoxAscent_Getter_(this);

  @DomName('TextMetrics.fontBoundingBoxDescent')
  @DocsEditable()
  @Experimental() // untriaged
  double get fontBoundingBoxDescent => _blink.BlinkTextMetrics.instance.fontBoundingBoxDescent_Getter_(this);

  @DomName('TextMetrics.hangingBaseline')
  @DocsEditable()
  @Experimental() // untriaged
  double get hangingBaseline => _blink.BlinkTextMetrics.instance.hangingBaseline_Getter_(this);

  @DomName('TextMetrics.ideographicBaseline')
  @DocsEditable()
  @Experimental() // untriaged
  double get ideographicBaseline => _blink.BlinkTextMetrics.instance.ideographicBaseline_Getter_(this);

  @DomName('TextMetrics.width')
  @DocsEditable()
  double get width => _blink.BlinkTextMetrics.instance.width_Getter_(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.


@DocsEditable()
@DomName('TextTrack')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#texttrack
@Experimental()
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()
  TextTrackCueList get activeCues => _blink.BlinkTextTrack.instance.activeCues_Getter_(this);

  @DomName('TextTrack.cues')
  @DocsEditable()
  TextTrackCueList get cues => _blink.BlinkTextTrack.instance.cues_Getter_(this);

  @DomName('TextTrack.id')
  @DocsEditable()
  @Experimental() // untriaged
  String get id => _blink.BlinkTextTrack.instance.id_Getter_(this);

  @DomName('TextTrack.kind')
  @DocsEditable()
  String get kind => _blink.BlinkTextTrack.instance.kind_Getter_(this);

  @DomName('TextTrack.label')
  @DocsEditable()
  String get label => _blink.BlinkTextTrack.instance.label_Getter_(this);

  @DomName('TextTrack.language')
  @DocsEditable()
  String get language => _blink.BlinkTextTrack.instance.language_Getter_(this);

  @DomName('TextTrack.mode')
  @DocsEditable()
  String get mode => _blink.BlinkTextTrack.instance.mode_Getter_(this);

  @DomName('TextTrack.mode')
  @DocsEditable()
  void set mode(String value) => _blink.BlinkTextTrack.instance.mode_Setter_(this, value);

  @DomName('TextTrack.regions')
  @DocsEditable()
  @Experimental() // untriaged
  VttRegionList get regions => _blink.BlinkTextTrack.instance.regions_Getter_(this);

  @DomName('TextTrack.addCue')
  @DocsEditable()
  void addCue(TextTrackCue cue) => _blink.BlinkTextTrack.instance.addCue_Callback_1_(this, cue);

  @DomName('TextTrack.addRegion')
  @DocsEditable()
  @Experimental() // untriaged
  void addRegion(VttRegion region) => _blink.BlinkTextTrack.instance.addRegion_Callback_1_(this, region);

  @DomName('TextTrack.removeCue')
  @DocsEditable()
  void removeCue(TextTrackCue cue) => _blink.BlinkTextTrack.instance.removeCue_Callback_1_(this, cue);

  @DomName('TextTrack.removeRegion')
  @DocsEditable()
  @Experimental() // untriaged
  void removeRegion(VttRegion region) => _blink.BlinkTextTrack.instance.removeRegion_Callback_1_(this, region);

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

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('TextTrackCue')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#texttrackcue
@Experimental()
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 get endTime => _blink.BlinkTextTrackCue.instance.endTime_Getter_(this);

  @DomName('TextTrackCue.endTime')
  @DocsEditable()
  void set endTime(num value) => _blink.BlinkTextTrackCue.instance.endTime_Setter_(this, value);

  @DomName('TextTrackCue.id')
  @DocsEditable()
  String get id => _blink.BlinkTextTrackCue.instance.id_Getter_(this);

  @DomName('TextTrackCue.id')
  @DocsEditable()
  void set id(String value) => _blink.BlinkTextTrackCue.instance.id_Setter_(this, value);

  @DomName('TextTrackCue.pauseOnExit')
  @DocsEditable()
  bool get pauseOnExit => _blink.BlinkTextTrackCue.instance.pauseOnExit_Getter_(this);

  @DomName('TextTrackCue.pauseOnExit')
  @DocsEditable()
  void set pauseOnExit(bool value) => _blink.BlinkTextTrackCue.instance.pauseOnExit_Setter_(this, value);

  @DomName('TextTrackCue.startTime')
  @DocsEditable()
  num get startTime => _blink.BlinkTextTrackCue.instance.startTime_Getter_(this);

  @DomName('TextTrackCue.startTime')
  @DocsEditable()
  void set startTime(num value) => _blink.BlinkTextTrackCue.instance.startTime_Setter_(this, value);

  @DomName('TextTrackCue.track')
  @DocsEditable()
  TextTrack get track => _blink.BlinkTextTrackCue.instance.track_Getter_(this);

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

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('TextTrackCueList')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#texttrackcuelist
@Experimental()
class TextTrackCueList extends NativeFieldWrapperClass2 with ListMixin<TextTrackCue>, ImmutableListMixin<TextTrackCue> implements List<TextTrackCue> {
  // To suppress missing implicit constructor warnings.
  factory TextTrackCueList._() { throw new UnsupportedError("Not supported"); }

  @DomName('TextTrackCueList.length')
  @DocsEditable()
  int get length => _blink.BlinkTextTrackCueList.instance.length_Getter_(this);

  TextTrackCue operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return _blink.BlinkTextTrackCueList.instance.item_Callback_1_(this, index);
  }

  TextTrackCue _nativeIndexedGetter(int index) => _blink.BlinkTextTrackCueList.instance.item_Callback_1_(this, index);

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


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

  TextTrackCue get first {
    if (this.length > 0) {
      return _nativeIndexedGetter(0);
    }
    throw new StateError("No elements");
  }

  TextTrackCue get last {
    int len = this.length;
    if (len > 0) {
      return _nativeIndexedGetter(len - 1);
    }
    throw new StateError("No elements");
  }

  TextTrackCue get single {
    int len = this.length;
    if (len == 1) {
      return _nativeIndexedGetter(0);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

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

  @DomName('TextTrackCueList.getCueById')
  @DocsEditable()
  TextTrackCue getCueById(String id) => _blink.BlinkTextTrackCueList.instance.getCueById_Callback_1_(this, id);

  @DomName('TextTrackCueList.item')
  @DocsEditable()
  TextTrackCue item(int index) => _blink.BlinkTextTrackCueList.instance.item_Callback_1_(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.


@DocsEditable()
@DomName('TextTrackList')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#texttracklist
@Experimental()
class TextTrackList extends EventTarget with ListMixin<TextTrack>, ImmutableListMixin<TextTrack> implements List<TextTrack> {
  // To suppress missing implicit constructor warnings.
  factory TextTrackList._() { throw new UnsupportedError("Not supported"); }

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

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

  @DomName('TextTrackList.length')
  @DocsEditable()
  int get length => _blink.BlinkTextTrackList.instance.length_Getter_(this);

  TextTrack operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return _blink.BlinkTextTrackList.instance.item_Callback_1_(this, index);
  }

  TextTrack _nativeIndexedGetter(int index) => _blink.BlinkTextTrackList.instance.item_Callback_1_(this, index);

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


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

  TextTrack get first {
    if (this.length > 0) {
      return _nativeIndexedGetter(0);
    }
    throw new StateError("No elements");
  }

  TextTrack get last {
    int len = this.length;
    if (len > 0) {
      return _nativeIndexedGetter(len - 1);
    }
    throw new StateError("No elements");
  }

  TextTrack get single {
    int len = this.length;
    if (len == 1) {
      return _nativeIndexedGetter(0);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

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

  @DomName('TextTrackList.getTrackById')
  @DocsEditable()
  @Experimental() // untriaged
  TextTrack getTrackById(String id) => _blink.BlinkTextTrackList.instance.getTrackById_Callback_1_(this, id);

  @DomName('TextTrackList.item')
  @DocsEditable()
  TextTrack item(int index) => _blink.BlinkTextTrackList.instance.item_Callback_1_(this, index);

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

// WARNING: Do not edit - generated code.


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

  @DomName('TimeRanges.length')
  @DocsEditable()
  int get length => _blink.BlinkTimeRanges.instance.length_Getter_(this);

  @DomName('TimeRanges.end')
  @DocsEditable()
  double end(int index) => _blink.BlinkTimeRanges.instance.end_Callback_1_(this, index);

  @DomName('TimeRanges.start')
  @DocsEditable()
  double start(int index) => _blink.BlinkTimeRanges.instance.start_Callback_1_(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('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.

// WARNING: Do not edit - generated code.


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

  @DomName('Timing.delay')
  @DocsEditable()
  @Experimental() // untriaged
  num get delay => _blink.BlinkTiming.instance.delay_Getter_(this);

  @DomName('Timing.delay')
  @DocsEditable()
  @Experimental() // untriaged
  void set delay(num value) => _blink.BlinkTiming.instance.delay_Setter_(this, value);

  @DomName('Timing.direction')
  @DocsEditable()
  @Experimental() // untriaged
  String get direction => _blink.BlinkTiming.instance.direction_Getter_(this);

  @DomName('Timing.direction')
  @DocsEditable()
  @Experimental() // untriaged
  void set direction(String value) => _blink.BlinkTiming.instance.direction_Setter_(this, value);

  @DomName('Timing.easing')
  @DocsEditable()
  @Experimental() // untriaged
  String get easing => _blink.BlinkTiming.instance.easing_Getter_(this);

  @DomName('Timing.easing')
  @DocsEditable()
  @Experimental() // untriaged
  void set easing(String value) => _blink.BlinkTiming.instance.easing_Setter_(this, value);

  @DomName('Timing.endDelay')
  @DocsEditable()
  @Experimental() // untriaged
  num get endDelay => _blink.BlinkTiming.instance.endDelay_Getter_(this);

  @DomName('Timing.endDelay')
  @DocsEditable()
  @Experimental() // untriaged
  void set endDelay(num value) => _blink.BlinkTiming.instance.endDelay_Setter_(this, value);

  @DomName('Timing.fill')
  @DocsEditable()
  @Experimental() // untriaged
  String get fill => _blink.BlinkTiming.instance.fill_Getter_(this);

  @DomName('Timing.fill')
  @DocsEditable()
  @Experimental() // untriaged
  void set fill(String value) => _blink.BlinkTiming.instance.fill_Setter_(this, value);

  @DomName('Timing.iterationStart')
  @DocsEditable()
  @Experimental() // untriaged
  num get iterationStart => _blink.BlinkTiming.instance.iterationStart_Getter_(this);

  @DomName('Timing.iterationStart')
  @DocsEditable()
  @Experimental() // untriaged
  void set iterationStart(num value) => _blink.BlinkTiming.instance.iterationStart_Setter_(this, value);

  @DomName('Timing.iterations')
  @DocsEditable()
  @Experimental() // untriaged
  num get iterations => _blink.BlinkTiming.instance.iterations_Getter_(this);

  @DomName('Timing.iterations')
  @DocsEditable()
  @Experimental() // untriaged
  void set iterations(num value) => _blink.BlinkTiming.instance.iterations_Setter_(this, value);

  @DomName('Timing.playbackRate')
  @DocsEditable()
  @Experimental() // untriaged
  num get playbackRate => _blink.BlinkTiming.instance.playbackRate_Getter_(this);

  @DomName('Timing.playbackRate')
  @DocsEditable()
  @Experimental() // untriaged
  void set playbackRate(num value) => _blink.BlinkTiming.instance.playbackRate_Setter_(this, value);

  @DomName('Timing.__getter__')
  @DocsEditable()
  @Experimental() // untriaged
  Object __getter__(String name) => _blink.BlinkTiming.instance.$__getter___Callback_1_(this, name);

  @DomName('Timing.__setter__')
  @DocsEditable()
  @Experimental() // untriaged
  void __setter__(String name, num duration) => _blink.BlinkTiming.instance.$__setter___Callback_2_(this, name, duration);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


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

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

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


@DocsEditable()
@DomName('Touch')
// http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
@Experimental()
class Touch extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory Touch._() { throw new UnsupportedError("Not supported"); }

  @DomName('Touch.clientX')
  @DocsEditable()
  double get _clientX => _blink.BlinkTouch.instance.clientX_Getter_(this);

  @DomName('Touch.clientY')
  @DocsEditable()
  double get _clientY => _blink.BlinkTouch.instance.clientY_Getter_(this);

  @DomName('Touch.force')
  @DocsEditable()
  @Experimental() // untriaged
  double get force => _blink.BlinkTouch.instance.force_Getter_(this);

  @DomName('Touch.identifier')
  @DocsEditable()
  int get identifier => _blink.BlinkTouch.instance.identifier_Getter_(this);

  @DomName('Touch.pageX')
  @DocsEditable()
  double get _pageX => _blink.BlinkTouch.instance.pageX_Getter_(this);

  @DomName('Touch.pageY')
  @DocsEditable()
  double get _pageY => _blink.BlinkTouch.instance.pageY_Getter_(this);

  @DomName('Touch.radiusX')
  @DocsEditable()
  @Experimental() // untriaged
  double get _radiusX => _blink.BlinkTouch.instance.radiusX_Getter_(this);

  @DomName('Touch.radiusY')
  @DocsEditable()
  @Experimental() // untriaged
  double get _radiusY => _blink.BlinkTouch.instance.radiusY_Getter_(this);

  @DomName('Touch.screenX')
  @DocsEditable()
  double get _screenX => _blink.BlinkTouch.instance.screenX_Getter_(this);

  @DomName('Touch.screenY')
  @DocsEditable()
  double get _screenY => _blink.BlinkTouch.instance.screenY_Getter_(this);

  @DomName('Touch.target')
  @DocsEditable()
  EventTarget get target => _blink.BlinkTouch.instance.target_Getter_(this);

  @DomName('Touch.webkitRotationAngle')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  double get rotationAngle => _blink.BlinkTouch.instance.webkitRotationAngle_Getter_(this);


// As of Chrome 37, these all changed from long to double.  This code
// preserves backwards compatability for the time being.
  int get __clientX => _blink.BlinkTouch.clientX_Getter(this).round();
  int get __clientY => _blink.BlinkTouch.clientY_Getter(this).round();
  int get __screenX => _blink.BlinkTouch.screenX_Getter(this).round();
  int get __screenY => _blink.BlinkTouch.screenY_Getter(this).round();
  int get __pageX => _blink.BlinkTouch.pageX_Getter(this).round();
  int get __pageY => _blink.BlinkTouch.pageY_Getter(this).round();
  int get __radiusX => _blink.BlinkTouch.radiusX_Getter(this).round();
  int get __radiusY => _blink.BlinkTouch.radiusY_Getter(this).round();

  @DomName('Touch.clientX')
  @DomName('Touch.clientY')
  Point get client => new Point(__clientX, __clientY);

  @DomName('Touch.pageX')
  @DomName('Touch.pageY')
  Point get page => new Point(__pageX, __pageY);

  @DomName('Touch.screenX')
  @DomName('Touch.screenY')
  Point get screen => new Point(__screenX, __screenY);

  @DomName('Touch.radiusX')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  int get radiusX => __radiusX;

  @DomName('Touch.radiusY')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  int get radiusY => __radiusY;

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

// WARNING: Do not edit - generated code.


@DomName('TouchEvent')
// http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
@Experimental()
class TouchEvent extends UIEvent {
  factory TouchEvent(TouchList touches, TouchList targetTouches,
      TouchList changedTouches, String type,
      {Window view, int screenX: 0, int screenY: 0, int clientX: 0,
      int clientY: 0, bool ctrlKey: false, bool altKey: false,
      bool shiftKey: false, bool metaKey: false}) {
    if (view == null) {
      view = window;
    }
    var e = document._createEvent("TouchEvent");
    e._initTouchEvent(touches, targetTouches, changedTouches, type, view,
        screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey);
    return e;
  }
  // To suppress missing implicit constructor warnings.
  factory TouchEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('TouchEvent.altKey')
  @DocsEditable()
  bool get altKey => _blink.BlinkTouchEvent.instance.altKey_Getter_(this);

  @DomName('TouchEvent.changedTouches')
  @DocsEditable()
  TouchList get changedTouches => _blink.BlinkTouchEvent.instance.changedTouches_Getter_(this);

  @DomName('TouchEvent.ctrlKey')
  @DocsEditable()
  bool get ctrlKey => _blink.BlinkTouchEvent.instance.ctrlKey_Getter_(this);

  @DomName('TouchEvent.metaKey')
  @DocsEditable()
  bool get metaKey => _blink.BlinkTouchEvent.instance.metaKey_Getter_(this);

  @DomName('TouchEvent.shiftKey')
  @DocsEditable()
  bool get shiftKey => _blink.BlinkTouchEvent.instance.shiftKey_Getter_(this);

  @DomName('TouchEvent.targetTouches')
  @DocsEditable()
  TouchList get targetTouches => _blink.BlinkTouchEvent.instance.targetTouches_Getter_(this);

  @DomName('TouchEvent.touches')
  @DocsEditable()
  TouchList get touches => _blink.BlinkTouchEvent.instance.touches_Getter_(this);

  @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) => _blink.BlinkTouchEvent.instance.initTouchEvent_Callback_13_(this, touches, targetTouches, changedTouches, type, view, unused1, unused2, unused3, unused4, ctrlKey, altKey, shiftKey, metaKey);


  /**
   * Checks if touch events supported on the current platform.
   *
   * Note that touch events are only supported if the user is using a touch
   * device.
   */
  static bool get supported => Device.isEventTypeSupported('TouchEvent');
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('TouchList')
// http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
@Experimental()
class TouchList extends NativeFieldWrapperClass2 with ListMixin<Touch>, ImmutableListMixin<Touch> implements 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 => true;

  @DomName('TouchList.length')
  @DocsEditable()
  int get length => _blink.BlinkTouchList.instance.length_Getter_(this);

  Touch operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return _blink.BlinkTouchList.instance.item_Callback_1_(this, index);
  }

  Touch _nativeIndexedGetter(int index) => _blink.BlinkTouchList.instance.item_Callback_1_(this, index);

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


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

  Touch get first {
    if (this.length > 0) {
      return _nativeIndexedGetter(0);
    }
    throw new StateError("No elements");
  }

  Touch get last {
    int len = this.length;
    if (len > 0) {
      return _nativeIndexedGetter(len - 1);
    }
    throw new StateError("No elements");
  }

  Touch get single {
    int len = this.length;
    if (len == 1) {
      return _nativeIndexedGetter(0);
    }
    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) => _blink.BlinkTouchList.instance.item_Callback_1_(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.


@DocsEditable()
@DomName('HTMLTrackElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#the-track-element
@Experimental()
class TrackElement extends HtmlElement {
  // 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 => true;

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

  @DomName('HTMLTrackElement.default')
  @DocsEditable()
  bool get defaultValue => _blink.BlinkHTMLTrackElement.instance.default_Getter_(this);

  @DomName('HTMLTrackElement.default')
  @DocsEditable()
  void set defaultValue(bool value) => _blink.BlinkHTMLTrackElement.instance.default_Setter_(this, value);

  @DomName('HTMLTrackElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String get integrity => _blink.BlinkHTMLTrackElement.instance.integrity_Getter_(this);

  @DomName('HTMLTrackElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  void set integrity(String value) => _blink.BlinkHTMLTrackElement.instance.integrity_Setter_(this, value);

  @DomName('HTMLTrackElement.kind')
  @DocsEditable()
  String get kind => _blink.BlinkHTMLTrackElement.instance.kind_Getter_(this);

  @DomName('HTMLTrackElement.kind')
  @DocsEditable()
  void set kind(String value) => _blink.BlinkHTMLTrackElement.instance.kind_Setter_(this, value);

  @DomName('HTMLTrackElement.label')
  @DocsEditable()
  String get label => _blink.BlinkHTMLTrackElement.instance.label_Getter_(this);

  @DomName('HTMLTrackElement.label')
  @DocsEditable()
  void set label(String value) => _blink.BlinkHTMLTrackElement.instance.label_Setter_(this, value);

  @DomName('HTMLTrackElement.readyState')
  @DocsEditable()
  int get readyState => _blink.BlinkHTMLTrackElement.instance.readyState_Getter_(this);

  @DomName('HTMLTrackElement.src')
  @DocsEditable()
  String get src => _blink.BlinkHTMLTrackElement.instance.src_Getter_(this);

  @DomName('HTMLTrackElement.src')
  @DocsEditable()
  void set src(String value) => _blink.BlinkHTMLTrackElement.instance.src_Setter_(this, value);

  @DomName('HTMLTrackElement.srclang')
  @DocsEditable()
  String get srclang => _blink.BlinkHTMLTrackElement.instance.srclang_Getter_(this);

  @DomName('HTMLTrackElement.srclang')
  @DocsEditable()
  void set srclang(String value) => _blink.BlinkHTMLTrackElement.instance.srclang_Setter_(this, value);

  @DomName('HTMLTrackElement.track')
  @DocsEditable()
  TextTrack get track => _blink.BlinkHTMLTrackElement.instance.track_Getter_(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.


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

  @DomName('TrackEvent.track')
  @DocsEditable()
  Object get track => _blink.BlinkTrackEvent.instance.track_Getter_(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.


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

  @DomName('TransitionEvent.elapsedTime')
  @DocsEditable()
  double get elapsedTime => _blink.BlinkTransitionEvent.instance.elapsedTime_Getter_(this);

  @DomName('TransitionEvent.propertyName')
  @DocsEditable()
  String get propertyName => _blink.BlinkTransitionEvent.instance.propertyName_Getter_(this);

  @DomName('TransitionEvent.pseudoElement')
  @DocsEditable()
  String get pseudoElement => _blink.BlinkTransitionEvent.instance.pseudoElement_Getter_(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('TreeWalker')
@Unstable()
class TreeWalker extends NativeFieldWrapperClass2 {
  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 get currentNode => _blink.BlinkTreeWalker.instance.currentNode_Getter_(this);

  @DomName('TreeWalker.currentNode')
  @DocsEditable()
  void set currentNode(Node value) => _blink.BlinkTreeWalker.instance.currentNode_Setter_(this, value);

  @DomName('TreeWalker.filter')
  @DocsEditable()
  NodeFilter get filter => _blink.BlinkTreeWalker.instance.filter_Getter_(this);

  @DomName('TreeWalker.root')
  @DocsEditable()
  Node get root => _blink.BlinkTreeWalker.instance.root_Getter_(this);

  @DomName('TreeWalker.whatToShow')
  @DocsEditable()
  int get whatToShow => _blink.BlinkTreeWalker.instance.whatToShow_Getter_(this);

  @DomName('TreeWalker.firstChild')
  @DocsEditable()
  Node firstChild() => _blink.BlinkTreeWalker.instance.firstChild_Callback_0_(this);

  @DomName('TreeWalker.lastChild')
  @DocsEditable()
  Node lastChild() => _blink.BlinkTreeWalker.instance.lastChild_Callback_0_(this);

  @DomName('TreeWalker.nextNode')
  @DocsEditable()
  Node nextNode() => _blink.BlinkTreeWalker.instance.nextNode_Callback_0_(this);

  @DomName('TreeWalker.nextSibling')
  @DocsEditable()
  Node nextSibling() => _blink.BlinkTreeWalker.instance.nextSibling_Callback_0_(this);

  @DomName('TreeWalker.parentNode')
  @DocsEditable()
  Node parentNode() => _blink.BlinkTreeWalker.instance.parentNode_Callback_0_(this);

  @DomName('TreeWalker.previousNode')
  @DocsEditable()
  Node previousNode() => _blink.BlinkTreeWalker.instance.previousNode_Callback_0_(this);

  @DomName('TreeWalker.previousSibling')
  @DocsEditable()
  Node previousSibling() => _blink.BlinkTreeWalker.instance.previousSibling_Callback_0_(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('UIEvent')
class UIEvent extends Event {
  // In JS, canBubble and cancelable are technically required parameters to
  // init*Event. In practice, though, if they aren't provided they simply
  // default to false (since that's Boolean(undefined)).
  //
  // Contrary to JS, we default canBubble and cancelable to true, since that's
  // what people want most of the time anyway.
  factory UIEvent(String type,
      {Window view, int detail: 0, bool canBubble: true,
      bool cancelable: true}) {
    if (view == null) {
      view = window;
    }
    final e = document._createEvent("UIEvent");
    e._initUIEvent(type, canBubble, cancelable, view, detail);
    return e;
  }
  // To suppress missing implicit constructor warnings.
  factory UIEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('UIEvent.charCode')
  @DocsEditable()
  @Unstable()
  int get _charCode => _blink.BlinkUIEvent.instance.charCode_Getter_(this);

  @DomName('UIEvent.detail')
  @DocsEditable()
  int get detail => _blink.BlinkUIEvent.instance.detail_Getter_(this);

  @DomName('UIEvent.keyCode')
  @DocsEditable()
  @Unstable()
  int get _keyCode => _blink.BlinkUIEvent.instance.keyCode_Getter_(this);

  @DomName('UIEvent.layerX')
  @DocsEditable()
  // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-mouseevents
  @Experimental() // nonstandard
  int get _layerX => _blink.BlinkUIEvent.instance.layerX_Getter_(this);

  @DomName('UIEvent.layerY')
  @DocsEditable()
  // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-mouseevents
  @Experimental() // nonstandard
  int get _layerY => _blink.BlinkUIEvent.instance.layerY_Getter_(this);

  @DomName('UIEvent.pageX')
  @DocsEditable()
  // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-mouseevents
  @Experimental() // nonstandard
  int get _pageX => _blink.BlinkUIEvent.instance.pageX_Getter_(this);

  @DomName('UIEvent.pageY')
  @DocsEditable()
  // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-mouseevents
  @Experimental() // nonstandard
  int get _pageY => _blink.BlinkUIEvent.instance.pageY_Getter_(this);

  @DomName('UIEvent.view')
  @DocsEditable()
  WindowBase get view => _blink.BlinkUIEvent.instance.view_Getter_(this);

  @DomName('UIEvent.which')
  @DocsEditable()
  @Unstable()
  int get which => _blink.BlinkUIEvent.instance.which_Getter_(this);

  @DomName('UIEvent.initUIEvent')
  @DocsEditable()
  void _initUIEvent(String type, bool canBubble, bool cancelable, Window view, int detail) => _blink.BlinkUIEvent.instance.initUIEvent_Callback_5_(this, type, canBubble, cancelable, view, detail);


  @DomName('UIEvent.layerX')
  @DomName('UIEvent.layerY')
  Point get layer => new Point(_layerX, _layerY);

  @DomName('UIEvent.pageX')
  @DomName('UIEvent.pageY')
  Point get page => new Point(_pageX, _pageY);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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

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

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

// WARNING: Do not edit - generated code.


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

// WARNING: Do not edit - generated code.


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

  static String createObjectUrl(blob_OR_source_OR_stream) {
    if ((blob_OR_source_OR_stream is Blob || blob_OR_source_OR_stream == null)) {
      return _blink.BlinkURL.instance.createObjectURL_Callback_1_(blob_OR_source_OR_stream);
    }
    if ((blob_OR_source_OR_stream is MediaStream)) {
      return _blink.BlinkURL.instance.createObjectURL_Callback_1_(blob_OR_source_OR_stream);
    }
    if ((blob_OR_source_OR_stream is MediaSource)) {
      return _blink.BlinkURL.instance.createObjectURL_Callback_1_(blob_OR_source_OR_stream);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('URL.createObjectUrlFromBlob')
  @DocsEditable()
  static String createObjectUrlFromBlob(Blob blob) => _blink.BlinkURL.instance.createObjectURL_Callback_1_(blob);

  @DomName('URL.createObjectUrlFromSource')
  @DocsEditable()
  static String createObjectUrlFromSource(MediaSource source) => _blink.BlinkURL.instance.createObjectURL_Callback_1_(source);

  @DomName('URL.createObjectUrlFromStream')
  @DocsEditable()
  static String createObjectUrlFromStream(MediaStream stream) => _blink.BlinkURL.instance.createObjectURL_Callback_1_(stream);

  @DomName('URL.revokeObjectURL')
  @DocsEditable()
  static void revokeObjectUrl(String url) => _blink.BlinkURL.instance.revokeObjectURL_Callback_1_(url);

  @DomName('URL.hash')
  @DocsEditable()
  @Experimental() // untriaged
  String get hash => _blink.BlinkURL.instance.hash_Getter_(this);

  @DomName('URL.hash')
  @DocsEditable()
  @Experimental() // untriaged
  void set hash(String value) => _blink.BlinkURL.instance.hash_Setter_(this, value);

  @DomName('URL.host')
  @DocsEditable()
  @Experimental() // untriaged
  String get host => _blink.BlinkURL.instance.host_Getter_(this);

  @DomName('URL.host')
  @DocsEditable()
  @Experimental() // untriaged
  void set host(String value) => _blink.BlinkURL.instance.host_Setter_(this, value);

  @DomName('URL.hostname')
  @DocsEditable()
  @Experimental() // untriaged
  String get hostname => _blink.BlinkURL.instance.hostname_Getter_(this);

  @DomName('URL.hostname')
  @DocsEditable()
  @Experimental() // untriaged
  void set hostname(String value) => _blink.BlinkURL.instance.hostname_Setter_(this, value);

  @DomName('URL.href')
  @DocsEditable()
  @Experimental() // untriaged
  String get href => _blink.BlinkURL.instance.href_Getter_(this);

  @DomName('URL.href')
  @DocsEditable()
  @Experimental() // untriaged
  void set href(String value) => _blink.BlinkURL.instance.href_Setter_(this, value);

  @DomName('URL.origin')
  @DocsEditable()
  @Experimental() // untriaged
  String get origin => _blink.BlinkURL.instance.origin_Getter_(this);

  @DomName('URL.password')
  @DocsEditable()
  @Experimental() // untriaged
  String get password => _blink.BlinkURL.instance.password_Getter_(this);

  @DomName('URL.password')
  @DocsEditable()
  @Experimental() // untriaged
  void set password(String value) => _blink.BlinkURL.instance.password_Setter_(this, value);

  @DomName('URL.pathname')
  @DocsEditable()
  @Experimental() // untriaged
  String get pathname => _blink.BlinkURL.instance.pathname_Getter_(this);

  @DomName('URL.pathname')
  @DocsEditable()
  @Experimental() // untriaged
  void set pathname(String value) => _blink.BlinkURL.instance.pathname_Setter_(this, value);

  @DomName('URL.port')
  @DocsEditable()
  @Experimental() // untriaged
  String get port => _blink.BlinkURL.instance.port_Getter_(this);

  @DomName('URL.port')
  @DocsEditable()
  @Experimental() // untriaged
  void set port(String value) => _blink.BlinkURL.instance.port_Setter_(this, value);

  @DomName('URL.protocol')
  @DocsEditable()
  @Experimental() // untriaged
  String get protocol => _blink.BlinkURL.instance.protocol_Getter_(this);

  @DomName('URL.protocol')
  @DocsEditable()
  @Experimental() // untriaged
  void set protocol(String value) => _blink.BlinkURL.instance.protocol_Setter_(this, value);

  @DomName('URL.search')
  @DocsEditable()
  @Experimental() // untriaged
  String get search => _blink.BlinkURL.instance.search_Getter_(this);

  @DomName('URL.search')
  @DocsEditable()
  @Experimental() // untriaged
  void set search(String value) => _blink.BlinkURL.instance.search_Setter_(this, value);

  @DomName('URL.username')
  @DocsEditable()
  @Experimental() // untriaged
  String get username => _blink.BlinkURL.instance.username_Getter_(this);

  @DomName('URL.username')
  @DocsEditable()
  @Experimental() // untriaged
  void set username(String value) => _blink.BlinkURL.instance.username_Setter_(this, value);

  @DomName('URL.toString')
  @DocsEditable()
  @Experimental() // untriaged
  String toString() => _blink.BlinkURL.instance.toString_Callback_0_(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.


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

  @DomName('URLUtils.hash')
  @DocsEditable()
  @Experimental() // untriaged
  String get hash;

  @DomName('URLUtils.hash')
  @DocsEditable()
  @Experimental() // untriaged
  void set hash(String value);

  @DomName('URLUtils.host')
  @DocsEditable()
  @Experimental() // untriaged
  String get host;

  @DomName('URLUtils.host')
  @DocsEditable()
  @Experimental() // untriaged
  void set host(String value);

  @DomName('URLUtils.hostname')
  @DocsEditable()
  @Experimental() // untriaged
  String get hostname;

  @DomName('URLUtils.hostname')
  @DocsEditable()
  @Experimental() // untriaged
  void set hostname(String value);

  @DomName('URLUtils.href')
  @DocsEditable()
  @Experimental() // untriaged
  String get href;

  @DomName('URLUtils.href')
  @DocsEditable()
  @Experimental() // untriaged
  void set href(String value);

  @DomName('URLUtils.origin')
  @DocsEditable()
  @Experimental() // untriaged
  String get origin;

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

  @DomName('URLUtils.password')
  @DocsEditable()
  @Experimental() // untriaged
  void set password(String value);

  @DomName('URLUtils.pathname')
  @DocsEditable()
  @Experimental() // untriaged
  String get pathname;

  @DomName('URLUtils.pathname')
  @DocsEditable()
  @Experimental() // untriaged
  void set pathname(String value);

  @DomName('URLUtils.port')
  @DocsEditable()
  @Experimental() // untriaged
  String get port;

  @DomName('URLUtils.port')
  @DocsEditable()
  @Experimental() // untriaged
  void set port(String value);

  @DomName('URLUtils.protocol')
  @DocsEditable()
  @Experimental() // untriaged
  String get protocol;

  @DomName('URLUtils.protocol')
  @DocsEditable()
  @Experimental() // untriaged
  void set protocol(String value);

  @DomName('URLUtils.search')
  @DocsEditable()
  @Experimental() // untriaged
  String get search;

  @DomName('URLUtils.search')
  @DocsEditable()
  @Experimental() // untriaged
  void set search(String value);

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

  @DomName('URLUtils.username')
  @DocsEditable()
  @Experimental() // untriaged
  void set username(String value);

  @DomName('URLUtils.toString')
  @DocsEditable()
  @Experimental() // untriaged
  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.

// WARNING: Do not edit - generated code.


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

  @DomName('URLUtilsReadOnly.hash')
  @DocsEditable()
  @Experimental() // untriaged
  String get hash;

  @DomName('URLUtilsReadOnly.host')
  @DocsEditable()
  @Experimental() // untriaged
  String get host;

  @DomName('URLUtilsReadOnly.hostname')
  @DocsEditable()
  @Experimental() // untriaged
  String get hostname;

  @DomName('URLUtilsReadOnly.href')
  @DocsEditable()
  @Experimental() // untriaged
  String get href;

  @DomName('URLUtilsReadOnly.origin')
  @DocsEditable()
  @Experimental() // untriaged
  String get origin;

  @DomName('URLUtilsReadOnly.pathname')
  @DocsEditable()
  @Experimental() // untriaged
  String get pathname;

  @DomName('URLUtilsReadOnly.port')
  @DocsEditable()
  @Experimental() // untriaged
  String get port;

  @DomName('URLUtilsReadOnly.protocol')
  @DocsEditable()
  @Experimental() // untriaged
  String get protocol;

  @DomName('URLUtilsReadOnly.search')
  @DocsEditable()
  @Experimental() // untriaged
  String get search;

  @DomName('URLUtilsReadOnly.toString')
  @DocsEditable()
  @Experimental() // untriaged
  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.

// WARNING: Do not edit - generated code.


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

  @DomName('ValidityState.badInput')
  @DocsEditable()
  bool get badInput => _blink.BlinkValidityState.instance.badInput_Getter_(this);

  @DomName('ValidityState.customError')
  @DocsEditable()
  bool get customError => _blink.BlinkValidityState.instance.customError_Getter_(this);

  @DomName('ValidityState.patternMismatch')
  @DocsEditable()
  bool get patternMismatch => _blink.BlinkValidityState.instance.patternMismatch_Getter_(this);

  @DomName('ValidityState.rangeOverflow')
  @DocsEditable()
  bool get rangeOverflow => _blink.BlinkValidityState.instance.rangeOverflow_Getter_(this);

  @DomName('ValidityState.rangeUnderflow')
  @DocsEditable()
  bool get rangeUnderflow => _blink.BlinkValidityState.instance.rangeUnderflow_Getter_(this);

  @DomName('ValidityState.stepMismatch')
  @DocsEditable()
  bool get stepMismatch => _blink.BlinkValidityState.instance.stepMismatch_Getter_(this);

  @DomName('ValidityState.tooLong')
  @DocsEditable()
  bool get tooLong => _blink.BlinkValidityState.instance.tooLong_Getter_(this);

  @DomName('ValidityState.typeMismatch')
  @DocsEditable()
  bool get typeMismatch => _blink.BlinkValidityState.instance.typeMismatch_Getter_(this);

  @DomName('ValidityState.valid')
  @DocsEditable()
  bool get valid => _blink.BlinkValidityState.instance.valid_Getter_(this);

  @DomName('ValidityState.valueMissing')
  @DocsEditable()
  bool get valueMissing => _blink.BlinkValidityState.instance.valueMissing_Getter_(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('HTMLVideoElement')
class VideoElement extends MediaElement implements CanvasImageSource {
  // To suppress missing implicit constructor warnings.
  factory VideoElement._() { throw new UnsupportedError("Not supported"); }

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

  @DomName('HTMLVideoElement.height')
  @DocsEditable()
  int get height => _blink.BlinkHTMLVideoElement.instance.height_Getter_(this);

  @DomName('HTMLVideoElement.height')
  @DocsEditable()
  void set height(int value) => _blink.BlinkHTMLVideoElement.instance.height_Setter_(this, value);

  @DomName('HTMLVideoElement.poster')
  @DocsEditable()
  String get poster => _blink.BlinkHTMLVideoElement.instance.poster_Getter_(this);

  @DomName('HTMLVideoElement.poster')
  @DocsEditable()
  void set poster(String value) => _blink.BlinkHTMLVideoElement.instance.poster_Setter_(this, value);

  @DomName('HTMLVideoElement.videoHeight')
  @DocsEditable()
  int get videoHeight => _blink.BlinkHTMLVideoElement.instance.videoHeight_Getter_(this);

  @DomName('HTMLVideoElement.videoWidth')
  @DocsEditable()
  int get videoWidth => _blink.BlinkHTMLVideoElement.instance.videoWidth_Getter_(this);

  @DomName('HTMLVideoElement.webkitDecodedFrameCount')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  int get decodedFrameCount => _blink.BlinkHTMLVideoElement.instance.webkitDecodedFrameCount_Getter_(this);

  @DomName('HTMLVideoElement.webkitDroppedFrameCount')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  int get droppedFrameCount => _blink.BlinkHTMLVideoElement.instance.webkitDroppedFrameCount_Getter_(this);

  @DomName('HTMLVideoElement.width')
  @DocsEditable()
  int get width => _blink.BlinkHTMLVideoElement.instance.width_Getter_(this);

  @DomName('HTMLVideoElement.width')
  @DocsEditable()
  void set width(int value) => _blink.BlinkHTMLVideoElement.instance.width_Setter_(this, value);

  @DomName('HTMLVideoElement.getVideoPlaybackQuality')
  @DocsEditable()
  @Experimental() // untriaged
  VideoPlaybackQuality getVideoPlaybackQuality() => _blink.BlinkHTMLVideoElement.instance.getVideoPlaybackQuality_Callback_0_(this);

  @DomName('HTMLVideoElement.webkitEnterFullscreen')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  void enterFullscreen() => _blink.BlinkHTMLVideoElement.instance.webkitEnterFullscreen_Callback_0_(this);

  @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() => _blink.BlinkHTMLVideoElement.instance.webkitExitFullscreen_Callback_0_(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.


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

  @DomName('VideoPlaybackQuality.corruptedVideoFrames')
  @DocsEditable()
  @Experimental() // untriaged
  int get corruptedVideoFrames => _blink.BlinkVideoPlaybackQuality.instance.corruptedVideoFrames_Getter_(this);

  @DomName('VideoPlaybackQuality.creationTime')
  @DocsEditable()
  @Experimental() // untriaged
  double get creationTime => _blink.BlinkVideoPlaybackQuality.instance.creationTime_Getter_(this);

  @DomName('VideoPlaybackQuality.droppedVideoFrames')
  @DocsEditable()
  @Experimental() // untriaged
  int get droppedVideoFrames => _blink.BlinkVideoPlaybackQuality.instance.droppedVideoFrames_Getter_(this);

  @DomName('VideoPlaybackQuality.totalVideoFrames')
  @DocsEditable()
  @Experimental() // untriaged
  int get totalVideoFrames => _blink.BlinkVideoPlaybackQuality.instance.totalVideoFrames_Getter_(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.


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

  @DomName('VideoTrack.id')
  @DocsEditable()
  @Experimental() // untriaged
  String get id => _blink.BlinkVideoTrack.instance.id_Getter_(this);

  @DomName('VideoTrack.kind')
  @DocsEditable()
  @Experimental() // untriaged
  String get kind => _blink.BlinkVideoTrack.instance.kind_Getter_(this);

  @DomName('VideoTrack.label')
  @DocsEditable()
  @Experimental() // untriaged
  String get label => _blink.BlinkVideoTrack.instance.label_Getter_(this);

  @DomName('VideoTrack.language')
  @DocsEditable()
  @Experimental() // untriaged
  String get language => _blink.BlinkVideoTrack.instance.language_Getter_(this);

  @DomName('VideoTrack.selected')
  @DocsEditable()
  @Experimental() // untriaged
  bool get selected => _blink.BlinkVideoTrack.instance.selected_Getter_(this);

  @DomName('VideoTrack.selected')
  @DocsEditable()
  @Experimental() // untriaged
  void set selected(bool value) => _blink.BlinkVideoTrack.instance.selected_Setter_(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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('VideoTrackList')
@Experimental() // untriaged
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
  int get length => _blink.BlinkVideoTrackList.instance.length_Getter_(this);

  @DomName('VideoTrackList.selectedIndex')
  @DocsEditable()
  @Experimental() // untriaged
  int get selectedIndex => _blink.BlinkVideoTrackList.instance.selectedIndex_Getter_(this);

  @DomName('VideoTrackList.__getter__')
  @DocsEditable()
  @Experimental() // untriaged
  VideoTrack __getter__(int index) => _blink.BlinkVideoTrackList.instance.$__getter___Callback_1_(this, index);

  @DomName('VideoTrackList.getTrackById')
  @DocsEditable()
  @Experimental() // untriaged
  VideoTrack getTrackById(String id) => _blink.BlinkVideoTrackList.instance.getTrackById_Callback_1_(this, id);

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

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('VTTCue')
@Experimental() // untriaged
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 _blink.BlinkVTTCue.instance.constructorCallback_3_(startTime, endTime, text);
  }

  @DomName('VTTCue.align')
  @DocsEditable()
  @Experimental() // untriaged
  String get align => _blink.BlinkVTTCue.instance.align_Getter_(this);

  @DomName('VTTCue.align')
  @DocsEditable()
  @Experimental() // untriaged
  void set align(String value) => _blink.BlinkVTTCue.instance.align_Setter_(this, value);

  @DomName('VTTCue.line')
  @DocsEditable()
  @Experimental() // untriaged
  int get line => _blink.BlinkVTTCue.instance.line_Getter_(this);

  @DomName('VTTCue.line')
  @DocsEditable()
  @Experimental() // untriaged
  void set line(int value) => _blink.BlinkVTTCue.instance.line_Setter_(this, value);

  @DomName('VTTCue.position')
  @DocsEditable()
  @Experimental() // untriaged
  int get position => _blink.BlinkVTTCue.instance.position_Getter_(this);

  @DomName('VTTCue.position')
  @DocsEditable()
  @Experimental() // untriaged
  void set position(int value) => _blink.BlinkVTTCue.instance.position_Setter_(this, value);

  @DomName('VTTCue.regionId')
  @DocsEditable()
  @Experimental() // untriaged
  String get regionId => _blink.BlinkVTTCue.instance.regionId_Getter_(this);

  @DomName('VTTCue.regionId')
  @DocsEditable()
  @Experimental() // untriaged
  void set regionId(String value) => _blink.BlinkVTTCue.instance.regionId_Setter_(this, value);

  @DomName('VTTCue.size')
  @DocsEditable()
  @Experimental() // untriaged
  int get size => _blink.BlinkVTTCue.instance.size_Getter_(this);

  @DomName('VTTCue.size')
  @DocsEditable()
  @Experimental() // untriaged
  void set size(int value) => _blink.BlinkVTTCue.instance.size_Setter_(this, value);

  @DomName('VTTCue.snapToLines')
  @DocsEditable()
  @Experimental() // untriaged
  bool get snapToLines => _blink.BlinkVTTCue.instance.snapToLines_Getter_(this);

  @DomName('VTTCue.snapToLines')
  @DocsEditable()
  @Experimental() // untriaged
  void set snapToLines(bool value) => _blink.BlinkVTTCue.instance.snapToLines_Setter_(this, value);

  @DomName('VTTCue.text')
  @DocsEditable()
  @Experimental() // untriaged
  String get text => _blink.BlinkVTTCue.instance.text_Getter_(this);

  @DomName('VTTCue.text')
  @DocsEditable()
  @Experimental() // untriaged
  void set text(String value) => _blink.BlinkVTTCue.instance.text_Setter_(this, value);

  @DomName('VTTCue.vertical')
  @DocsEditable()
  @Experimental() // untriaged
  String get vertical => _blink.BlinkVTTCue.instance.vertical_Getter_(this);

  @DomName('VTTCue.vertical')
  @DocsEditable()
  @Experimental() // untriaged
  void set vertical(String value) => _blink.BlinkVTTCue.instance.vertical_Setter_(this, value);

  @DomName('VTTCue.getCueAsHTML')
  @DocsEditable()
  @Experimental() // untriaged
  DocumentFragment getCueAsHtml() => _blink.BlinkVTTCue.instance.getCueAsHTML_Callback_0_(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.


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

  @DomName('VTTRegion.VTTRegion')
  @DocsEditable()
  factory VttRegion() {
    return _blink.BlinkVTTRegion.instance.constructorCallback_0_();
  }

  @DomName('VTTRegion.height')
  @DocsEditable()
  @Experimental() // untriaged
  int get height => _blink.BlinkVTTRegion.instance.height_Getter_(this);

  @DomName('VTTRegion.height')
  @DocsEditable()
  @Experimental() // untriaged
  void set height(int value) => _blink.BlinkVTTRegion.instance.height_Setter_(this, value);

  @DomName('VTTRegion.id')
  @DocsEditable()
  @Experimental() // untriaged
  String get id => _blink.BlinkVTTRegion.instance.id_Getter_(this);

  @DomName('VTTRegion.id')
  @DocsEditable()
  @Experimental() // untriaged
  void set id(String value) => _blink.BlinkVTTRegion.instance.id_Setter_(this, value);

  @DomName('VTTRegion.regionAnchorX')
  @DocsEditable()
  @Experimental() // untriaged
  num get regionAnchorX => _blink.BlinkVTTRegion.instance.regionAnchorX_Getter_(this);

  @DomName('VTTRegion.regionAnchorX')
  @DocsEditable()
  @Experimental() // untriaged
  void set regionAnchorX(num value) => _blink.BlinkVTTRegion.instance.regionAnchorX_Setter_(this, value);

  @DomName('VTTRegion.regionAnchorY')
  @DocsEditable()
  @Experimental() // untriaged
  num get regionAnchorY => _blink.BlinkVTTRegion.instance.regionAnchorY_Getter_(this);

  @DomName('VTTRegion.regionAnchorY')
  @DocsEditable()
  @Experimental() // untriaged
  void set regionAnchorY(num value) => _blink.BlinkVTTRegion.instance.regionAnchorY_Setter_(this, value);

  @DomName('VTTRegion.scroll')
  @DocsEditable()
  @Experimental() // untriaged
  String get scroll => _blink.BlinkVTTRegion.instance.scroll_Getter_(this);

  @DomName('VTTRegion.scroll')
  @DocsEditable()
  @Experimental() // untriaged
  void set scroll(String value) => _blink.BlinkVTTRegion.instance.scroll_Setter_(this, value);

  @DomName('VTTRegion.track')
  @DocsEditable()
  @Experimental() // untriaged
  TextTrack get track => _blink.BlinkVTTRegion.instance.track_Getter_(this);

  @DomName('VTTRegion.viewportAnchorX')
  @DocsEditable()
  @Experimental() // untriaged
  num get viewportAnchorX => _blink.BlinkVTTRegion.instance.viewportAnchorX_Getter_(this);

  @DomName('VTTRegion.viewportAnchorX')
  @DocsEditable()
  @Experimental() // untriaged
  void set viewportAnchorX(num value) => _blink.BlinkVTTRegion.instance.viewportAnchorX_Setter_(this, value);

  @DomName('VTTRegion.viewportAnchorY')
  @DocsEditable()
  @Experimental() // untriaged
  num get viewportAnchorY => _blink.BlinkVTTRegion.instance.viewportAnchorY_Getter_(this);

  @DomName('VTTRegion.viewportAnchorY')
  @DocsEditable()
  @Experimental() // untriaged
  void set viewportAnchorY(num value) => _blink.BlinkVTTRegion.instance.viewportAnchorY_Setter_(this, value);

  @DomName('VTTRegion.width')
  @DocsEditable()
  @Experimental() // untriaged
  num get width => _blink.BlinkVTTRegion.instance.width_Getter_(this);

  @DomName('VTTRegion.width')
  @DocsEditable()
  @Experimental() // untriaged
  void set width(num value) => _blink.BlinkVTTRegion.instance.width_Setter_(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.

// WARNING: Do not edit - generated code.


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

  @DomName('VTTRegionList.length')
  @DocsEditable()
  @Experimental() // untriaged
  int get length => _blink.BlinkVTTRegionList.instance.length_Getter_(this);

  @DomName('VTTRegionList.getRegionById')
  @DocsEditable()
  @Experimental() // untriaged
  VttRegion getRegionById(String id) => _blink.BlinkVTTRegionList.instance.getRegionById_Callback_1_(this, id);

  @DomName('VTTRegionList.item')
  @DocsEditable()
  @Experimental() // untriaged
  VttRegion item(int index) => _blink.BlinkVTTRegionList.instance.item_Callback_1_(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.


@DocsEditable()
/**
 * Use the WebSocket interface to connect to a WebSocket,
 * and to send and receive data on that WebSocket.
 *
 * To use a WebSocket in your web app, first create a WebSocket object,
 * passing the WebSocket URL as an argument to the constructor.
 *
 *     var webSocket = new WebSocket('ws://127.0.0.1:1337/ws');
 *
 * To send data on the WebSocket, use the [send] method.
 *
 *     if (webSocket != null && webSocket.readyState == WebSocket.OPEN) {
 *       webSocket.send(data);
 *     } else {
 *       print('WebSocket not connected, message $data not sent');
 *     }
 *
 * To receive data on the WebSocket, register a listener for message events.
 *
 *     webSocket.onMessage.listen((MessageEvent e) {
 *       receivedData(e.data);
 *     });
 *
 * The message event handler receives a [MessageEvent] object
 * as its sole argument.
 * You can also define open, close, and error handlers,
 * as specified by [WebSocketEvents].
 *
 * For more information, see the
 * [WebSockets](http://www.dartlang.org/docs/library-tour/#html-websockets)
 * section of the library tour and
 * [Introducing WebSockets](http://www.html5rocks.com/en/tutorials/websockets/basics/),
 * an HTML5Rocks.com tutorial.
 */
@DomName('WebSocket')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
class WebSocket extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory WebSocket._() { throw new UnsupportedError("Not supported"); }

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

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

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [WebSocket].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('WebSocket.messageEvent')
  @DocsEditable()
  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');

  /**
   * Static factory designed to expose `open` events to event
   * handlers that are not necessarily instances of [WebSocket].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('WebSocket.openEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> openEvent = const EventStreamProvider<Event>('open');

  @DomName('WebSocket.WebSocket')
  @DocsEditable()
  factory WebSocket(String url, [protocol_OR_protocols]) {
    if ((url is String || url == null) && protocol_OR_protocols == null) {
      return _blink.BlinkWebSocket.instance.constructorCallback_1_(url);
    }
    if ((protocol_OR_protocols is String || protocol_OR_protocols == null) && (url is String || url == null)) {
      return _blink.BlinkWebSocket.instance.constructorCallback_2_(url, protocol_OR_protocols);
    }
    if ((protocol_OR_protocols is List<String> || protocol_OR_protocols == null) && (url is String || url == null)) {
      return _blink.BlinkWebSocket.instance.constructorCallback_2_(url, protocol_OR_protocols);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  /// Checks if this type is supported on the current platform.
  static bool get supported => true;

  @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 get binaryType => _blink.BlinkWebSocket.instance.binaryType_Getter_(this);

  @DomName('WebSocket.binaryType')
  @DocsEditable()
  void set binaryType(String value) => _blink.BlinkWebSocket.instance.binaryType_Setter_(this, value);

  @DomName('WebSocket.bufferedAmount')
  @DocsEditable()
  int get bufferedAmount => _blink.BlinkWebSocket.instance.bufferedAmount_Getter_(this);

  @DomName('WebSocket.extensions')
  @DocsEditable()
  String get extensions => _blink.BlinkWebSocket.instance.extensions_Getter_(this);

  @DomName('WebSocket.protocol')
  @DocsEditable()
  String get protocol => _blink.BlinkWebSocket.instance.protocol_Getter_(this);

  @DomName('WebSocket.readyState')
  @DocsEditable()
  int get readyState => _blink.BlinkWebSocket.instance.readyState_Getter_(this);

  @DomName('WebSocket.url')
  @DocsEditable()
  String get url => _blink.BlinkWebSocket.instance.url_Getter_(this);

  void close([int code, String reason]) {
    if (reason != null) {
      _blink.BlinkWebSocket.instance.close_Callback_2_(this, code, reason);
      return;
    }
    if (code != null) {
      _blink.BlinkWebSocket.instance.close_Callback_1_(this, code);
      return;
    }
    _blink.BlinkWebSocket.instance.close_Callback_0_(this);
    return;
  }

  void send(data) {
    if ((data is String || data == null)) {
      _blink.BlinkWebSocket.instance.send_Callback_1_(this, data);
      return;
    }
    if ((data is Blob || data == null)) {
      _blink.BlinkWebSocket.instance.send_Callback_1_(this, data);
      return;
    }
    if ((data is TypedData || data == null)) {
      _blink.BlinkWebSocket.instance.send_Callback_1_(this, data);
      return;
    }
    if ((data is ByteBuffer || data == null)) {
      _blink.BlinkWebSocket.instance.send_Callback_1_(this, data);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('WebSocket.sendBlob')
  @DocsEditable()
  void sendBlob(Blob data) => _blink.BlinkWebSocket.instance.send_Callback_1_(this, data);

  @DomName('WebSocket.sendByteBuffer')
  @DocsEditable()
  void sendByteBuffer(ByteBuffer data) => _blink.BlinkWebSocket.instance.send_Callback_1_(this, data);

  @DomName('WebSocket.sendString')
  @DocsEditable()
  void sendString(String data) => _blink.BlinkWebSocket.instance.send_Callback_1_(this, data);

  @DomName('WebSocket.sendTypedData')
  @DocsEditable()
  void sendTypedData(TypedData data) => _blink.BlinkWebSocket.instance.send_Callback_1_(this, data);

  /// Stream of `close` events handled by this [WebSocket].
  @DomName('WebSocket.onclose')
  @DocsEditable()
  Stream<CloseEvent> get onClose => closeEvent.forTarget(this);

  /// Stream of `error` events handled by this [WebSocket].
  @DomName('WebSocket.onerror')
  @DocsEditable()
  Stream<Event> get onError => errorEvent.forTarget(this);

  /// Stream of `message` events handled by this [WebSocket].
  @DomName('WebSocket.onmessage')
  @DocsEditable()
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  /// Stream of `open` events handled by this [WebSocket].
  @DomName('WebSocket.onopen')
  @DocsEditable()
  Stream<Event> get onOpen => openEvent.forTarget(this);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('WheelEvent')
class WheelEvent extends MouseEvent {

  factory WheelEvent(String type,
      {Window view, int deltaX: 0, int deltaY: 0,
      int detail: 0, int screenX: 0, int screenY: 0, int clientX: 0,
      int clientY: 0, int button: 0, bool canBubble: true,
      bool cancelable: true, bool ctrlKey: false, bool altKey: false,
      bool shiftKey: false, bool metaKey: false, EventTarget relatedTarget}) {
    var options = {
      'view': view,
      'deltaX': deltaX,
      'deltaY': deltaY,
      '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,
    };
    return _blink.BlinkWheelEvent.constructorCallback_2(type, options);
  }

  // To suppress missing implicit constructor warnings.
  factory WheelEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('WheelEvent.DOM_DELTA_LINE')
  @DocsEditable()
  static const int DOM_DELTA_LINE = 0x01;

  @DomName('WheelEvent.DOM_DELTA_PAGE')
  @DocsEditable()
  static const int DOM_DELTA_PAGE = 0x02;

  @DomName('WheelEvent.DOM_DELTA_PIXEL')
  @DocsEditable()
  static const int DOM_DELTA_PIXEL = 0x00;

  @DomName('WheelEvent.deltaMode')
  @DocsEditable()
  int get deltaMode => _blink.BlinkWheelEvent.instance.deltaMode_Getter_(this);

  @DomName('WheelEvent.deltaX')
  @DocsEditable()
  @Experimental() // untriaged
  double get _deltaX => _blink.BlinkWheelEvent.instance.deltaX_Getter_(this);

  @DomName('WheelEvent.deltaY')
  @DocsEditable()
  @Experimental() // untriaged
  double get _deltaY => _blink.BlinkWheelEvent.instance.deltaY_Getter_(this);

  @DomName('WheelEvent.deltaZ')
  @DocsEditable()
  @Experimental() // untriaged
  double get deltaZ => _blink.BlinkWheelEvent.instance.deltaZ_Getter_(this);

  @DomName('WheelEvent.wheelDeltaX')
  @DocsEditable()
  @Experimental() // non-standard
  int get wheelDeltaX => _blink.BlinkWheelEvent.instance.wheelDeltaX_Getter_(this);

  @DomName('WheelEvent.wheelDeltaY')
  @DocsEditable()
  @Experimental() // non-standard
  int get wheelDeltaY => _blink.BlinkWheelEvent.instance.wheelDeltaY_Getter_(this);


  /**
   * 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 => _deltaX;

  /**
   * 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 => _deltaY;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
/**
 * Top-level container for the current browser tab or window.
 *
 * In a web browser, each window has a [Window] object, but within the context
 * of a script, this object represents only the current window.
 * Each other window, tab, and iframe has its own [Window] object.
 *
 * Each window contains a [Document] object, which contains all of the window's
 * content.
 *
 * Use the top-level `window` object to access the current window.
 * For example:
 *
 *     // Draw a scene when the window repaints.
 *     drawScene(num delta) {...}
 *     window.animationFrame.then(drawScene);.
 *
 *     // Write to the console.
 *     window.console.log('Jinkies!');
 *     window.console.error('Jeepers!');
 *
 * **Note:** This class represents only the current window, while [WindowBase]
 * is a representation of any window, including other tabs, windows, and frames.
 *
 * ## See also
 *
 * * [WindowBase]
 *
 * ## Other resources
 *
 * * [DOM Window](https://developer.mozilla.org/en-US/docs/DOM/window) from MDN.
 * * [Window](http://www.w3.org/TR/Window/) from the W3C.
 */
@DomName('Window')
class Window extends EventTarget implements WindowEventHandlers, WindowBase, GlobalEventHandlers, _WindowTimers, WindowBase64 {

  /**
   * 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;
  }

  /**
   * Called to draw an animation frame and then request the window to repaint
   * after [callback] has finished (creating the animation).
   *
   * Use this method only if you need to later call [cancelAnimationFrame]. If
   * not, the preferred Dart idiom is to set animation frames by calling
   * [animationFrame], which returns a Future.
   *
   * Returns a non-zero valued integer to represent the request id for this
   * request. This value only needs to be saved if you intend to call
   * [cancelAnimationFrame] so you can specify the particular animation to
   * cancel.
   *
   * Note: The supplied [callback] needs to call [requestAnimationFrame] again
   * for the animation to continue.
   */
  @DomName('Window.requestAnimationFrame')
  int requestAnimationFrame(RequestAnimationFrameCallback callback) {
    return _requestAnimationFrame(_wrapZone(callback));
  }

  /**
   * 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;

  /**
   * Entrypoint for CSS-related functions.
   *
   * ## Other resources
   *
   * * [The CSS interface](http://dev.w3.org/csswg/css-conditional/#the-css-interface) from W3C.
   */
  @DomName('Window.CSS')
  @DocsEditable()
  Css get css => _blink.BlinkWindow.instance.CSS_Getter_(this);

  /**
   * The application cache for this window.
   *
   * ## Other resources
   *
   * * [A beginner's guide to using the application cache]
   * (http://www.html5rocks.com/en/tutorials/appcache/beginner) from HTML5Rocks.
   * * [Application cache API]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html#application-cache-api)
   * from WHATWG.
   */
  @DomName('Window.applicationCache')
  @DocsEditable()
  ApplicationCache get applicationCache => _blink.BlinkWindow.instance.applicationCache_Getter_(this);

  @DomName('Window.closed')
  @DocsEditable()
  bool get closed => _blink.BlinkWindow.instance.closed_Getter_(this);

  @DomName('Window.console')
  @DocsEditable()
  Console get console => _blink.BlinkWindow.instance.console_Getter_(this);

  /**
   * 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()
  Crypto get crypto => _blink.BlinkWindow.instance.crypto_Getter_(this);

  /// *Deprecated*.
  @DomName('Window.defaultStatus')
  @DocsEditable()
  @Experimental() // non-standard
  String get defaultStatus => _blink.BlinkWindow.instance.defaultStatus_Getter_(this);

  /// *Deprecated*.
  @DomName('Window.defaultStatus')
  @DocsEditable()
  @Experimental() // non-standard
  void set defaultStatus(String value) => _blink.BlinkWindow.instance.defaultStatus_Setter_(this, value);

  /// *Deprecated*.
  @DomName('Window.defaultstatus')
  @DocsEditable()
  @Experimental() // non-standard
  String get defaultstatus => _blink.BlinkWindow.instance.defaultstatus_Getter_(this);

  /// *Deprecated*.
  @DomName('Window.defaultstatus')
  @DocsEditable()
  @Experimental() // non-standard
  void set defaultstatus(String value) => _blink.BlinkWindow.instance.defaultstatus_Setter_(this, value);

  /**
   * 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
  double get devicePixelRatio => _blink.BlinkWindow.instance.devicePixelRatio_Getter_(this);

  @DomName('Window.document')
  @DocsEditable()
  Document get document => _blink.BlinkWindow.instance.document_Getter_(this);

  /**
   * The current session history for this window's newest document.
   *
   * ## Other resources
   *
   * * [Loading web pages]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html)
   * from WHATWG.
   */
  @DomName('Window.history')
  @DocsEditable()
  History get history => _blink.BlinkWindow.instance.history_Getter_(this);

  @DomName('Window.indexedDB')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX, '15')
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @Experimental()
  IdbFactory get indexedDB => _blink.BlinkWindow.instance.indexedDB_Getter_(this);

  /**
   * 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()
  int get innerHeight => _blink.BlinkWindow.instance.innerHeight_Getter_(this);

  /**
   * 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()
  int get innerWidth => _blink.BlinkWindow.instance.innerWidth_Getter_(this);

  /**
   * 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()
  Storage get localStorage => _blink.BlinkWindow.instance.localStorage_Getter_(this);

  @DomName('Window.location')
  @DocsEditable()
  Location get location => _blink.BlinkWindow.instance.location_Getter_(this);

  /**
   * This window's location bar, which displays the URL.
   *
   * ## Other resources
   *
   * * [Browser interface elements]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
   * from WHATWG.
   */
  @DomName('Window.locationbar')
  @DocsEditable()
  BarProp get locationbar => _blink.BlinkWindow.instance.locationbar_Getter_(this);

  /**
   * This window's menu bar, which displays menu commands.
   *
   * ## Other resources
   *
   * * [Browser interface elements]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
   * from WHATWG.
   */
  @DomName('Window.menubar')
  @DocsEditable()
  BarProp get menubar => _blink.BlinkWindow.instance.menubar_Getter_(this);

  /**
   * 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 get name => _blink.BlinkWindow.instance.name_Getter_(this);

  /**
   * 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()
  void set name(String value) => _blink.BlinkWindow.instance.name_Setter_(this, value);

  /**
   * The user agent accessing this window.
   *
   * ## Other resources
   *
   * * [The navigator object]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#the-navigator-object)
   * from WHATWG.
   */
  @DomName('Window.navigator')
  @DocsEditable()
  Navigator get navigator => _blink.BlinkWindow.instance.navigator_Getter_(this);

  /**
   * 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
  bool get offscreenBuffering => _blink.BlinkWindow.instance.offscreenBuffering_Getter_(this);

  @DomName('Window.opener')
  @DocsEditable()
  WindowBase get opener => _blink.BlinkWindow.instance.opener_Getter_(this);

  @DomName('Window.opener')
  @DocsEditable()
  void set opener(Window value) => _blink.BlinkWindow.instance.opener_Setter_(this, value);

  @DomName('Window.orientation')
  @DocsEditable()
  @Experimental() // untriaged
  int get orientation => _blink.BlinkWindow.instance.orientation_Getter_(this);

  /**
   * 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()
  int get outerHeight => _blink.BlinkWindow.instance.outerHeight_Getter_(this);

  /**
   * 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()
  int get outerWidth => _blink.BlinkWindow.instance.outerWidth_Getter_(this);

  /**
   * 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()
  int get pageXOffset => _blink.BlinkWindow.instance.pageXOffset_Getter_(this);

  /**
   * 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()
  int get pageYOffset => _blink.BlinkWindow.instance.pageYOffset_Getter_(this);

  @DomName('Window.parent')
  @DocsEditable()
  WindowBase get parent => _blink.BlinkWindow.instance.parent_Getter_(this);

  /**
   * 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)
  Performance get performance => _blink.BlinkWindow.instance.performance_Getter_(this);

  /**
   * 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()
  Screen get screen => _blink.BlinkWindow.instance.screen_Getter_(this);

  /**
   * 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()
  int get screenLeft => _blink.BlinkWindow.instance.screenLeft_Getter_(this);

  /**
   * 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()
  int get screenTop => _blink.BlinkWindow.instance.screenTop_Getter_(this);

  /**
   * 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()
  int get screenX => _blink.BlinkWindow.instance.screenX_Getter_(this);

  /**
   * 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()
  int get screenY => _blink.BlinkWindow.instance.screenY_Getter_(this);

  @DomName('Window.scrollX')
  @DocsEditable()
  int get scrollX => _blink.BlinkWindow.instance.scrollX_Getter_(this);

  @DomName('Window.scrollY')
  @DocsEditable()
  int get scrollY => _blink.BlinkWindow.instance.scrollY_Getter_(this);

  /**
   * This window's scroll bars.
   *
   * ## Other resources
   *
   * * [Browser interface elements]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
   * from WHATWG.
   */
  @DomName('Window.scrollbars')
  @DocsEditable()
  BarProp get scrollbars => _blink.BlinkWindow.instance.scrollbars_Getter_(this);

  /**
   * 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 => _blink.BlinkWindow.instance.self_Getter_(this);

  /**
   * 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()
  Storage get sessionStorage => _blink.BlinkWindow.instance.sessionStorage_Getter_(this);

  /**
   * 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()
  SpeechSynthesis get speechSynthesis => _blink.BlinkWindow.instance.speechSynthesis_Getter_(this);

  /// *Deprecated*.
  @DomName('Window.status')
  @DocsEditable()
  String get status => _blink.BlinkWindow.instance.status_Getter_(this);

  /// *Deprecated*.
  @DomName('Window.status')
  @DocsEditable()
  void set status(String value) => _blink.BlinkWindow.instance.status_Setter_(this, value);

  /**
   * This window's status bar.
   *
   * ## Other resources
   *
   * * [Browser interface elements]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
   * from WHATWG.
   */
  @DomName('Window.statusbar')
  @DocsEditable()
  BarProp get statusbar => _blink.BlinkWindow.instance.statusbar_Getter_(this);

  /**
   * Access to CSS media queries.
   *
   * ## Other resources
   *
   * * [StyleMedia class reference]
   * (https://developer.apple.com/library/safari/documentation/SafariDOMAdditions/Reference/StyleMedia/StyleMedia/StyleMedia.html)
   * from Safari Developer Library.
   */
  @DomName('Window.styleMedia')
  @DocsEditable()
  // http://developer.apple.com/library/safari/#documentation/SafariDOMAdditions/Reference/StyleMedia/StyleMedia/StyleMedia.html
  @Experimental() // nonstandard
  StyleMedia get styleMedia => _blink.BlinkWindow.instance.styleMedia_Getter_(this);

  /**
   * This window's tool bar.
   *
   * ## Other resources
   *
   * * [Browser interface elements]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
   * from WHATWG.
   */
  @DomName('Window.toolbar')
  @DocsEditable()
  BarProp get toolbar => _blink.BlinkWindow.instance.toolbar_Getter_(this);

  @DomName('Window.top')
  @DocsEditable()
  WindowBase get top => _blink.BlinkWindow.instance.top_Getter_(this);

  /**
   * 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 => _blink.BlinkWindow.instance.window_Getter_(this);

  WindowBase __getter__(index_OR_name) {
    if ((index_OR_name is int)) {
      return _blink.BlinkWindow.instance.$__getter___Callback_1_(this, index_OR_name);
    }
    if ((index_OR_name is String)) {
      return _blink.BlinkWindow.instance.$__getter___Callback_1_(this, index_OR_name);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  void alert([String message]) {
    if (message != null) {
      _blink.BlinkWindow.instance.alert_Callback_1_(this, message);
      return;
    }
    _blink.BlinkWindow.instance.alert_Callback_0_(this);
    return;
  }

  @DomName('Window.cancelAnimationFrame')
  @DocsEditable()
  void cancelAnimationFrame(int id) => _blink.BlinkWindow.instance.cancelAnimationFrame_Callback_1_(this, id);

  @DomName('Window.close')
  @DocsEditable()
  void close() => _blink.BlinkWindow.instance.close_Callback_0_(this);

  bool confirm([String message]) {
    if (message != null) {
      return _blink.BlinkWindow.instance.confirm_Callback_1_(this, message);
    }
    return _blink.BlinkWindow.instance.confirm_Callback_0_(this);
  }

  /**
   * 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) => _blink.BlinkWindow.instance.find_Callback_7_(this, string, caseSensitive, backwards, wrap, wholeWord, searchInFrames, showDialog);

  @DomName('Window.getComputedStyle')
  @DocsEditable()
  CssStyleDeclaration _getComputedStyle(Element element, String pseudoElement) => _blink.BlinkWindow.instance.getComputedStyle_Callback_2_(this, element, pseudoElement);

  /**
   * Returns all CSS rules that apply to the element's pseudo-element.
   */
  @DomName('Window.getMatchedCSSRules')
  @DocsEditable()
  @Experimental() // non-standard
  List<CssRule> getMatchedCssRules(Element element, String pseudoElement) => _blink.BlinkWindow.instance.getMatchedCSSRules_Callback_2_(this, element, pseudoElement);

  /**
   * 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() => _blink.BlinkWindow.instance.getSelection_Callback_0_(this);

  /**
   * 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) => _blink.BlinkWindow.instance.matchMedia_Callback_1_(this, query);

  /**
   * Moves this window.
   *
   * x and y can be negative.
   *
   * ## Other resources
   *
   * * [Window.moveBy]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.moveBy) from MDN.
   * * [Window.moveBy]
   * (http://dev.w3.org/csswg/cssom-view/#dom-window-moveby) from W3C.
   */
  @DomName('Window.moveBy')
  @DocsEditable()
  void moveBy(num x, num y) => _blink.BlinkWindow.instance.moveBy_Callback_2_(this, x, y);

  @DomName('Window.moveTo')
  @DocsEditable()
  void _moveTo(num x, num y) => _blink.BlinkWindow.instance.moveTo_Callback_2_(this, x, y);

  @DomName('Window.open')
  @DocsEditable()
  WindowBase open(String url, String name, [String options]) => _blink.BlinkWindow.instance.open_Callback_3_(this, url, name, options);

  SqlDatabase openDatabase(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) {
    if (creationCallback != null) {
      return _blink.BlinkWindow.instance.openDatabase_Callback_5_(this, name, version, displayName, estimatedSize, creationCallback);
    }
    return _blink.BlinkWindow.instance.openDatabase_Callback_4_(this, name, version, displayName, estimatedSize);
  }

  @DomName('Window.postMessage')
  @DocsEditable()
  void postMessage(/*SerializedScriptValue*/ message, String targetOrigin, [List<MessagePort> transfer]) => _blink.BlinkWindow.instance.postMessage_Callback_3_(this, message, targetOrigin, transfer);

  /**
   * 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() => _blink.BlinkWindow.instance.print_Callback_0_(this);

  @DomName('Window.requestAnimationFrame')
  @DocsEditable()
  int _requestAnimationFrame(RequestAnimationFrameCallback callback) => _blink.BlinkWindow.instance.requestAnimationFrame_Callback_1_(this, callback);

  /**
   * Resizes this window by an offset.
   *
   * ## Other resources
   *
   * * [Window resizeBy] (http://docs.webplatform.org/wiki/dom/methods/resizeBy)
   * from WebPlatform.org.
   */
  @DomName('Window.resizeBy')
  @DocsEditable()
  void resizeBy(num x, num y) => _blink.BlinkWindow.instance.resizeBy_Callback_2_(this, x, y);

  /**
   * Resizes this window to a specific width and height.
   *
   * ## Other resources
   *
   * * [Window resizeTo] (http://docs.webplatform.org/wiki/dom/methods/resizeTo)
   * from WebPlatform.org.
   */
  @DomName('Window.resizeTo')
  @DocsEditable()
  void resizeTo(num width, num height) => _blink.BlinkWindow.instance.resizeTo_Callback_2_(this, width, height);

  void scroll(int x, int y, [Map scrollOptions]) {
    if (scrollOptions != null) {
      _blink.BlinkWindow.instance.scroll_Callback_3_(this, x, y, scrollOptions);
      return;
    }
    _blink.BlinkWindow.instance.scroll_Callback_2_(this, x, y);
    return;
  }

  void scrollBy(int x, int y, [Map scrollOptions]) {
    if (scrollOptions != null) {
      _blink.BlinkWindow.instance.scrollBy_Callback_3_(this, x, y, scrollOptions);
      return;
    }
    _blink.BlinkWindow.instance.scrollBy_Callback_2_(this, x, y);
    return;
  }

  void scrollTo(int x, int y, [Map scrollOptions]) {
    if (scrollOptions != null) {
      _blink.BlinkWindow.instance.scrollTo_Callback_3_(this, x, y, scrollOptions);
      return;
    }
    _blink.BlinkWindow.instance.scrollTo_Callback_2_(this, x, y);
    return;
  }

  /**
   * Opens a new page as a modal dialog.
   *
   * ## Other resources
   *
   * * [Dialogs implemented using separate documents]
   * (http://www.w3.org/html/wg/drafts/html/master/webappapis.html#dialogs-implemented-using-separate-documents)
   * from W3C.
   */
  @DomName('Window.showModalDialog')
  @DocsEditable()
  Object showModalDialog(String url, [Object dialogArgs, String featureArgs]) => _blink.BlinkWindow.instance.showModalDialog_Callback_3_(this, url, dialogArgs, featureArgs);

  /**
   * 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() => _blink.BlinkWindow.instance.stop_Callback_0_(this);

  void __requestFileSystem(int type, int size, _FileSystemCallback successCallback, [_ErrorCallback errorCallback]) {
    if (errorCallback != null) {
      _blink.BlinkWindow.instance.webkitRequestFileSystem_Callback_4_(this, type, size, successCallback, errorCallback);
      return;
    }
    _blink.BlinkWindow.instance.webkitRequestFileSystem_Callback_3_(this, type, size, successCallback);
    return;
  }

  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;
  }

  void _resolveLocalFileSystemUrl(String url, _EntryCallback successCallback, [_ErrorCallback errorCallback]) {
    if (errorCallback != null) {
      _blink.BlinkWindow.instance.webkitResolveLocalFileSystemURL_Callback_3_(this, url, successCallback, errorCallback);
      return;
    }
    _blink.BlinkWindow.instance.webkitResolveLocalFileSystemURL_Callback_2_(this, url, successCallback);
    return;
  }

  Future<Entry> resolveLocalFileSystemUrl(String url) {
    var completer = new Completer<Entry>();
    _resolveLocalFileSystemUrl(url,
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  @DomName('Window.atob')
  @DocsEditable()
  String atob(String string) => _blink.BlinkWindow.instance.atob_Callback_1_(this, string);

  @DomName('Window.btoa')
  @DocsEditable()
  String btoa(String string) => _blink.BlinkWindow.instance.btoa_Callback_1_(this, string);

  @DomName('Window.clearInterval')
  @DocsEditable()
  void _clearInterval(int handle) => _blink.BlinkWindow.instance.clearInterval_Callback_1_(this, handle);

  @DomName('Window.clearTimeout')
  @DocsEditable()
  void _clearTimeout(int handle) => _blink.BlinkWindow.instance.clearTimeout_Callback_1_(this, handle);

  @DomName('Window.setInterval')
  @DocsEditable()
  int _setInterval(Object handler, int timeout) => _blink.BlinkWindow.instance.setInterval_Callback_2_(this, handler, timeout);

  @DomName('Window.setTimeout')
  @DocsEditable()
  int _setTimeout(Object handler, int timeout) => _blink.BlinkWindow.instance.setTimeout_Callback_2_(this, handler, timeout);

  /// 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);
  }

}


class _BeforeUnloadEventStreamProvider implements
    EventStreamProvider<BeforeUnloadEvent> {
  final String _eventType;

  const _BeforeUnloadEventStreamProvider(this._eventType);

  Stream<BeforeUnloadEvent> forTarget(EventTarget e, {bool useCapture: false}) {
    var stream = new _EventStream(e, _eventType, useCapture);
    return stream;
  }

  String getEventType(EventTarget target) {
    return _eventType;
  }

  ElementStream<BeforeUnloadEvent> forElement(Element e, {bool useCapture: false}) {
    return new _ElementEventStreamImpl(e, _eventType, useCapture);
  }

  ElementStream<BeforeUnloadEvent> _forElementList(ElementList e,
      {bool useCapture: false}) {
    return new _ElementListEventStreamImpl(e, _eventType, useCapture);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('WindowBase64')
@Experimental() // untriaged
abstract class WindowBase64 extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory WindowBase64._() { throw new UnsupportedError("Not supported"); }

  @DomName('WindowBase64.atob')
  @DocsEditable()
  @Experimental() // untriaged
  String atob(String string);

  @DomName('WindowBase64.btoa')
  @DocsEditable()
  @Experimental() // untriaged
  String btoa(String string);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('WindowEventHandlers')
@Experimental() // untriaged
abstract class WindowEventHandlers extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory WindowEventHandlers._() { throw new UnsupportedError("Not supported"); }

  @DomName('WindowEventHandlers.hashchangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> hashChangeEvent = const EventStreamProvider<Event>('hashchange');

  @DomName('WindowEventHandlers.messageEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');

  @DomName('WindowEventHandlers.offlineEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> offlineEvent = const EventStreamProvider<Event>('offline');

  @DomName('WindowEventHandlers.onlineEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> onlineEvent = const EventStreamProvider<Event>('online');

  @DomName('WindowEventHandlers.popstateEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<PopStateEvent> popStateEvent = const EventStreamProvider<PopStateEvent>('popstate');

  @DomName('WindowEventHandlers.storageEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<StorageEvent> storageEvent = const EventStreamProvider<StorageEvent>('storage');

  @DomName('WindowEventHandlers.unloadEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> unloadEvent = const EventStreamProvider<Event>('unload');

  @DomName('WindowEventHandlers.onhashchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onHashChange => hashChangeEvent.forTarget(this);

  @DomName('WindowEventHandlers.onmessage')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  @DomName('WindowEventHandlers.onoffline')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onOffline => offlineEvent.forTarget(this);

  @DomName('WindowEventHandlers.ononline')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onOnline => onlineEvent.forTarget(this);

  @DomName('WindowEventHandlers.onpopstate')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<PopStateEvent> get onPopState => popStateEvent.forTarget(this);

  @DomName('WindowEventHandlers.onstorage')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<StorageEvent> get onStorage => storageEvent.forTarget(this);

  @DomName('WindowEventHandlers.onunload')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onUnload => unloadEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('Worker')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
// http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#worker
@Experimental() // stable
class Worker extends EventTarget implements AbstractWorker {
  // 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 _blink.BlinkWorker.instance.constructorCallback_1_(scriptUrl);
  }

  /// Checks if this type is supported on the current platform.
  static bool get supported => true;

  @DomName('Worker.postMessage')
  @DocsEditable()
  void postMessage(/*SerializedScriptValue*/ message, [List<MessagePort> transfer]) => _blink.BlinkWorker.instance.postMessage_Callback_2_(this, message, transfer);

  @DomName('Worker.terminate')
  @DocsEditable()
  void terminate() => _blink.BlinkWorker.instance.terminate_Callback_0_(this);

  /// 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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('WorkerConsole')
@Experimental() // untriaged
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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('WorkerGlobalScope')
@Experimental() // untriaged
class WorkerGlobalScope extends EventTarget implements _WindowTimers, WindowBase64 {
  // To suppress missing implicit constructor warnings.
  factory WorkerGlobalScope._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [WorkerGlobalScope].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('WorkerGlobalScope.errorEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  @DomName('WorkerGlobalScope.PERSISTENT')
  @DocsEditable()
  @Experimental() // untriaged
  static const int PERSISTENT = 1;

  @DomName('WorkerGlobalScope.TEMPORARY')
  @DocsEditable()
  @Experimental() // untriaged
  static const int TEMPORARY = 0;

  @DomName('WorkerGlobalScope.console')
  @DocsEditable()
  @Experimental() // untriaged
  WorkerConsole get console => _blink.BlinkWorkerGlobalScope.instance.console_Getter_(this);

  @DomName('WorkerGlobalScope.crypto')
  @DocsEditable()
  @Experimental() // untriaged
  Crypto get crypto => _blink.BlinkWorkerGlobalScope.instance.crypto_Getter_(this);

  @DomName('WorkerGlobalScope.indexedDB')
  @DocsEditable()
  @Experimental() // untriaged
  IdbFactory get indexedDB => _blink.BlinkWorkerGlobalScope.instance.indexedDB_Getter_(this);

  @DomName('WorkerGlobalScope.location')
  @DocsEditable()
  @Experimental() // untriaged
  _WorkerLocation get location => _blink.BlinkWorkerGlobalScope.instance.location_Getter_(this);

  @DomName('WorkerGlobalScope.navigator')
  @DocsEditable()
  @Experimental() // untriaged
  _WorkerNavigator get navigator => _blink.BlinkWorkerGlobalScope.instance.navigator_Getter_(this);

  @DomName('WorkerGlobalScope.performance')
  @DocsEditable()
  @Experimental() // untriaged
  WorkerPerformance get performance => _blink.BlinkWorkerGlobalScope.instance.performance_Getter_(this);

  @DomName('WorkerGlobalScope.self')
  @DocsEditable()
  @Experimental() // untriaged
  WorkerGlobalScope get self => _blink.BlinkWorkerGlobalScope.instance.self_Getter_(this);

  @DomName('WorkerGlobalScope.close')
  @DocsEditable()
  @Experimental() // untriaged
  void close() => _blink.BlinkWorkerGlobalScope.instance.close_Callback_0_(this);

  @DomName('WorkerGlobalScope.importScripts')
  @DocsEditable()
  @Experimental() // untriaged
  void importScripts(String urls) => _blink.BlinkWorkerGlobalScope.instance.importScripts_Callback_1_(this, urls);

  SqlDatabase openDatabase(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) {
    if (creationCallback != null) {
      return _blink.BlinkWorkerGlobalScope.instance.openDatabase_Callback_5_(this, name, version, displayName, estimatedSize, creationCallback);
    }
    return _blink.BlinkWorkerGlobalScope.instance.openDatabase_Callback_4_(this, name, version, displayName, estimatedSize);
  }

  _DatabaseSync openDatabaseSync(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) {
    if (creationCallback != null) {
      return _blink.BlinkWorkerGlobalScope.instance.openDatabaseSync_Callback_5_(this, name, version, displayName, estimatedSize, creationCallback);
    }
    return _blink.BlinkWorkerGlobalScope.instance.openDatabaseSync_Callback_4_(this, name, version, displayName, estimatedSize);
  }

  void _webkitRequestFileSystem(int type, int size, [_FileSystemCallback successCallback, _ErrorCallback errorCallback]) {
    if (errorCallback != null) {
      _blink.BlinkWorkerGlobalScope.instance.webkitRequestFileSystem_Callback_4_(this, type, size, successCallback, errorCallback);
      return;
    }
    if (successCallback != null) {
      _blink.BlinkWorkerGlobalScope.instance.webkitRequestFileSystem_Callback_3_(this, type, size, successCallback);
      return;
    }
    _blink.BlinkWorkerGlobalScope.instance.webkitRequestFileSystem_Callback_2_(this, type, size);
    return;
  }

  Future<FileSystem> webkitRequestFileSystem(int type, int size) {
    var completer = new Completer<FileSystem>();
    _webkitRequestFileSystem(type, size,
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  @DomName('WorkerGlobalScope.webkitRequestFileSystemSync')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // untriaged
  _DOMFileSystemSync requestFileSystemSync(int type, int size) => _blink.BlinkWorkerGlobalScope.instance.webkitRequestFileSystemSync_Callback_2_(this, type, size);

  @DomName('WorkerGlobalScope.webkitResolveLocalFileSystemSyncURL')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // untriaged
  _EntrySync resolveLocalFileSystemSyncUrl(String url) => _blink.BlinkWorkerGlobalScope.instance.webkitResolveLocalFileSystemSyncURL_Callback_1_(this, url);

  void _webkitResolveLocalFileSystemUrl(String url, _EntryCallback successCallback, [_ErrorCallback errorCallback]) {
    if (errorCallback != null) {
      _blink.BlinkWorkerGlobalScope.instance.webkitResolveLocalFileSystemURL_Callback_3_(this, url, successCallback, errorCallback);
      return;
    }
    _blink.BlinkWorkerGlobalScope.instance.webkitResolveLocalFileSystemURL_Callback_2_(this, url, successCallback);
    return;
  }

  Future<Entry> webkitResolveLocalFileSystemUrl(String url) {
    var completer = new Completer<Entry>();
    _webkitResolveLocalFileSystemUrl(url,
        (value) { completer.complete(value); },
        (error) { completer.completeError(error); });
    return completer.future;
  }

  @DomName('WorkerGlobalScope.atob')
  @DocsEditable()
  @Experimental() // untriaged
  String atob(String string) => _blink.BlinkWorkerGlobalScope.instance.atob_Callback_1_(this, string);

  @DomName('WorkerGlobalScope.btoa')
  @DocsEditable()
  @Experimental() // untriaged
  String btoa(String string) => _blink.BlinkWorkerGlobalScope.instance.btoa_Callback_1_(this, string);

  @DomName('WorkerGlobalScope.clearInterval')
  @DocsEditable()
  @Experimental() // untriaged
  void _clearInterval(int handle) => _blink.BlinkWorkerGlobalScope.instance.clearInterval_Callback_1_(this, handle);

  @DomName('WorkerGlobalScope.clearTimeout')
  @DocsEditable()
  @Experimental() // untriaged
  void _clearTimeout(int handle) => _blink.BlinkWorkerGlobalScope.instance.clearTimeout_Callback_1_(this, handle);

  @DomName('WorkerGlobalScope.setInterval')
  @DocsEditable()
  @Experimental() // untriaged
  int _setInterval(Object handler, int timeout) => _blink.BlinkWorkerGlobalScope.instance.setInterval_Callback_2_(this, handler, timeout);

  @DomName('WorkerGlobalScope.setTimeout')
  @DocsEditable()
  @Experimental() // untriaged
  int _setTimeout(Object handler, int timeout) => _blink.BlinkWorkerGlobalScope.instance.setTimeout_Callback_2_(this, handler, timeout);

  /// 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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('WorkerPerformance')
@Experimental() // untriaged
class WorkerPerformance extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory WorkerPerformance._() { throw new UnsupportedError("Not supported"); }

  @DomName('WorkerPerformance.memory')
  @DocsEditable()
  @Experimental() // untriaged
  MemoryInfo get memory => _blink.BlinkWorkerPerformance.instance.memory_Getter_(this);

  @DomName('WorkerPerformance.now')
  @DocsEditable()
  @Experimental() // untriaged
  double now() => _blink.BlinkWorkerPerformance.instance.now_Callback_0_(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.


@DocsEditable()
@DomName('XPathEvaluator')
// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathEvaluator
@deprecated // experimental
class XPathEvaluator extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory XPathEvaluator._() { throw new UnsupportedError("Not supported"); }

  @DomName('XPathEvaluator.XPathEvaluator')
  @DocsEditable()
  factory XPathEvaluator() {
    return _blink.BlinkXPathEvaluator.instance.constructorCallback_0_();
  }

  @DomName('XPathEvaluator.createExpression')
  @DocsEditable()
  XPathExpression createExpression(String expression, XPathNSResolver resolver) => _blink.BlinkXPathEvaluator.instance.createExpression_Callback_2_(this, expression, resolver);

  @DomName('XPathEvaluator.createNSResolver')
  @DocsEditable()
  XPathNSResolver createNSResolver(Node nodeResolver) => _blink.BlinkXPathEvaluator.instance.createNSResolver_Callback_1_(this, nodeResolver);

  @DomName('XPathEvaluator.evaluate')
  @DocsEditable()
  XPathResult evaluate(String expression, Node contextNode, XPathNSResolver resolver, int type, XPathResult inResult) => _blink.BlinkXPathEvaluator.instance.evaluate_Callback_5_(this, expression, contextNode, resolver, type, inResult);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


@DocsEditable()
@DomName('XPathExpression')
// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathExpression
@deprecated // experimental
class XPathExpression extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory XPathExpression._() { throw new UnsupportedError("Not supported"); }

  @DomName('XPathExpression.evaluate')
  @DocsEditable()
  XPathResult evaluate(Node contextNode, int type, XPathResult inResult) => _blink.BlinkXPathExpression.instance.evaluate_Callback_3_(this, contextNode, type, inResult);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


@DocsEditable()
@DomName('XPathNSResolver')
// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathNSResolver
@deprecated // experimental
class XPathNSResolver extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory XPathNSResolver._() { throw new UnsupportedError("Not supported"); }

  @DomName('XPathNSResolver.lookupNamespaceURI')
  @DocsEditable()
  String lookupNamespaceUri(String prefix) => _blink.BlinkXPathNSResolver.instance.lookupNamespaceURI_Callback_1_(this, 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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('XPathResult')
// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathResult
@deprecated // experimental
class XPathResult extends NativeFieldWrapperClass2 {
  // 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()
  bool get booleanValue => _blink.BlinkXPathResult.instance.booleanValue_Getter_(this);

  @DomName('XPathResult.invalidIteratorState')
  @DocsEditable()
  bool get invalidIteratorState => _blink.BlinkXPathResult.instance.invalidIteratorState_Getter_(this);

  @DomName('XPathResult.numberValue')
  @DocsEditable()
  double get numberValue => _blink.BlinkXPathResult.instance.numberValue_Getter_(this);

  @DomName('XPathResult.resultType')
  @DocsEditable()
  int get resultType => _blink.BlinkXPathResult.instance.resultType_Getter_(this);

  @DomName('XPathResult.singleNodeValue')
  @DocsEditable()
  Node get singleNodeValue => _blink.BlinkXPathResult.instance.singleNodeValue_Getter_(this);

  @DomName('XPathResult.snapshotLength')
  @DocsEditable()
  int get snapshotLength => _blink.BlinkXPathResult.instance.snapshotLength_Getter_(this);

  @DomName('XPathResult.stringValue')
  @DocsEditable()
  String get stringValue => _blink.BlinkXPathResult.instance.stringValue_Getter_(this);

  @DomName('XPathResult.iterateNext')
  @DocsEditable()
  Node iterateNext() => _blink.BlinkXPathResult.instance.iterateNext_Callback_0_(this);

  @DomName('XPathResult.snapshotItem')
  @DocsEditable()
  Node snapshotItem(int index) => _blink.BlinkXPathResult.instance.snapshotItem_Callback_1_(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.


@DocsEditable()
@DomName('XMLDocument')
@Experimental() // untriaged
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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('XMLSerializer')
// http://domparsing.spec.whatwg.org/#the-xmlserializer-interface
@deprecated // stable
class XmlSerializer extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory XmlSerializer._() { throw new UnsupportedError("Not supported"); }

  @DomName('XMLSerializer.XMLSerializer')
  @DocsEditable()
  factory XmlSerializer() {
    return _blink.BlinkXMLSerializer.instance.constructorCallback_0_();
  }

  @DomName('XMLSerializer.serializeToString')
  @DocsEditable()
  String serializeToString(Node node) => _blink.BlinkXMLSerializer.instance.serializeToString_Callback_1_(this, node);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


@DocsEditable()
@DomName('XSLTProcessor')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@deprecated // nonstandard
class XsltProcessor extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory XsltProcessor._() { throw new UnsupportedError("Not supported"); }

  @DomName('XSLTProcessor.XSLTProcessor')
  @DocsEditable()
  factory XsltProcessor() {
    return _blink.BlinkXSLTProcessor.instance.constructorCallback_0_();
  }

  /// Checks if this type is supported on the current platform.
  static bool get supported => true;

  @DomName('XSLTProcessor.clearParameters')
  @DocsEditable()
  void clearParameters() => _blink.BlinkXSLTProcessor.instance.clearParameters_Callback_0_(this);

  @DomName('XSLTProcessor.getParameter')
  @DocsEditable()
  String getParameter(String namespaceURI, String localName) => _blink.BlinkXSLTProcessor.instance.getParameter_Callback_2_(this, namespaceURI, localName);

  @DomName('XSLTProcessor.importStylesheet')
  @DocsEditable()
  void importStylesheet(Node stylesheet) => _blink.BlinkXSLTProcessor.instance.importStylesheet_Callback_1_(this, stylesheet);

  @DomName('XSLTProcessor.removeParameter')
  @DocsEditable()
  void removeParameter(String namespaceURI, String localName) => _blink.BlinkXSLTProcessor.instance.removeParameter_Callback_2_(this, namespaceURI, localName);

  @DomName('XSLTProcessor.reset')
  @DocsEditable()
  void reset() => _blink.BlinkXSLTProcessor.instance.reset_Callback_0_(this);

  @DomName('XSLTProcessor.setParameter')
  @DocsEditable()
  void setParameter(String namespaceURI, String localName, String value) => _blink.BlinkXSLTProcessor.instance.setParameter_Callback_3_(this, namespaceURI, localName, value);

  @DomName('XSLTProcessor.transformToDocument')
  @DocsEditable()
  Document transformToDocument(Node source) => _blink.BlinkXSLTProcessor.instance.transformToDocument_Callback_1_(this, source);

  @DomName('XSLTProcessor.transformToFragment')
  @DocsEditable()
  DocumentFragment transformToFragment(Node source, Document docVal) => _blink.BlinkXSLTProcessor.instance.transformToFragment_Callback_2_(this, source, docVal);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


@DocsEditable()
@DomName('Attr')
class _Attr extends Node {
  // To suppress missing implicit constructor warnings.
  factory _Attr._() { throw new UnsupportedError("Not supported"); }

  @DomName('Attr.localName')
  @DocsEditable()
  @Experimental() // untriaged
  String get _localName => _blink.BlinkAttr.instance.localName_Getter_(this);

  @DomName('Attr.name')
  @DocsEditable()
  String get name => _blink.BlinkAttr.instance.name_Getter_(this);

  @DomName('Attr.namespaceURI')
  @DocsEditable()
  @Experimental() // untriaged
  String get _namespaceUri => _blink.BlinkAttr.instance.namespaceURI_Getter_(this);

  @DomName('Attr.nodeValue')
  @DocsEditable()
  @Experimental() // untriaged
  String get nodeValue => _blink.BlinkAttr.instance.nodeValue_Getter_(this);

  @DomName('Attr.textContent')
  @DocsEditable()
  @Experimental() // untriaged
  String get text => _blink.BlinkAttr.instance.textContent_Getter_(this);

  @DomName('Attr.textContent')
  @DocsEditable()
  @Experimental() // untriaged
  void set text(String value) => _blink.BlinkAttr.instance.textContent_Setter_(this, value);

  @DomName('Attr.value')
  @DocsEditable()
  String get value => _blink.BlinkAttr.instance.value_Getter_(this);

  @DomName('Attr.value')
  @DocsEditable()
  void set value(String value) => _blink.BlinkAttr.instance.value_Setter_(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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('CSSPrimitiveValue')
// http://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface
@deprecated // deprecated
abstract class _CSSPrimitiveValue extends _CSSValue {
  // To suppress missing implicit constructor warnings.
  factory _CSSPrimitiveValue._() { throw new UnsupportedError("Not supported"); }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('CSSUnknownRule')
// http://dev.w3.org/csswg/cssom/#the-cssstylesheet-interface
@deprecated // deprecated
abstract class _CSSUnknownRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory _CSSUnknownRule._() { throw new UnsupportedError("Not supported"); }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('CSSValue')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
abstract class _CSSValue extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory _CSSValue._() { throw new UnsupportedError("Not supported"); }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('Cache')
@Experimental() // untriaged
abstract class _Cache extends NativeFieldWrapperClass2 {
  // 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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('CanvasPathMethods')
@Experimental() // untriaged
abstract class _CanvasPathMethods extends NativeFieldWrapperClass2 {
  // 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')
class _ClientRect extends NativeFieldWrapperClass2 implements Rectangle {

  // NOTE! All code below should be common with RectangleBase.
   String toString() {
    return 'Rectangle ($left, $top) $width x $height';
  }

  bool operator ==(other) {
    if (other is !Rectangle) return false;
    return left == other.left && top == other.top && width == other.width &&
        height == other.height;
  }

  int get hashCode => _JenkinsSmiHash.hash4(left.hashCode, top.hashCode,
      width.hashCode, height.hashCode);

  /**
   * Computes the intersection of `this` and [other].
   *
   * The intersection of two axis-aligned rectangles, if any, is always another
   * axis-aligned rectangle.
   *
   * Returns the intersection of this and `other`, or null if they don't
   * intersect.
   */
  Rectangle intersection(Rectangle other) {
    var x0 = max(left, other.left);
    var x1 = min(left + width, other.left + other.width);

    if (x0 <= x1) {
      var y0 = max(top, other.top);
      var y1 = min(top + height, other.top + other.height);

      if (y0 <= y1) {
        return new Rectangle(x0, y0, x1 - x0, y1 - y0);
      }
    }
    return null;
  }


  /**
   * Returns true if `this` intersects [other].
   */
  bool intersects(Rectangle<num> other) {
    return (left <= other.left + other.width &&
        other.left <= left + width &&
        top <= other.top + other.height &&
        other.top <= top + height);
  }

  /**
   * Returns a new rectangle which completely contains `this` and [other].
   */
  Rectangle boundingBox(Rectangle other) {
    var right = max(this.left + this.width, other.left + other.width);
    var bottom = max(this.top + this.height, other.top + other.height);

    var left = min(this.left, other.left);
    var top = min(this.top, other.top);

    return new Rectangle(left, top, right - left, bottom - top);
  }

  /**
   * Tests whether `this` entirely contains [another].
   */
  bool containsRectangle(Rectangle<num> another) {
    return left <= another.left &&
           left + width >= another.left + another.width &&
           top <= another.top &&
           top + height >= another.top + another.height;
  }

  /**
   * Tests whether [another] is inside or along the edges of `this`.
   */
  bool containsPoint(Point<num> another) {
    return another.x >= left &&
           another.x <= left + width &&
           another.y >= top &&
           another.y <= top + height;
  }

  Point get topLeft => new Point(this.left, this.top);
  Point get topRight => new Point(this.left + this.width, this.top);
  Point get bottomRight => new Point(this.left + this.width,
      this.top + this.height);
  Point get bottomLeft => new Point(this.left,
      this.top + this.height);

    // To suppress missing implicit constructor warnings.
  factory _ClientRect._() { throw new UnsupportedError("Not supported"); }

  @DomName('ClientRect.bottom')
  @DocsEditable()
  double get bottom => _blink.BlinkClientRect.instance.bottom_Getter_(this);

  @DomName('ClientRect.height')
  @DocsEditable()
  double get height => _blink.BlinkClientRect.instance.height_Getter_(this);

  @DomName('ClientRect.left')
  @DocsEditable()
  double get left => _blink.BlinkClientRect.instance.left_Getter_(this);

  @DomName('ClientRect.right')
  @DocsEditable()
  double get right => _blink.BlinkClientRect.instance.right_Getter_(this);

  @DomName('ClientRect.top')
  @DocsEditable()
  double get top => _blink.BlinkClientRect.instance.top_Getter_(this);

  @DomName('ClientRect.width')
  @DocsEditable()
  double get width => _blink.BlinkClientRect.instance.width_Getter_(this);
}

/**
 * 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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('ClientRectList')
class _ClientRectList extends NativeFieldWrapperClass2 with ListMixin<Rectangle>, ImmutableListMixin<Rectangle> implements List<Rectangle> {
  // To suppress missing implicit constructor warnings.
  factory _ClientRectList._() { throw new UnsupportedError("Not supported"); }

  @DomName('ClientRectList.length')
  @DocsEditable()
  int get length => _blink.BlinkClientRectList.instance.length_Getter_(this);

  Rectangle operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return _blink.BlinkClientRectList.instance.item_Callback_1_(this, index);
  }

  Rectangle _nativeIndexedGetter(int index) => _blink.BlinkClientRectList.instance.item_Callback_1_(this, index);

  void operator[]=(int index, Rectangle value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Rectangle> mixins.
  // Rectangle is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Rectangle get first {
    if (this.length > 0) {
      return _nativeIndexedGetter(0);
    }
    throw new StateError("No elements");
  }

  Rectangle get last {
    int len = this.length;
    if (len > 0) {
      return _nativeIndexedGetter(len - 1);
    }
    throw new StateError("No elements");
  }

  Rectangle get single {
    int len = this.length;
    if (len == 1) {
      return _nativeIndexedGetter(0);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Rectangle elementAt(int index) => this[index];
  // -- end List<Rectangle> mixins.

  @DomName('ClientRectList.item')
  @DocsEditable()
  Rectangle item(int index) => _blink.BlinkClientRectList.instance.item_Callback_1_(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.


@DocsEditable()
@DomName('Counter')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
abstract class _Counter extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory _Counter._() { throw new UnsupportedError("Not supported"); }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('CSSRuleList')
class _CssRuleList extends NativeFieldWrapperClass2 with ListMixin<CssRule>, ImmutableListMixin<CssRule> implements List<CssRule> {
  // To suppress missing implicit constructor warnings.
  factory _CssRuleList._() { throw new UnsupportedError("Not supported"); }

  @DomName('CSSRuleList.length')
  @DocsEditable()
  int get length => _blink.BlinkCSSRuleList.instance.length_Getter_(this);

  CssRule operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return _blink.BlinkCSSRuleList.instance.item_Callback_1_(this, index);
  }

  CssRule _nativeIndexedGetter(int index) => _blink.BlinkCSSRuleList.instance.item_Callback_1_(this, index);

  void operator[]=(int index, CssRule value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<CssRule> mixins.
  // CssRule is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  CssRule get first {
    if (this.length > 0) {
      return _nativeIndexedGetter(0);
    }
    throw new StateError("No elements");
  }

  CssRule get last {
    int len = this.length;
    if (len > 0) {
      return _nativeIndexedGetter(len - 1);
    }
    throw new StateError("No elements");
  }

  CssRule get single {
    int len = this.length;
    if (len == 1) {
      return _nativeIndexedGetter(0);
    }
    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) => _blink.BlinkCSSRuleList.instance.item_Callback_1_(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.


@DocsEditable()
@DomName('CSSValueList')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
class _CssValueList extends _CSSValue with ListMixin<_CSSValue>, ImmutableListMixin<_CSSValue> implements List<_CSSValue> {
  // To suppress missing implicit constructor warnings.
  factory _CssValueList._() { throw new UnsupportedError("Not supported"); }

  @DomName('CSSValueList.length')
  @DocsEditable()
  int get length => _blink.BlinkCSSValueList.instance.length_Getter_(this);

  _CSSValue operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return _blink.BlinkCSSValueList.instance.item_Callback_1_(this, index);
  }

  _CSSValue _nativeIndexedGetter(int index) => _blink.BlinkCSSValueList.instance.item_Callback_1_(this, index);

  void operator[]=(int index, _CSSValue value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<_CSSValue> mixins.
  // _CSSValue is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  _CSSValue get first {
    if (this.length > 0) {
      return _nativeIndexedGetter(0);
    }
    throw new StateError("No elements");
  }

  _CSSValue get last {
    int len = this.length;
    if (len > 0) {
      return _nativeIndexedGetter(len - 1);
    }
    throw new StateError("No elements");
  }

  _CSSValue get single {
    int len = this.length;
    if (len == 1) {
      return _nativeIndexedGetter(0);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  _CSSValue elementAt(int index) => this[index];
  // -- end List<_CSSValue> mixins.

  @DomName('CSSValueList.item')
  @DocsEditable()
  _CSSValue item(int index) => _blink.BlinkCSSValueList.instance.item_Callback_1_(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.


@DocsEditable()
@DomName('DOMFileSystemSync')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://www.w3.org/TR/file-system-api/#the-filesystemsync-interface
abstract class _DOMFileSystemSync extends NativeFieldWrapperClass2 {
  // 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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('DatabaseSync')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
// http://www.w3.org/TR/webdatabase/#databasesync
@deprecated // deprecated
abstract class _DatabaseSync extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory _DatabaseSync._() { throw new UnsupportedError("Not supported"); }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('DirectoryEntrySync')
// http://www.w3.org/TR/file-system-api/#the-directoryentrysync-interface
@Experimental()
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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('DirectoryReaderSync')
// http://www.w3.org/TR/file-system-api/#idl-def-DirectoryReaderSync
@Experimental()
abstract class _DirectoryReaderSync extends NativeFieldWrapperClass2 {
  // 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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('DocumentType')
// http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-412266927
@deprecated // stable
abstract class _DocumentType extends Node implements ChildNode {
  // To suppress missing implicit constructor warnings.
  factory _DocumentType._() { 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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('WebKitPoint')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
// http://developer.apple.com/library/safari/#documentation/DataManagement/Reference/DOMWindowAdditionsReference/DOMWindowAdditions/DOMWindowAdditions.html
@Experimental() // non-standard
class _DomPoint extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory _DomPoint._() { throw new UnsupportedError("Not supported"); }

  @DomName('WebKitPoint.WebKitPoint')
  @DocsEditable()
  factory _DomPoint(num x, num y) => _create(x, y);

  @DocsEditable()
  static _DomPoint _create(x, y) => _blink.BlinkWebKitPoint.instance.constructorCallback_2_(x, y);

  /// Checks if this type is supported on the current platform.
  static bool get supported => true;

  @DomName('WebKitPoint.x')
  @DocsEditable()
  num get x => _blink.BlinkWebKitPoint.instance.x_Getter_(this);

  @DomName('WebKitPoint.x')
  @DocsEditable()
  void set x(num value) => _blink.BlinkWebKitPoint.instance.x_Setter_(this, value);

  @DomName('WebKitPoint.y')
  @DocsEditable()
  num get y => _blink.BlinkWebKitPoint.instance.y_Getter_(this);

  @DomName('WebKitPoint.y')
  @DocsEditable()
  void set y(num value) => _blink.BlinkWebKitPoint.instance.y_Setter_(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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('DOMRect')
@Experimental() // untriaged
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 _blink.BlinkDOMRect.instance.constructorCallback_4_(x, y, width, height);
    }
    if (width != null) {
      return _blink.BlinkDOMRect.instance.constructorCallback_3_(x, y, width);
    }
    if (y != null) {
      return _blink.BlinkDOMRect.instance.constructorCallback_2_(x, y);
    }
    if (x != null) {
      return _blink.BlinkDOMRect.instance.constructorCallback_1_(x);
    }
    return _blink.BlinkDOMRect.instance.constructorCallback_0_();
  }

  @DomName('DOMRect.height')
  @DocsEditable()
  @Experimental() // untriaged
  num get height => _blink.BlinkDOMRect.instance.height_Getter_(this);

  @DomName('DOMRect.height')
  @DocsEditable()
  @Experimental() // untriaged
  void set height(num value) => _blink.BlinkDOMRect.instance.height_Setter_(this, value);

  @DomName('DOMRect.width')
  @DocsEditable()
  @Experimental() // untriaged
  num get width => _blink.BlinkDOMRect.instance.width_Getter_(this);

  @DomName('DOMRect.width')
  @DocsEditable()
  @Experimental() // untriaged
  void set width(num value) => _blink.BlinkDOMRect.instance.width_Setter_(this, value);

  @DomName('DOMRect.x')
  @DocsEditable()
  @Experimental() // untriaged
  num get x => _blink.BlinkDOMRect.instance.x_Getter_(this);

  @DomName('DOMRect.x')
  @DocsEditable()
  @Experimental() // untriaged
  void set x(num value) => _blink.BlinkDOMRect.instance.x_Setter_(this, value);

  @DomName('DOMRect.y')
  @DocsEditable()
  @Experimental() // untriaged
  num get y => _blink.BlinkDOMRect.instance.y_Getter_(this);

  @DomName('DOMRect.y')
  @DocsEditable()
  @Experimental() // untriaged
  void set y(num value) => _blink.BlinkDOMRect.instance.y_Setter_(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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('EntrySync')
// http://www.w3.org/TR/file-system-api/#idl-def-EntrySync
@Experimental()
abstract class _EntrySync extends NativeFieldWrapperClass2 {
  // 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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('FileEntrySync')
// http://www.w3.org/TR/file-system-api/#the-fileentrysync-interface
@Experimental()
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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('FileReaderSync')
// http://www.w3.org/TR/FileAPI/#FileReaderSync
@Experimental()
abstract class _FileReaderSync extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory _FileReaderSync._() { throw new UnsupportedError("Not supported"); }

  @DomName('FileReaderSync.FileReaderSync')
  @DocsEditable()
  factory _FileReaderSync() {
    return _blink.BlinkFileReaderSync.instance.constructorCallback_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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('FileWriterSync')
// http://www.w3.org/TR/file-writer-api/#idl-def-FileWriterSync
@Experimental()
abstract class _FileWriterSync extends NativeFieldWrapperClass2 {
  // 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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('GamepadList')
// https://dvcs.w3.org/hg/gamepad/raw-file/default/gamepad.html
@Experimental()
class _GamepadList extends NativeFieldWrapperClass2 with ListMixin<Gamepad>, ImmutableListMixin<Gamepad> implements List<Gamepad> {
  // To suppress missing implicit constructor warnings.
  factory _GamepadList._() { throw new UnsupportedError("Not supported"); }

  @DomName('GamepadList.length')
  @DocsEditable()
  int get length => _blink.BlinkGamepadList.instance.length_Getter_(this);

  Gamepad operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return _blink.BlinkGamepadList.instance.item_Callback_1_(this, index);
  }

  Gamepad _nativeIndexedGetter(int index) => _blink.BlinkGamepadList.instance.item_Callback_1_(this, index);

  void operator[]=(int index, Gamepad value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Gamepad> mixins.
  // Gamepad is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Gamepad get first {
    if (this.length > 0) {
      return _nativeIndexedGetter(0);
    }
    throw new StateError("No elements");
  }

  Gamepad get last {
    int len = this.length;
    if (len > 0) {
      return _nativeIndexedGetter(len - 1);
    }
    throw new StateError("No elements");
  }

  Gamepad get single {
    int len = this.length;
    if (len == 1) {
      return _nativeIndexedGetter(0);
    }
    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) => _blink.BlinkGamepadList.instance.item_Callback_1_(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.


@DocsEditable()
@DomName('HTMLAllCollection')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#dom-document-all
@deprecated // deprecated
abstract class _HTMLAllCollection extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory _HTMLAllCollection._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLAllCollection.item')
  @DocsEditable()
  Element _item(int index) => _blink.BlinkHTMLAllCollection.instance.item_Callback_1_(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.


@DocsEditable()
@DomName('HTMLAppletElement')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#the-applet-element
@deprecated // deprecated
abstract class _HTMLAppletElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory _HTMLAppletElement._() { throw new UnsupportedError("Not supported"); }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLAppletElement.created() : super.created();

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('HTMLDirectoryElement')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#dir
@deprecated // deprecated
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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('HTMLFontElement')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#htmlfontelement
@deprecated // deprecated
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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('HTMLFrameElement')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#htmlframeelement
@deprecated // deprecated
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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('HTMLFrameSetElement')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#frameset
@deprecated // deprecated
abstract class _HTMLFrameSetElement extends HtmlElement implements WindowEventHandlers {
  // 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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('HTMLMarqueeElement')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#the-marquee-element
@deprecated // deprecated
abstract class _HTMLMarqueeElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory _HTMLMarqueeElement._() { throw new UnsupportedError("Not supported"); }
  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLMarqueeElement.created() : super.created();

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('MutationEvent')
// http://www.w3.org/TR/DOM-Level-3-Events/#events-mutationevents
@deprecated
abstract class _MutationEvent extends Event {
  factory _MutationEvent(String type,
      {bool canBubble: false, bool cancelable: false, Node relatedNode,
      String prevValue, String newValue, String attrName, int attrChange: 0}) {

    var event = document._createEvent('MutationEvent');
    event._initMutationEvent(type, canBubble, cancelable, relatedNode,
        prevValue, newValue, attrName, attrChange);
    return event;
  }
  // To suppress missing implicit constructor warnings.
  factory _MutationEvent._() { throw new UnsupportedError("Not supported"); }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('NamedNodeMap')
// http://dom.spec.whatwg.org/#namednodemap
@deprecated // deprecated
class _NamedNodeMap extends NativeFieldWrapperClass2 with ListMixin<Node>, ImmutableListMixin<Node> implements List<Node> {
  // To suppress missing implicit constructor warnings.
  factory _NamedNodeMap._() { throw new UnsupportedError("Not supported"); }

  @DomName('NamedNodeMap.length')
  @DocsEditable()
  int get length => _blink.BlinkNamedNodeMap.instance.length_Getter_(this);

  Node operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return _blink.BlinkNamedNodeMap.instance.item_Callback_1_(this, index);
  }

  Node _nativeIndexedGetter(int index) => _blink.BlinkNamedNodeMap.instance.item_Callback_1_(this, index);

  void operator[]=(int index, Node value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<Node> mixins.
  // Node is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  Node get first {
    if (this.length > 0) {
      return _nativeIndexedGetter(0);
    }
    throw new StateError("No elements");
  }

  Node get last {
    int len = this.length;
    if (len > 0) {
      return _nativeIndexedGetter(len - 1);
    }
    throw new StateError("No elements");
  }

  Node get single {
    int len = this.length;
    if (len == 1) {
      return _nativeIndexedGetter(0);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

  Node elementAt(int index) => this[index];
  // -- end List<Node> mixins.

  @DomName('NamedNodeMap.__getter__')
  @DocsEditable()
  Node __getter__(String name) => _blink.BlinkNamedNodeMap.instance.$__getter___Callback_1_(this, name);

  @DomName('NamedNodeMap.getNamedItem')
  @DocsEditable()
  Node getNamedItem(String name) => _blink.BlinkNamedNodeMap.instance.getNamedItem_Callback_1_(this, name);

  @DomName('NamedNodeMap.getNamedItemNS')
  @DocsEditable()
  Node getNamedItemNS(String namespaceURI, String localName) => _blink.BlinkNamedNodeMap.instance.getNamedItemNS_Callback_2_(this, namespaceURI, localName);

  @DomName('NamedNodeMap.item')
  @DocsEditable()
  Node item(int index) => _blink.BlinkNamedNodeMap.instance.item_Callback_1_(this, index);

  @DomName('NamedNodeMap.removeNamedItem')
  @DocsEditable()
  Node removeNamedItem(String name) => _blink.BlinkNamedNodeMap.instance.removeNamedItem_Callback_1_(this, name);

  @DomName('NamedNodeMap.removeNamedItemNS')
  @DocsEditable()
  Node removeNamedItemNS(String namespaceURI, String localName) => _blink.BlinkNamedNodeMap.instance.removeNamedItemNS_Callback_2_(this, namespaceURI, localName);

  @DomName('NamedNodeMap.setNamedItem')
  @DocsEditable()
  Node setNamedItem(Node node) => _blink.BlinkNamedNodeMap.instance.setNamedItem_Callback_1_(this, node);

  @DomName('NamedNodeMap.setNamedItemNS')
  @DocsEditable()
  Node setNamedItemNS(Node node) => _blink.BlinkNamedNodeMap.instance.setNamedItemNS_Callback_1_(this, node);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


@DocsEditable()
@DomName('Notation')
// http://dom.spec.whatwg.org/#notation
@deprecated // deprecated
abstract class _Notation extends Node {
  // To suppress missing implicit constructor warnings.
  factory _Notation._() { throw new UnsupportedError("Not supported"); }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('PagePopupController')
@deprecated // nonstandard
abstract class _PagePopupController extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory _PagePopupController._() { throw new UnsupportedError("Not supported"); }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('RGBColor')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
abstract class _RGBColor extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory _RGBColor._() { throw new UnsupportedError("Not supported"); }

}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('RadioNodeList')
abstract class _RadioNodeList extends NodeList {
  // To suppress missing implicit constructor warnings.
  factory _RadioNodeList._() { 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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('Rect')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
abstract class _Rect extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory _Rect._() { throw new UnsupportedError("Not supported"); }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('Request')
@Experimental() // untriaged
class _Request extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory _Request._() { throw new UnsupportedError("Not supported"); }

  @DomName('Request.Request')
  @DocsEditable()
  factory _Request(input, [Map requestInitDict]) {
    if ((input is String || input == null) && requestInitDict == null) {
      return _blink.BlinkRequest.instance.constructorCallback_1_(input);
    }
    if ((requestInitDict is Map || requestInitDict == null) && (input is String || input == null)) {
      return _blink.BlinkRequest.instance.constructorCallback_2_(input, requestInitDict);
    }
    if ((input is _Request || input == null) && requestInitDict == null) {
      return _blink.BlinkRequest.instance.constructorCallback_1_(input);
    }
    if ((requestInitDict is Map || requestInitDict == null) && (input is _Request || input == null)) {
      return _blink.BlinkRequest.instance.constructorCallback_2_(input, requestInitDict);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('Request.credentials')
  @DocsEditable()
  @Experimental() // untriaged
  String get credentials => _blink.BlinkRequest.instance.credentials_Getter_(this);

  @DomName('Request.headers')
  @DocsEditable()
  @Experimental() // untriaged
  Headers get headers => _blink.BlinkRequest.instance.headers_Getter_(this);

  @DomName('Request.mode')
  @DocsEditable()
  @Experimental() // untriaged
  String get mode => _blink.BlinkRequest.instance.mode_Getter_(this);

  @DomName('Request.referrer')
  @DocsEditable()
  @Experimental() // untriaged
  String get referrer => _blink.BlinkRequest.instance.referrer_Getter_(this);

  @DomName('Request.url')
  @DocsEditable()
  @Experimental() // untriaged
  String get url => _blink.BlinkRequest.instance.url_Getter_(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.


@DocsEditable()
@DomName('Response')
@Experimental() // untriaged
abstract class _Response extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory _Response._() { throw new UnsupportedError("Not supported"); }

  @DomName('Response.Response')
  @DocsEditable()
  factory _Response(body, [Map responseInitDict]) {
    if ((body is String || body == null) && responseInitDict == null) {
      return _blink.BlinkResponse.instance.constructorCallback_1_(body);
    }
    if ((responseInitDict is Map || responseInitDict == null) && (body is String || body == null)) {
      return _blink.BlinkResponse.instance.constructorCallback_2_(body, responseInitDict);
    }
    if ((body is Blob || body == null) && responseInitDict == null) {
      return _blink.BlinkResponse.instance.constructorCallback_1_(body);
    }
    if ((responseInitDict is Map || responseInitDict == null) && (body is Blob || body == null)) {
      return _blink.BlinkResponse.instance.constructorCallback_2_(body, responseInitDict);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


@DocsEditable()
@DomName('ServiceWorker')
@Experimental() // untriaged
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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('SpeechRecognitionResultList')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechrecognitionresultlist
@Experimental()
class _SpeechRecognitionResultList extends NativeFieldWrapperClass2 with ListMixin<SpeechRecognitionResult>, ImmutableListMixin<SpeechRecognitionResult> implements List<SpeechRecognitionResult> {
  // To suppress missing implicit constructor warnings.
  factory _SpeechRecognitionResultList._() { throw new UnsupportedError("Not supported"); }

  @DomName('SpeechRecognitionResultList.length')
  @DocsEditable()
  int get length => _blink.BlinkSpeechRecognitionResultList.instance.length_Getter_(this);

  SpeechRecognitionResult operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return _blink.BlinkSpeechRecognitionResultList.instance.item_Callback_1_(this, index);
  }

  SpeechRecognitionResult _nativeIndexedGetter(int index) => _blink.BlinkSpeechRecognitionResultList.instance.item_Callback_1_(this, index);

  void operator[]=(int index, SpeechRecognitionResult value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<SpeechRecognitionResult> mixins.
  // SpeechRecognitionResult is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  SpeechRecognitionResult get first {
    if (this.length > 0) {
      return _nativeIndexedGetter(0);
    }
    throw new StateError("No elements");
  }

  SpeechRecognitionResult get last {
    int len = this.length;
    if (len > 0) {
      return _nativeIndexedGetter(len - 1);
    }
    throw new StateError("No elements");
  }

  SpeechRecognitionResult get single {
    int len = this.length;
    if (len == 1) {
      return _nativeIndexedGetter(0);
    }
    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) => _blink.BlinkSpeechRecognitionResultList.instance.item_Callback_1_(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.


@DocsEditable()
@DomName('StyleSheetList')
class _StyleSheetList extends NativeFieldWrapperClass2 with ListMixin<StyleSheet>, ImmutableListMixin<StyleSheet> implements List<StyleSheet> {
  // To suppress missing implicit constructor warnings.
  factory _StyleSheetList._() { throw new UnsupportedError("Not supported"); }

  @DomName('StyleSheetList.length')
  @DocsEditable()
  int get length => _blink.BlinkStyleSheetList.instance.length_Getter_(this);

  StyleSheet operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return _blink.BlinkStyleSheetList.instance.item_Callback_1_(this, index);
  }

  StyleSheet _nativeIndexedGetter(int index) => _blink.BlinkStyleSheetList.instance.item_Callback_1_(this, index);

  void operator[]=(int index, StyleSheet value) {
    throw new UnsupportedError("Cannot assign element of immutable List.");
  }
  // -- start List<StyleSheet> mixins.
  // StyleSheet is the element type.


  void set length(int value) {
    throw new UnsupportedError("Cannot resize immutable List.");
  }

  StyleSheet get first {
    if (this.length > 0) {
      return _nativeIndexedGetter(0);
    }
    throw new StateError("No elements");
  }

  StyleSheet get last {
    int len = this.length;
    if (len > 0) {
      return _nativeIndexedGetter(len - 1);
    }
    throw new StateError("No elements");
  }

  StyleSheet get single {
    int len = this.length;
    if (len == 1) {
      return _nativeIndexedGetter(0);
    }
    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) => _blink.BlinkStyleSheetList.instance.$__getter___Callback_1_(this, name);

  @DomName('StyleSheetList.item')
  @DocsEditable()
  StyleSheet item(int index) => _blink.BlinkStyleSheetList.instance.item_Callback_1_(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.


@DocsEditable()
@DomName('SubtleCrypto')
@Experimental() // untriaged
abstract class _SubtleCrypto extends NativeFieldWrapperClass2 {
  // 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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('WebKitCSSFilterValue')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
abstract class _WebKitCSSFilterValue extends _CssValueList {
  // To suppress missing implicit constructor warnings.
  factory _WebKitCSSFilterValue._() { throw new UnsupportedError("Not supported"); }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('WebKitCSSMatrix')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
abstract class _WebKitCSSMatrix extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory _WebKitCSSMatrix._() { throw new UnsupportedError("Not supported"); }

  @DomName('WebKitCSSMatrix.WebKitCSSMatrix')
  @DocsEditable()
  factory _WebKitCSSMatrix([String cssValue]) {
    return _blink.BlinkWebKitCSSMatrix.instance.constructorCallback_1_(cssValue);
  }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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.


@DocsEditable()
@DomName('WebKitCSSTransformValue')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
abstract class _WebKitCSSTransformValue extends _CssValueList {
  // To suppress missing implicit constructor warnings.
  factory _WebKitCSSTransformValue._() { throw new UnsupportedError("Not supported"); }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('WindowTimers')
@Experimental() // untriaged
abstract class _WindowTimers extends NativeFieldWrapperClass2 {
  // To suppress missing implicit constructor warnings.
  factory _WindowTimers._() { throw new UnsupportedError("Not supported"); }

  @DomName('WindowTimers.clearInterval')
  @DocsEditable()
  @Experimental() // untriaged
  void _clearInterval(int handle);

  @DomName('WindowTimers.clearTimeout')
  @DocsEditable()
  @Experimental() // untriaged
  void _clearTimeout(int handle);

  @DomName('WindowTimers.setInterval')
  @DocsEditable()
  @Experimental() // untriaged
  int _setInterval(Object handler, int timeout);

  @DomName('WindowTimers.setTimeout')
  @DocsEditable()
  @Experimental() // untriaged
  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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('WorkerLocation')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#workerlocation
@Experimental()
abstract class _WorkerLocation extends NativeFieldWrapperClass2 implements UrlUtilsReadOnly {
  // To suppress missing implicit constructor warnings.
  factory _WorkerLocation._() { 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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('WorkerNavigator')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#workernavigator
@Experimental()
abstract class _WorkerNavigator extends NativeFieldWrapperClass2 implements NavigatorCpu, NavigatorOnLine, NavigatorID {
  // To suppress missing implicit constructor warnings.
  factory _WorkerNavigator._() { 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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('XMLHttpRequestProgressEvent')
@Experimental() // nonstandard
abstract class _XMLHttpRequestProgressEvent extends ProgressEvent {
  // To suppress missing implicit constructor warnings.
  factory _XMLHttpRequestProgressEvent._() { throw new UnsupportedError("Not supported"); }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


abstract class _AttributeMap implements Map<String, String> {
  final Element _element;

  _AttributeMap(this._element);

  void addAll(Map<String, String> other) {
    other.forEach((k, v) { this[k] = v; });
  }

  bool containsValue(String value) {
    for (var v in this.values) {
      if (value == v) {
        return true;
      }
    }
    return false;
  }

  String putIfAbsent(String key, String ifAbsent()) {
    if (!containsKey(key)) {
      this[key] = ifAbsent();
    }
    return this[key];
  }

  void clear() {
    for (var key in keys) {
      remove(key);
    }
  }

  void forEach(void f(String key, String value)) {
    for (var key in keys) {
      var value = this[key];
      f(key, value);
    }
  }

  Iterable<String> get keys {
    // TODO: generate a lazy collection instead.
    var attributes = _element._attributes;
    var keys = new List<String>();
    for (int i = 0, len = attributes.length; i < len; i++) {
      if (_matches(attributes[i])) {
        keys.add(attributes[i].name);
      }
    }
    return keys;
  }

  Iterable<String> get values {
    // TODO: generate a lazy collection instead.
    var attributes = _element._attributes;
    var values = new List<String>();
    for (int i = 0, len = attributes.length; i < len; i++) {
      if (_matches(attributes[i])) {
        values.add(attributes[i].value);
      }
    }
    return values;
  }

  /**
   * Returns true if there is no {key, value} pair in the map.
   */
  bool get isEmpty {
    return length == 0;
  }

  /**
   * Returns true if there is at least one {key, value} pair in the map.
   */
  bool get isNotEmpty => !isEmpty;

  /**
   * Checks to see if the node should be included in this map.
   */
  bool _matches(Node node);
}

/**
 * Wrapper to expose [Element.attributes] as a typed map.
 */
class _ElementAttributeMap extends _AttributeMap {

  _ElementAttributeMap(Element element): super(element);

  bool containsKey(String key) {
    return _element._hasAttribute(key);
  }

  String operator [](String key) {
    return _element.getAttribute(key);
  }

  void operator []=(String key, String value) {
    _element.setAttribute(key, value);
  }

  String remove(String key) {
    String value = _element.getAttribute(key);
    _element._removeAttribute(key);
    return value;
  }

  /**
   * The number of {key, value} pairs in the map.
   */
  int get length {
    return keys.length;
  }

  bool _matches(Node node) => node._namespaceUri == null;
}

/**
 * Wrapper to expose namespaced attributes as a typed map.
 */
class _NamespacedAttributeMap extends _AttributeMap {

  final String _namespace;

  _NamespacedAttributeMap(Element element, this._namespace): super(element);

  bool containsKey(String key) {
    return _element._hasAttributeNS(_namespace, key);
  }

  String operator [](String key) {
    return _element.getAttributeNS(_namespace, key);
  }

  void operator []=(String key, String value) {
    _element.setAttributeNS(_namespace, key, value);
  }

  String remove(String key) {
    String value = this[key];
    _element._removeAttributeNS(_namespace, key);
    return value;
  }

  /**
   * The number of {key, value} pairs in the map.
   */
  int get length {
    return keys.length;
  }

  bool _matches(Node node) => node._namespaceUri == _namespace;
}


/**
 * Provides a Map abstraction on top of data-* attributes, similar to the
 * dataSet in the old DOM.
 */
class _DataAttributeMap implements Map<String, String> {

  final Map<String, String> _attributes;

  _DataAttributeMap(this._attributes);

  // interface Map

  void addAll(Map<String, String> other) {
    other.forEach((k, v) { this[k] = v; });
  }

  // TODO: Use lazy iterator when it is available on Map.
  bool containsValue(String value) => values.any((v) => v == value);

  bool containsKey(String key) => _attributes.containsKey(_attr(key));

  String operator [](String key) => _attributes[_attr(key)];

  void operator []=(String key, String value) {
    _attributes[_attr(key)] = value;
  }

  String putIfAbsent(String key, String ifAbsent()) =>
    _attributes.putIfAbsent(_attr(key), ifAbsent);

  String remove(String key) => _attributes.remove(_attr(key));

  void clear() {
    // Needs to operate on a snapshot since we are mutating the collection.
    for (String key in keys) {
      remove(key);
    }
  }

  void forEach(void f(String key, String value)) {
    _attributes.forEach((String key, String value) {
      if (_matches(key)) {
        f(_strip(key), value);
      }
    });
  }

  Iterable<String> get keys {
    final keys = new List<String>();
    _attributes.forEach((String key, String value) {
      if (_matches(key)) {
        keys.add(_strip(key));
      }
    });
    return keys;
  }

  Iterable<String> get values {
    final values = new List<String>();
    _attributes.forEach((String key, String value) {
      if (_matches(key)) {
        values.add(value);
      }
    });
    return values;
  }

  int get length => keys.length;

  // TODO: Use lazy iterator when it is available on Map.
  bool get isEmpty => length == 0;

  bool get isNotEmpty => !isEmpty;

  // Helpers.
  String _attr(String key) => 'data-${_toHyphenedName(key)}';
  bool _matches(String key) => key.startsWith('data-');
  String _strip(String key) => _toCamelCase(key.substring(5));

  /**
   * Converts a string name with hyphens into an identifier, by removing hyphens
   * and capitalizing the following letter. Optionally [startUppercase] to
   * captialize the first letter.
   */
  String _toCamelCase(String hyphenedName, {bool startUppercase: false}) {
    var segments = hyphenedName.split('-');
    int start = startUppercase ? 0 : 1;
    for (int i = start; i < segments.length; i++) {
      var segment = segments[i];
      if (segment.length > 0) {
        // Character between 'a'..'z' mapped to 'A'..'Z'
        segments[i] = '${segment[0].toUpperCase()}${segment.substring(1)}';
      }
    }
    return segments.join('');
  }

  /** Reverse of [toCamelCase]. */
  String _toHyphenedName(String word) {
    var sb = new StringBuffer();
    for (int i = 0; i < word.length; i++) {
      var lower = word[i].toLowerCase();
      if (word[i] != lower && i > 0) sb.write('-');
      sb.write(lower);
    }
    return sb.toString();
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * An object that can be drawn to a 2D canvas rendering context.
 *
 * The image drawn to the canvas depends on the type of this object:
 *
 * * If this object is an [ImageElement], then this element's image is
 * drawn to the canvas. If this element is an animated image, then this
 * element's poster frame is drawn. If this element has no poster frame, then
 * the first frame of animation is drawn.
 *
 * * If this object is a [VideoElement], then the frame at this element's current
 * playback position is drawn to the canvas.
 *
 * * If this object is a [CanvasElement], then this element's bitmap is drawn to
 * the canvas.
 *
 * **Note:** Currently all versions of Internet Explorer do not support
 * drawing a video element to a canvas. You may also encounter problems drawing
 * a video to a canvas in Firefox if the source of the video is a data URL.
 *
 * ## See also
 *
 * * [CanvasRenderingContext2D.drawImage]
 * * [CanvasRenderingContext2D.drawImageToRect]
 * * [CanvasRenderingContext2D.drawImageScaled]
 * * [CanvasRenderingContext2D.drawImageScaledFromSource]
 *
 * ## Other resources
 *
 * * [Image sources for 2D rendering contexts]
 * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#image-sources-for-2d-rendering-contexts)
 * from WHATWG.
 * * [Drawing images]
 * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
 * from WHATWG.
 */
abstract class CanvasImageSource {}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * Top-level container for a browser tab or window.
 *
 * In a web browser, a [WindowBase] object represents any browser window. This
 * object contains the window's state and its relation to other
 * windows, such as which window opened this window.
 *
 * **Note:** This class represents any window, while [Window] is
 * used to access the properties and content of the current window or tab.
 *
 * ## See also
 *
 * * [Window]
 *
 * ## Other resources
 *
 * * [DOM Window](https://developer.mozilla.org/en-US/docs/DOM/window) from MDN.
 * * [Window](http://www.w3.org/TR/Window/) from the W3C.
 */
abstract class WindowBase implements EventTarget {
  // Fields.

  /**
   * The current location of this window.
   *
   *     Location currentLocation = window.location;
   *     print(currentLocation.href); // 'http://www.example.com:80/'
   */
  LocationBase get location;

  /**
   * The current session history for this window.
   *
   * ## Other resources
   *
   * * [Session history and navigation specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html)
   * from WHATWG.
   */
  HistoryBase get history;

  /**
   * Indicates whether this window has been closed.
   *
   *     print(window.closed); // 'false'
   *     window.close();
   *     print(window.closed); // 'true'
   */
  bool get closed;

  /**
   * A reference to the window that opened this one.
   *
   *     Window thisWindow = window;
   *     WindowBase otherWindow = thisWindow.open('http://www.example.com/', 'foo');
   *     print(otherWindow.opener == thisWindow); // 'true'
   */
  WindowBase get opener;

  /**
   * A reference to the parent of this window.
   *
   * If this [WindowBase] has no parent, [parent] will return a reference to
   * the [WindowBase] itself.
   *
   *     IFrameElement myIFrame = new IFrameElement();
   *     window.document.body.elements.add(myIFrame);
   *     print(myIframe.contentWindow.parent == window) // 'true'
   *
   *     print(window.parent == window) // 'true'
   */
  WindowBase get parent;

  /**
   * A reference to the topmost window in the window hierarchy.
   *
   * If this [WindowBase] is the topmost [WindowBase], [top] will return a
   * reference to the [WindowBase] itself.
   *
   *     // Add an IFrame to the current window.
   *     IFrameElement myIFrame = new IFrameElement();
   *     window.document.body.elements.add(myIFrame);
   *
   *     // Add an IFrame inside of the other IFrame.
   *     IFrameElement innerIFrame = new IFrameElement();
   *     myIFrame.elements.add(innerIFrame);
   *
   *     print(myIframe.contentWindow.top == window) // 'true'
   *     print(innerIFrame.contentWindow.top == window) // 'true'
   *
   *     print(window.top == window) // 'true'
   */
  WindowBase get top;

  // Methods.
  /**
   * Closes the window.
   *
   * This method should only succeed if the [WindowBase] object is
   * **script-closeable** and the window calling [close] is allowed to navigate
   * the window.
   *
   * A window is script-closeable if it is either a window
   * that was opened by another window, or if it is a window with only one
   * document in its history.
   *
   * A window might not be allowed to navigate, and therefore close, another
   * window due to browser security features.
   *
   *     var other = window.open('http://www.example.com', 'foo');
   *     // Closes other window, as it is script-closeable.
   *     other.close();
   *     print(other.closed()); // 'true'
   *
   *     window.location('http://www.mysite.com', 'foo');
   *     // Does not close this window, as the history has changed.
   *     window.close();
   *     print(window.closed()); // 'false'
   *
   * See also:
   *
   * * [Window close discussion](http://www.w3.org/TR/html5/browsers.html#dom-window-close) from the W3C
   */
  void close();

  /**
   * Sends a cross-origin message.
   *
   * ## Other resources
   *
   * * [window.postMessage]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage) from
   * MDN.
   * * [Cross-document messaging]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/web-messaging.html)
   * from WHATWG.
   */
  void postMessage(var message, String targetOrigin, [List messagePorts]);
}

abstract class LocationBase {
  void set href(String val);
}

abstract class HistoryBase {
  void back();
  void forward();
  void go(int distance);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/** A Set that stores the CSS class names for an element. */
abstract class CssClassSet implements Set<String> {

  /**
   * Adds the class [value] to the element if it is not on it, removes it if it
   * is.
   *
   * If [shouldAdd] is true, then we always add that [value] to the element. If
   * [shouldAdd] is false then we always remove [value] from the element.
   */
  bool toggle(String value, [bool shouldAdd]);

  /**
   * Returns [:true:] if classes cannot be added or removed from this
   * [:CssClassSet:].
   */
  bool get frozen;

  /**
   * Determine if this element contains the class [value].
   *
   * This is the Dart equivalent of jQuery's
   * [hasClass](http://api.jquery.com/hasClass/).
   */
  bool contains(String value);

  /**
   * Add the class [value] to element.
   *
   * This is the Dart equivalent of jQuery's
   * [addClass](http://api.jquery.com/addClass/).
   *
   * If this corresponds to one element. Returns true if [value] was added to
   * the set, otherwise false.
   *
   * If this corresponds to many elements, null is always returned.
   */
  bool add(String value);

  /**
   * Remove the class [value] from element, and return true on successful
   * removal.
   *
   * This is the Dart equivalent of jQuery's
   * [removeClass](http://api.jquery.com/removeClass/).
   */
  bool remove(Object value);

  /**
   * Add all classes specified in [iterable] to element.
   *
   * This is the Dart equivalent of jQuery's
   * [addClass](http://api.jquery.com/addClass/).
   */
  void addAll(Iterable<String> iterable);

  /**
   * Remove all classes specified in [iterable] from element.
   *
   * This is the Dart equivalent of jQuery's
   * [removeClass](http://api.jquery.com/removeClass/).
   */
  void removeAll(Iterable<String> iterable);

  /**
   * Toggles all classes specified in [iterable] on element.
   *
   * Iterate through [iterable]'s items, and add it if it is not on it, or
   * remove it if it is. This is the Dart equivalent of jQuery's
   * [toggleClass](http://api.jquery.com/toggleClass/).
   * If [shouldAdd] is true, then we always add all the classes in [iterable]
   * element. If [shouldAdd] is false then we always remove all the classes in
   * [iterable] from the element.
   */
  void toggleAll(Iterable<String> iterable, [bool shouldAdd]);
}

/**
 * A set (union) of the CSS classes that are present in a set of elements.
 * Implemented separately from _ElementCssClassSet for performance.
 */
class _MultiElementCssClassSet extends CssClassSetImpl {
  final Iterable<Element> _elementIterable;
  Iterable<_ElementCssClassSet> _elementCssClassSetIterable;

  _MultiElementCssClassSet(this._elementIterable) {
    _elementCssClassSetIterable = new List.from(_elementIterable).map(
        (e) => new _ElementCssClassSet(e));
  }

  Set<String> readClasses() {
    var s = new LinkedHashSet<String>();
    _elementCssClassSetIterable.forEach((e) => s.addAll(e.readClasses()));
    return s;
  }

  void writeClasses(Set<String> s) {
    var classes = new List.from(s).join(' ');
    for (Element e in _elementIterable) {
      e.className = classes;
    }
  }

  /**
   * Helper method used to modify the set of css classes on this element.
   *
   *   f - callback with:
   *   s - a Set of all the css class name currently on this element.
   *
   *   After f returns, the modified set is written to the
   *       className property of this element.
   */
  modify( f(Set<String> s)) {
    _elementCssClassSetIterable.forEach((e) => e.modify(f));
  }

  /**
   * Adds the class [value] to the element if it is not on it, removes it if it
   * is.
   */
  bool toggle(String value, [bool shouldAdd]) =>
      _modifyWithReturnValue((e) => e.toggle(value, shouldAdd));

  /**
   * Remove the class [value] from element, and return true on successful
   * removal.
   *
   * This is the Dart equivalent of jQuery's
   * [removeClass](http://api.jquery.com/removeClass/).
   */
  bool remove(Object value) => _modifyWithReturnValue((e) => e.remove(value));

  bool _modifyWithReturnValue(f) => _elementCssClassSetIterable.fold(
      false, (prevValue, element) => f(element) || prevValue);
}

class _ElementCssClassSet extends CssClassSetImpl {

  final Element _element;

  _ElementCssClassSet(this._element);

  Set<String> readClasses() {
    var s = new LinkedHashSet<String>();
    var classname = _element.className;

    for (String name in classname.split(' ')) {
      String trimmed = name.trim();
      if (!trimmed.isEmpty) {
        s.add(trimmed);
      }
    }
    return s;
  }

  void writeClasses(Set<String> s) {
    List list = new List.from(s);
    _element.className = s.join(' ');
  }
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * A rectangle representing all the content of the element in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _ContentCssRect extends CssRect {

  _ContentCssRect(element) : super(element);

  num get height => _element.offsetHeight +
      _addOrSubtractToBoxModel(_HEIGHT, _CONTENT);

  num get width => _element.offsetWidth +
      _addOrSubtractToBoxModel(_WIDTH, _CONTENT);

  /**
   * Set the height to `newHeight`.
   *
   * newHeight can be either a [num] representing the height in pixels or a
   * [Dimension] object. Values of newHeight that are less than zero are
   * converted to effectively setting the height to 0. This is equivalent to the
   * `height` function in jQuery and the calculated `height` CSS value,
   * converted to a num in pixels.
   */
  void set height(newHeight) {
    if (newHeight is Dimension) {
      if (newHeight.value < 0) newHeight = new Dimension.px(0);
      _element.style.height = newHeight.toString();
    } else {
      if (newHeight < 0) newHeight = 0;
      _element.style.height = '${newHeight}px';
    }
  }

  /**
   * Set the current computed width in pixels of this element.
   *
   * newWidth can be either a [num] representing the width in pixels or a
   * [Dimension] object. This is equivalent to the `width` function in jQuery
   * and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels.
   */
  void set width(newWidth) {
    if (newWidth is Dimension) {
      if (newWidth.value < 0) newWidth = new Dimension.px(0);
      _element.style.width = newWidth.toString();
    } else {
      if (newWidth < 0) newWidth = 0;
      _element.style.width = '${newWidth}px';
    }
  }

  num get left => _element.getBoundingClientRect().left -
      _addOrSubtractToBoxModel(['left'], _CONTENT);
  num get top => _element.getBoundingClientRect().top -
      _addOrSubtractToBoxModel(['top'], _CONTENT);
}

/**
 * A list of element content rectangles in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _ContentCssListRect extends _ContentCssRect {
  List<Element> _elementList;

  _ContentCssListRect(elementList) : super(elementList.first) {
    _elementList = elementList;
  }

  /**
   * Set the height to `newHeight`.
   *
   * Values of newHeight that are less than zero are converted to effectively
   * setting the height to 0. This is equivalent to the `height`
   * function in jQuery and the calculated `height` CSS value, converted to a
   * num in pixels.
   */
  void set height(newHeight) {
    _elementList.forEach((e) => e.contentEdge.height = newHeight);
  }

  /**
   * Set the current computed width in pixels of this element.
   *
   * This is equivalent to the `width` function in jQuery and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels.
   */
  void set width(newWidth) {
    _elementList.forEach((e) => e.contentEdge.width = newWidth);
  }
}

/**
 * A rectangle representing the dimensions of the space occupied by the
 * element's content + padding in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _PaddingCssRect extends CssRect {
  _PaddingCssRect(element) : super(element);
  num get height => _element.offsetHeight +
      _addOrSubtractToBoxModel(_HEIGHT, _PADDING);
  num get width => _element.offsetWidth +
      _addOrSubtractToBoxModel(_WIDTH, _PADDING);

  num get left => _element.getBoundingClientRect().left -
      _addOrSubtractToBoxModel(['left'], _PADDING);
  num get top => _element.getBoundingClientRect().top -
      _addOrSubtractToBoxModel(['top'], _PADDING);
}

/**
 * A rectangle representing the dimensions of the space occupied by the
 * element's content + padding + border in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _BorderCssRect extends CssRect {
  _BorderCssRect(element) : super(element);
  num get height => _element.offsetHeight;
  num get width => _element.offsetWidth;

  num get left => _element.getBoundingClientRect().left;
  num get top => _element.getBoundingClientRect().top;
}

/**
 * A rectangle representing the dimensions of the space occupied by the
 * element's content + padding + border + margin in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _MarginCssRect extends CssRect {
  _MarginCssRect(element) : super(element);
  num get height => _element.offsetHeight +
      _addOrSubtractToBoxModel(_HEIGHT, _MARGIN);
  num get width =>
      _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _MARGIN);

  num get left => _element.getBoundingClientRect().left -
      _addOrSubtractToBoxModel(['left'], _MARGIN);
  num get top => _element.getBoundingClientRect().top -
      _addOrSubtractToBoxModel(['top'], _MARGIN);
}

/**
 * A class for representing CSS dimensions.
 *
 * In contrast to the more general purpose [Rectangle] class, this class's
 * values are mutable, so one can change the height of an element
 * programmatically.
 *
 * _Important_ _note_: use of these methods will perform CSS calculations that
 * can trigger a browser reflow. Therefore, use of these properties _during_ an
 * animation frame is discouraged. See also:
 * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
 */
abstract class CssRect extends MutableRectangle<num> {
  Element _element;

  CssRect(this._element) : super(0, 0, 0, 0);

  num get left;

  num get top;

  /**
   * The height of this rectangle.
   *
   * This is equivalent to the `height` function in jQuery and the calculated
   * `height` CSS value, converted to a dimensionless num in pixels. Unlike
   * [getBoundingClientRect], `height` will return the same numerical width if
   * the element is hidden or not.
   */
  num get height;

  /**
   * The width of this rectangle.
   *
   * This is equivalent to the `width` function in jQuery and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels. Unlike
   * [getBoundingClientRect], `width` will return the same numerical width if
   * the element is hidden or not.
   */
  num get width;

  /**
   * Set the height to `newHeight`.
   *
   * newHeight can be either a [num] representing the height in pixels or a
   * [Dimension] object. Values of newHeight that are less than zero are
   * converted to effectively setting the height to 0. This is equivalent to the
   * `height` function in jQuery and the calculated `height` CSS value,
   * converted to a num in pixels.
   *
   * Note that only the content height can actually be set via this method.
   */
  void set height(newHeight) {
    throw new UnsupportedError("Can only set height for content rect.");
  }

  /**
   * Set the current computed width in pixels of this element.
   *
   * newWidth can be either a [num] representing the width in pixels or a
   * [Dimension] object. This is equivalent to the `width` function in jQuery
   * and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels.
   *
   * Note that only the content width can be set via this method.
   */
  void set width(newWidth) {
    throw new UnsupportedError("Can only set width for content rect.");
  }

  /**
   * Return a value that is used to modify the initial height or width
   * measurement of an element. Depending on the value (ideally an enum) passed
   * to augmentingMeasurement, we may need to add or subtract margin, padding,
   * or border values, depending on the measurement we're trying to obtain.
   */
  num _addOrSubtractToBoxModel(List<String> dimensions,
      String augmentingMeasurement) {
    // getComputedStyle always returns pixel values (hence, computed), so we're
    // always dealing with pixels in this method.
    var styles = _element.getComputedStyle();

    var val = 0;

    for (String measurement in dimensions) {
      // The border-box and default box model both exclude margin in the regular
      // height/width calculation, so add it if we want it for this measurement.
      if (augmentingMeasurement == _MARGIN) {
        val += new Dimension.css(styles.getPropertyValue(
            '$augmentingMeasurement-$measurement')).value;
      }

      // The border-box includes padding and border, so remove it if we want
      // just the content itself.
      if (augmentingMeasurement == _CONTENT) {
      	val -= new Dimension.css(
            styles.getPropertyValue('${_PADDING}-$measurement')).value;
      }

      // At this point, we don't wan't to augment with border or margin,
      // so remove border.
      if (augmentingMeasurement != _MARGIN) {
	      val -= new Dimension.css(styles.getPropertyValue(
            'border-${measurement}-width')).value;
      }
    }
    return val;
  }
}

final _HEIGHT = ['top', 'bottom'];
final _WIDTH = ['right', 'left'];
final _CONTENT = 'content';
final _PADDING = 'padding';
final _MARGIN = 'margin';

/**
 * Class representing a
 * [length measurement](https://developer.mozilla.org/en-US/docs/Web/CSS/length)
 * in CSS.
 */
@Experimental()
class Dimension {
  num _value;
  String _unit;

  /** Set this CSS Dimension to a percentage `value`. */
  Dimension.percent(this._value) : _unit = '%';

  /** Set this CSS Dimension to a pixel `value`. */
  Dimension.px(this._value) : _unit = 'px';

  /** Set this CSS Dimension to a pica `value`. */
  Dimension.pc(this._value) : _unit = 'pc';

  /** Set this CSS Dimension to a point `value`. */
  Dimension.pt(this._value) : _unit = 'pt';

  /** Set this CSS Dimension to an inch `value`. */
  Dimension.inch(this._value) : _unit = 'in';

  /** Set this CSS Dimension to a centimeter `value`. */
  Dimension.cm(this._value) : _unit = 'cm';

  /** Set this CSS Dimension to a millimeter `value`. */
  Dimension.mm(this._value) : _unit = 'mm';

  /**
   * Set this CSS Dimension to the specified number of ems.
   *
   * 1em is equal to the current font size. (So 2ems is equal to double the font
   * size). This is useful for producing website layouts that scale nicely with
   * the user's desired font size.
   */
  Dimension.em(this._value) : _unit = 'em';

  /**
   * Set this CSS Dimension to the specified number of x-heights.
   *
   * One ex is equal to the the x-height of a font's baseline to its mean line,
   * generally the height of the letter "x" in the font, which is usually about
   * half the font-size.
   */
  Dimension.ex(this._value) : _unit = 'ex';

  /**
   * Construct a Dimension object from the valid, simple CSS string `cssValue`
   * that represents a distance measurement.
   *
   * This constructor is intended as a convenience method for working with
   * simplistic CSS length measurements. Non-numeric values such as `auto` or
   * `inherit` or invalid CSS will cause this constructor to throw a
   * FormatError.
   */
  Dimension.css(String cssValue) {
    if (cssValue == '') cssValue = '0px';
    if (cssValue.endsWith('%')) {
      _unit = '%';
    } else {
      _unit = cssValue.substring(cssValue.length - 2);
    }
    if (cssValue.contains('.')) {
      _value = double.parse(cssValue.substring(0,
          cssValue.length - _unit.length));
    } else {
      _value = int.parse(cssValue.substring(0, cssValue.length - _unit.length));
    }
  }

  /** Print out the CSS String representation of this value. */
  String toString() {
    return '${_value}${_unit}';
  }

  /** Return a unitless, numerical value of this CSS value. */
  num get value => this._value;
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


typedef EventListener(Event event);
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * A factory to expose DOM events as Streams.
 */
class EventStreamProvider<T extends Event> {
  final String _eventType;

  const EventStreamProvider(this._eventType);

  /**
   * Gets a [Stream] for this event type, on the specified target.
   *
   * This will always return a broadcast stream so multiple listeners can be
   * used simultaneously.
   *
   * This may be used to capture DOM events:
   *
   *     Element.keyDownEvent.forTarget(element, useCapture: true).listen(...);
   *
   *     // Alternate method:
   *     Element.keyDownEvent.forTarget(element).capture(...);
   *
   * Or for listening to an event which will bubble through the DOM tree:
   *
   *     MediaElement.pauseEvent.forTarget(document.body).listen(...);
   *
   * See also:
   *
   * [addEventListener](http://docs.webplatform.org/wiki/dom/methods/addEventListener)
   */
  Stream<T> forTarget(EventTarget e, {bool useCapture: false}) =>
    new _EventStream(e, _eventType, useCapture);

  /**
   * Gets an [ElementEventStream] for this event type, on the specified element.
   *
   * This will always return a broadcast stream so multiple listeners can be
   * used simultaneously.
   *
   * This may be used to capture DOM events:
   *
   *     Element.keyDownEvent.forElement(element, useCapture: true).listen(...);
   *
   *     // Alternate method:
   *     Element.keyDownEvent.forElement(element).capture(...);
   *
   * Or for listening to an event which will bubble through the DOM tree:
   *
   *     MediaElement.pauseEvent.forElement(document.body).listen(...);
   *
   * See also:
   *
   * [addEventListener](http://docs.webplatform.org/wiki/dom/methods/addEventListener)
   */
  ElementStream<T> forElement(Element e, {bool useCapture: false}) {
    return new _ElementEventStreamImpl(e, _eventType, useCapture);
  }

  /**
   * Gets an [ElementEventStream] for this event type, on the list of elements.
   *
   * This will always return a broadcast stream so multiple listeners can be
   * used simultaneously.
   *
   * This may be used to capture DOM events:
   *
   *     Element.keyDownEvent._forElementList(element, useCapture: true).listen(...);
   *
   * See also:
   *
   * [addEventListener](http://docs.webplatform.org/wiki/dom/methods/addEventListener)
   */
  ElementStream<T> _forElementList(ElementList e, {bool useCapture: false}) {
    return new _ElementListEventStreamImpl(e, _eventType, useCapture);
  }

  /**
   * Gets the type of the event which this would listen for on the specified
   * event target.
   *
   * The target is necessary because some browsers may use different event names
   * for the same purpose and the target allows differentiating browser support.
   */
  String getEventType(EventTarget target) {
    return _eventType;
  }
}

/** A specialized Stream available to [Element]s to enable event delegation. */
abstract class ElementStream<T extends Event> implements Stream<T> {
  /**
   * Return a stream that only fires when the particular event fires for
   * elements matching the specified CSS selector.
   *
   * This is the Dart equivalent to jQuery's
   * [delegate](http://api.jquery.com/delegate/).
   */
  Stream<T> matches(String selector);

  /**
   * Adds a capturing subscription to this stream.
   *
   * If the target of the event is a descendant of the element from which this
   * stream derives then [onData] is called before the event propagates down to
   * the target. This is the opposite of bubbling behavior, where the event
   * is first processed for the event target and then bubbles upward.
   *
   * ## Other resources
   *
   * * [Event Capture]
   * (http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture)
   * from the W3C DOM Events specification.
   */
  StreamSubscription<T> capture(void onData(T event));
}

/**
 * Adapter for exposing DOM events as Dart streams.
 */
class _EventStream<T extends Event> extends Stream<T> {
  final EventTarget _target;
  final String _eventType;
  final bool _useCapture;

  _EventStream(this._target, this._eventType, this._useCapture);

  // DOM events are inherently multi-subscribers.
  Stream<T> asBroadcastStream({void onListen(StreamSubscription subscription),
                               void onCancel(StreamSubscription subscription)})
      => this;
  bool get isBroadcast => true;

  StreamSubscription<T> listen(void onData(T event),
      { Function onError,
        void onDone(),
        bool cancelOnError}) {

    return new _EventStreamSubscription<T>(
        this._target, this._eventType, onData, this._useCapture);
  }
}

/**
 * Adapter for exposing DOM Element events as streams, while also allowing
 * event delegation.
 */
class _ElementEventStreamImpl<T extends Event> extends _EventStream<T>
    implements ElementStream<T> {
  _ElementEventStreamImpl(target, eventType, useCapture) :
      super(target, eventType, useCapture);

  Stream<T> matches(String selector) => this.where(
      (event) => event.target.matchesWithAncestors(selector)).map((e) {
        e._selector = selector;
        return e;
      });

  StreamSubscription<T> capture(void onData(T event)) =>
    new _EventStreamSubscription<T>(
        this._target, this._eventType, onData, true);
}

/**
 * Adapter for exposing events on a collection of DOM Elements as streams,
 * while also allowing event delegation.
 */
class _ElementListEventStreamImpl<T extends Event> extends Stream<T>
    implements ElementStream<T> {
  final Iterable<Element> _targetList;
  final bool _useCapture;
  final String _eventType;

  _ElementListEventStreamImpl(
      this._targetList, this._eventType, this._useCapture);

  Stream<T> matches(String selector) => this.where(
      (event) => event.target.matchesWithAncestors(selector)).map((e) {
        e._selector = selector;
        return e;
      });

  // Delegate all regular Stream behavior to a wrapped Stream.
  StreamSubscription<T> listen(void onData(T event),
      { Function onError,
        void onDone(),
        bool cancelOnError}) {
    var pool = new _StreamPool.broadcast();
    for (var target in _targetList) {
      pool.add(new _EventStream(target, _eventType, _useCapture));
    }
    return pool.stream.listen(onData, onError: onError, onDone: onDone,
          cancelOnError: cancelOnError);
  }

  StreamSubscription<T> capture(void onData(T event)) {
    var pool = new _StreamPool.broadcast();
    for (var target in _targetList) {
      pool.add(new _EventStream(target, _eventType, true));
    }
    return pool.stream.listen(onData);
  }

  Stream<T> asBroadcastStream({void onListen(StreamSubscription subscription),
                               void onCancel(StreamSubscription subscription)})
      => this;
  bool get isBroadcast => true;
}

class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> {
  int _pauseCount = 0;
  EventTarget _target;
  final String _eventType;
  var _onData;
  final bool _useCapture;

  _EventStreamSubscription(this._target, this._eventType, onData,
      this._useCapture) : _onData = _wrapZone(onData) {
    _tryResume();
  }

  Future cancel() {
    if (_canceled) return null;

    _unlisten();
    // Clear out the target to indicate this is complete.
    _target = null;
    _onData = null;
    return null;
  }

  bool get _canceled => _target == null;

  void onData(void handleData(T event)) {
    if (_canceled) {
      throw new StateError("Subscription has been canceled.");
    }
    // Remove current event listener.
    _unlisten();

    _onData = _wrapZone(handleData);
    _tryResume();
  }

  /// Has no effect.
  void onError(Function handleError) {}

  /// Has no effect.
  void onDone(void handleDone()) {}

  void pause([Future resumeSignal]) {
    if (_canceled) return;
    ++_pauseCount;
    _unlisten();

    if (resumeSignal != null) {
      resumeSignal.whenComplete(resume);
    }
  }

  bool get isPaused => _pauseCount > 0;

  void resume() {
    if (_canceled || !isPaused) return;
    --_pauseCount;
    _tryResume();
  }

  void _tryResume() {
    if (_onData != null && !isPaused) {
      _target.addEventListener(_eventType, _onData, _useCapture);
    }
  }

  void _unlisten() {
    if (_onData != null) {
      _target.removeEventListener(_eventType, _onData, _useCapture);
    }
  }

  Future asFuture([var futureValue]) {
    // We just need a future that will never succeed or fail.
    Completer completer = new Completer();
    return completer.future;
  }
}

/**
 * A stream of custom events, which enables the user to "fire" (add) their own
 * custom events to a stream.
 */
abstract class CustomStream<T extends Event> implements Stream<T> {
  /**
   * Add the following custom event to the stream for dispatching to interested
   * listeners.
   */
  void add(T event);
}

class _CustomEventStreamImpl<T extends Event> extends Stream<T>
    implements CustomStream<T> {
  StreamController<T> _streamController;
  /** The type of event this stream is providing (e.g. "keydown"). */
  String _type;

  _CustomEventStreamImpl(String type) {
    _type = type;
    _streamController = new StreamController.broadcast(sync: true);
  }

  // Delegate all regular Stream behavior to our wrapped Stream.
  StreamSubscription<T> listen(void onData(T event),
      { Function onError,
        void onDone(),
        bool cancelOnError}) {
    return _streamController.stream.listen(onData, onError: onError,
        onDone: onDone, cancelOnError: cancelOnError);
  }

  Stream<T> asBroadcastStream({void onListen(StreamSubscription subscription),
                               void onCancel(StreamSubscription subscription)})
      => _streamController.stream;

  bool get isBroadcast => true;

  void add(T event) {
    if (event.type == _type) _streamController.add(event);
  }
}

class _CustomKeyEventStreamImpl extends _CustomEventStreamImpl<KeyEvent>
    implements CustomStream<KeyEvent> {
  _CustomKeyEventStreamImpl(String type) : super(type);

  void add(KeyEvent event) {
    if (event.type == _type) {
      event.currentTarget.dispatchEvent(event._parent);
      _streamController.add(event);
    }
  }
}

/**
 * A pool of streams whose events are unified and emitted through a central
 * stream.
 */
// TODO (efortuna): Remove this when Issue 12218 is addressed.
class _StreamPool<T> {
  StreamController<T> _controller;

  /// Subscriptions to the streams that make up the pool.
  var _subscriptions = new Map<Stream<T>, StreamSubscription<T>>();

  /**
   * Creates a new stream pool where [stream] can be listened to more than
   * once.
   *
   * Any events from buffered streams in the pool will be emitted immediately,
   * regardless of whether [stream] has any subscribers.
   */
  _StreamPool.broadcast() {
    _controller = new StreamController<T>.broadcast(sync: true,
        onCancel: close);
  }

  /**
   * The stream through which all events from streams in the pool are emitted.
   */
  Stream<T> get stream => _controller.stream;

  /**
   * Adds [stream] as a member of this pool.
   *
   * Any events from [stream] will be emitted through [this.stream]. If
   * [stream] is sync, they'll be emitted synchronously; if [stream] is async,
   * they'll be emitted asynchronously.
   */
  void add(Stream<T> stream) {
    if (_subscriptions.containsKey(stream)) return;
    _subscriptions[stream] = stream.listen(_controller.add,
        onError: _controller.addError,
        onDone: () => remove(stream));
  }

  /** Removes [stream] as a member of this pool. */
  void remove(Stream<T> stream) {
    var subscription = _subscriptions.remove(stream);
    if (subscription != null) subscription.cancel();
  }

  /** Removes all streams from this pool and closes [stream]. */
  void close() {
    for (var subscription in _subscriptions.values) {
      subscription.cancel();
    }
    _subscriptions.clear();
    _controller.close();
  }
}

/**
 * A factory to expose DOM events as streams, where the DOM event name has to
 * be determined on the fly (for example, mouse wheel events).
 */
class _CustomEventStreamProvider<T extends Event>
    implements EventStreamProvider<T> {

  final _eventTypeGetter;
  const _CustomEventStreamProvider(this._eventTypeGetter);

  Stream<T> forTarget(EventTarget e, {bool useCapture: false}) {
    return new _EventStream(e, _eventTypeGetter(e), useCapture);
  }

  ElementStream<T> forElement(Element e, {bool useCapture: false}) {
    return new _ElementEventStreamImpl(e, _eventTypeGetter(e), useCapture);
  }

  ElementStream<T> _forElementList(ElementList e,
      {bool useCapture: false}) {
    return new _ElementListEventStreamImpl(e, _eventTypeGetter(e), useCapture);
  }

  String getEventType(EventTarget target) {
    return _eventTypeGetter(target);
  }

  String get _eventType =>
      throw new UnsupportedError('Access type through getEventType method.');
}
// DO NOT EDIT- this file is generated from running tool/generator.sh.

// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * A Dart DOM validator generated from Caja whitelists.
 *
 * This contains a whitelist of known HTML tagNames and attributes and will only
 * accept known good values.
 *
 * See also:
 *
 * * <https://code.google.com/p/google-caja/wiki/CajaWhitelists>
 */
class _Html5NodeValidator implements NodeValidator {

  static final Set<String> _allowedElements = new Set.from([
    'A',
    'ABBR',
    'ACRONYM',
    'ADDRESS',
    'AREA',
    'ARTICLE',
    'ASIDE',
    'AUDIO',
    'B',
    'BDI',
    'BDO',
    'BIG',
    'BLOCKQUOTE',
    'BR',
    'BUTTON',
    'CANVAS',
    'CAPTION',
    'CENTER',
    'CITE',
    'CODE',
    'COL',
    'COLGROUP',
    'COMMAND',
    'DATA',
    'DATALIST',
    'DD',
    'DEL',
    'DETAILS',
    'DFN',
    'DIR',
    'DIV',
    'DL',
    'DT',
    'EM',
    'FIELDSET',
    'FIGCAPTION',
    'FIGURE',
    'FONT',
    'FOOTER',
    'FORM',
    'H1',
    'H2',
    'H3',
    'H4',
    'H5',
    'H6',
    'HEADER',
    'HGROUP',
    'HR',
    'I',
    'IFRAME',
    'IMG',
    'INPUT',
    'INS',
    'KBD',
    'LABEL',
    'LEGEND',
    'LI',
    'MAP',
    'MARK',
    'MENU',
    'METER',
    'NAV',
    'NOBR',
    'OL',
    'OPTGROUP',
    'OPTION',
    'OUTPUT',
    'P',
    'PRE',
    'PROGRESS',
    'Q',
    'S',
    'SAMP',
    'SECTION',
    'SELECT',
    'SMALL',
    'SOURCE',
    'SPAN',
    'STRIKE',
    'STRONG',
    'SUB',
    'SUMMARY',
    'SUP',
    'TABLE',
    'TBODY',
    'TD',
    'TEXTAREA',
    'TFOOT',
    'TH',
    'THEAD',
    'TIME',
    'TR',
    'TRACK',
    'TT',
    'U',
    'UL',
    'VAR',
    'VIDEO',
    'WBR',
  ]);

  static const _standardAttributes = const <String>[
    '*::class',
    '*::dir',
    '*::draggable',
    '*::hidden',
    '*::id',
    '*::inert',
    '*::itemprop',
    '*::itemref',
    '*::itemscope',
    '*::lang',
    '*::spellcheck',
    '*::title',
    '*::translate',
    'A::accesskey',
    'A::coords',
    'A::hreflang',
    'A::name',
    'A::shape',
    'A::tabindex',
    'A::target',
    'A::type',
    'AREA::accesskey',
    'AREA::alt',
    'AREA::coords',
    'AREA::nohref',
    'AREA::shape',
    'AREA::tabindex',
    'AREA::target',
    'AUDIO::controls',
    'AUDIO::loop',
    'AUDIO::mediagroup',
    'AUDIO::muted',
    'AUDIO::preload',
    'BDO::dir',
    'BODY::alink',
    'BODY::bgcolor',
    'BODY::link',
    'BODY::text',
    'BODY::vlink',
    'BR::clear',
    'BUTTON::accesskey',
    'BUTTON::disabled',
    'BUTTON::name',
    'BUTTON::tabindex',
    'BUTTON::type',
    'BUTTON::value',
    'CANVAS::height',
    'CANVAS::width',
    'CAPTION::align',
    'COL::align',
    'COL::char',
    'COL::charoff',
    'COL::span',
    'COL::valign',
    'COL::width',
    'COLGROUP::align',
    'COLGROUP::char',
    'COLGROUP::charoff',
    'COLGROUP::span',
    'COLGROUP::valign',
    'COLGROUP::width',
    'COMMAND::checked',
    'COMMAND::command',
    'COMMAND::disabled',
    'COMMAND::label',
    'COMMAND::radiogroup',
    'COMMAND::type',
    'DATA::value',
    'DEL::datetime',
    'DETAILS::open',
    'DIR::compact',
    'DIV::align',
    'DL::compact',
    'FIELDSET::disabled',
    'FONT::color',
    'FONT::face',
    'FONT::size',
    'FORM::accept',
    'FORM::autocomplete',
    'FORM::enctype',
    'FORM::method',
    'FORM::name',
    'FORM::novalidate',
    'FORM::target',
    'FRAME::name',
    'H1::align',
    'H2::align',
    'H3::align',
    'H4::align',
    'H5::align',
    'H6::align',
    'HR::align',
    'HR::noshade',
    'HR::size',
    'HR::width',
    'HTML::version',
    'IFRAME::align',
    'IFRAME::frameborder',
    'IFRAME::height',
    'IFRAME::marginheight',
    'IFRAME::marginwidth',
    'IFRAME::width',
    'IMG::align',
    'IMG::alt',
    'IMG::border',
    'IMG::height',
    'IMG::hspace',
    'IMG::ismap',
    'IMG::name',
    'IMG::usemap',
    'IMG::vspace',
    'IMG::width',
    'INPUT::accept',
    'INPUT::accesskey',
    'INPUT::align',
    'INPUT::alt',
    'INPUT::autocomplete',
    'INPUT::checked',
    'INPUT::disabled',
    'INPUT::inputmode',
    'INPUT::ismap',
    'INPUT::list',
    'INPUT::max',
    'INPUT::maxlength',
    'INPUT::min',
    'INPUT::multiple',
    'INPUT::name',
    'INPUT::placeholder',
    'INPUT::readonly',
    'INPUT::required',
    'INPUT::size',
    'INPUT::step',
    'INPUT::tabindex',
    'INPUT::type',
    'INPUT::usemap',
    'INPUT::value',
    'INS::datetime',
    'KEYGEN::disabled',
    'KEYGEN::keytype',
    'KEYGEN::name',
    'LABEL::accesskey',
    'LABEL::for',
    'LEGEND::accesskey',
    'LEGEND::align',
    'LI::type',
    'LI::value',
    'LINK::sizes',
    'MAP::name',
    'MENU::compact',
    'MENU::label',
    'MENU::type',
    'METER::high',
    'METER::low',
    'METER::max',
    'METER::min',
    'METER::value',
    'OBJECT::typemustmatch',
    'OL::compact',
    'OL::reversed',
    'OL::start',
    'OL::type',
    'OPTGROUP::disabled',
    'OPTGROUP::label',
    'OPTION::disabled',
    'OPTION::label',
    'OPTION::selected',
    'OPTION::value',
    'OUTPUT::for',
    'OUTPUT::name',
    'P::align',
    'PRE::width',
    'PROGRESS::max',
    'PROGRESS::min',
    'PROGRESS::value',
    'SELECT::autocomplete',
    'SELECT::disabled',
    'SELECT::multiple',
    'SELECT::name',
    'SELECT::required',
    'SELECT::size',
    'SELECT::tabindex',
    'SOURCE::type',
    'TABLE::align',
    'TABLE::bgcolor',
    'TABLE::border',
    'TABLE::cellpadding',
    'TABLE::cellspacing',
    'TABLE::frame',
    'TABLE::rules',
    'TABLE::summary',
    'TABLE::width',
    'TBODY::align',
    'TBODY::char',
    'TBODY::charoff',
    'TBODY::valign',
    'TD::abbr',
    'TD::align',
    'TD::axis',
    'TD::bgcolor',
    'TD::char',
    'TD::charoff',
    'TD::colspan',
    'TD::headers',
    'TD::height',
    'TD::nowrap',
    'TD::rowspan',
    'TD::scope',
    'TD::valign',
    'TD::width',
    'TEXTAREA::accesskey',
    'TEXTAREA::autocomplete',
    'TEXTAREA::cols',
    'TEXTAREA::disabled',
    'TEXTAREA::inputmode',
    'TEXTAREA::name',
    'TEXTAREA::placeholder',
    'TEXTAREA::readonly',
    'TEXTAREA::required',
    'TEXTAREA::rows',
    'TEXTAREA::tabindex',
    'TEXTAREA::wrap',
    'TFOOT::align',
    'TFOOT::char',
    'TFOOT::charoff',
    'TFOOT::valign',
    'TH::abbr',
    'TH::align',
    'TH::axis',
    'TH::bgcolor',
    'TH::char',
    'TH::charoff',
    'TH::colspan',
    'TH::headers',
    'TH::height',
    'TH::nowrap',
    'TH::rowspan',
    'TH::scope',
    'TH::valign',
    'TH::width',
    'THEAD::align',
    'THEAD::char',
    'THEAD::charoff',
    'THEAD::valign',
    'TR::align',
    'TR::bgcolor',
    'TR::char',
    'TR::charoff',
    'TR::valign',
    'TRACK::default',
    'TRACK::kind',
    'TRACK::label',
    'TRACK::srclang',
    'UL::compact',
    'UL::type',
    'VIDEO::controls',
    'VIDEO::height',
    'VIDEO::loop',
    'VIDEO::mediagroup',
    'VIDEO::muted',
    'VIDEO::preload',
    'VIDEO::width',
  ];

  static const _uriAttributes = const <String>[
    'A::href',
    'AREA::href',
    'BLOCKQUOTE::cite',
    'BODY::background',
    'COMMAND::icon',
    'DEL::cite',
    'FORM::action',
    'IMG::src',
    'INPUT::src',
    'INS::cite',
    'Q::cite',
    'VIDEO::poster',
  ];

  final UriPolicy uriPolicy;

  static final Map<String, Function> _attributeValidators = {};

  /**
   * All known URI attributes will be validated against the UriPolicy, if
   * [uriPolicy] is null then a default UriPolicy will be used.
   */
  _Html5NodeValidator({UriPolicy uriPolicy})
      :uriPolicy = uriPolicy != null ? uriPolicy : new UriPolicy() {

    if (_attributeValidators.isEmpty) {
      for (var attr in _standardAttributes) {
        _attributeValidators[attr] = _standardAttributeValidator;
      }

      for (var attr in _uriAttributes) {
        _attributeValidators[attr] = _uriAttributeValidator;
      }
    }
  }

  bool allowsElement(Element element) {
    return _allowedElements.contains(element.tagName);
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    var tagName = element.tagName;
    var validator = _attributeValidators['$tagName::$attributeName'];
    if (validator == null) {
      validator = _attributeValidators['*::$attributeName'];
    }
    if (validator == null) {
      return false;
    }
    return validator(element, attributeName, value, this);
  }

  static bool _standardAttributeValidator(Element element, String attributeName,
      String value, _Html5NodeValidator context) {
    return true;
  }

  static bool _uriAttributeValidator(Element element, String attributeName,
      String value, _Html5NodeValidator context) {
    return context.uriPolicy.allowsUri(value);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


abstract class ImmutableListMixin<E> implements List<E> {
  // From Iterable<$E>:
  Iterator<E> get iterator {
    // Note: NodeLists are not fixed size. And most probably length shouldn't
    // be cached in both iterator _and_ forEach method. For now caching it
    // for consistency.
    return new FixedSizeListIterator<E>(this);
  }

  // From Collection<E>:
  void add(E value) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  void addAll(Iterable<E> iterable) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  // From List<E>:
  void sort([int compare(E a, E b)]) {
    throw new UnsupportedError("Cannot sort immutable List.");
  }

  void shuffle([Random random]) {
    throw new UnsupportedError("Cannot shuffle immutable List.");
  }

  void insert(int index, E element) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  void insertAll(int index, Iterable<E> iterable) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  void setAll(int index, Iterable<E> iterable) {
    throw new UnsupportedError("Cannot modify an immutable List.");
  }

  E removeAt(int pos) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  E removeLast() {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  bool remove(Object object) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  void removeWhere(bool test(E element)) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  void retainWhere(bool test(E element)) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
    throw new UnsupportedError("Cannot setRange on immutable List.");
  }

  void removeRange(int start, int end) {
    throw new UnsupportedError("Cannot removeRange on immutable List.");
  }

  void replaceRange(int start, int end, Iterable<E> iterable) {
    throw new UnsupportedError("Cannot modify an immutable List.");
  }

  void fillRange(int start, int end, [E fillValue]) {
    throw new UnsupportedError("Cannot modify an immutable List.");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * Defines the keycode values for keys that are returned by
 * KeyboardEvent.keyCode.
 *
 * Important note: There is substantial divergence in how different browsers
 * handle keycodes and their variants in different locales/keyboard layouts. We
 * provide these constants to help make code processing keys more readable.
 */
abstract class KeyCode {
  // These constant names were borrowed from Closure's Keycode enumeration
  // class.
  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keycodes.js.source.html
  static const int WIN_KEY_FF_LINUX = 0;
  static const int MAC_ENTER = 3;
  static const int BACKSPACE = 8;
  static const int TAB = 9;
  /** NUM_CENTER is also NUMLOCK for FF and Safari on Mac. */
  static const int NUM_CENTER = 12;
  static const int ENTER = 13;
  static const int SHIFT = 16;
  static const int CTRL = 17;
  static const int ALT = 18;
  static const int PAUSE = 19;
  static const int CAPS_LOCK = 20;
  static const int ESC = 27;
  static const int SPACE = 32;
  static const int PAGE_UP = 33;
  static const int PAGE_DOWN = 34;
  static const int END = 35;
  static const int HOME = 36;
  static const int LEFT = 37;
  static const int UP = 38;
  static const int RIGHT = 39;
  static const int DOWN = 40;
  static const int NUM_NORTH_EAST = 33;
  static const int NUM_SOUTH_EAST = 34;
  static const int NUM_SOUTH_WEST = 35;
  static const int NUM_NORTH_WEST = 36;
  static const int NUM_WEST = 37;
  static const int NUM_NORTH = 38;
  static const int NUM_EAST = 39;
  static const int NUM_SOUTH = 40;
  static const int PRINT_SCREEN = 44;
  static const int INSERT = 45;
  static const int NUM_INSERT = 45;
  static const int DELETE = 46;
  static const int NUM_DELETE = 46;
  static const int ZERO = 48;
  static const int ONE = 49;
  static const int TWO = 50;
  static const int THREE = 51;
  static const int FOUR = 52;
  static const int FIVE = 53;
  static const int SIX = 54;
  static const int SEVEN = 55;
  static const int EIGHT = 56;
  static const int NINE = 57;
  static const int FF_SEMICOLON = 59;
  static const int FF_EQUALS = 61;
  /**
   * CAUTION: The question mark is for US-keyboard layouts. It varies
   * for other locales and keyboard layouts.
   */
  static const int QUESTION_MARK = 63;
  static const int A = 65;
  static const int B = 66;
  static const int C = 67;
  static const int D = 68;
  static const int E = 69;
  static const int F = 70;
  static const int G = 71;
  static const int H = 72;
  static const int I = 73;
  static const int J = 74;
  static const int K = 75;
  static const int L = 76;
  static const int M = 77;
  static const int N = 78;
  static const int O = 79;
  static const int P = 80;
  static const int Q = 81;
  static const int R = 82;
  static const int S = 83;
  static const int T = 84;
  static const int U = 85;
  static const int V = 86;
  static const int W = 87;
  static const int X = 88;
  static const int Y = 89;
  static const int Z = 90;
  static const int META = 91;
  static const int WIN_KEY_LEFT = 91;
  static const int WIN_KEY_RIGHT = 92;
  static const int CONTEXT_MENU = 93;
  static const int NUM_ZERO = 96;
  static const int NUM_ONE = 97;
  static const int NUM_TWO = 98;
  static const int NUM_THREE = 99;
  static const int NUM_FOUR = 100;
  static const int NUM_FIVE = 101;
  static const int NUM_SIX = 102;
  static const int NUM_SEVEN = 103;
  static const int NUM_EIGHT = 104;
  static const int NUM_NINE = 105;
  static const int NUM_MULTIPLY = 106;
  static const int NUM_PLUS = 107;
  static const int NUM_MINUS = 109;
  static const int NUM_PERIOD = 110;
  static const int NUM_DIVISION = 111;
  static const int F1 = 112;
  static const int F2 = 113;
  static const int F3 = 114;
  static const int F4 = 115;
  static const int F5 = 116;
  static const int F6 = 117;
  static const int F7 = 118;
  static const int F8 = 119;
  static const int F9 = 120;
  static const int F10 = 121;
  static const int F11 = 122;
  static const int F12 = 123;
  static const int NUMLOCK = 144;
  static const int SCROLL_LOCK = 145;

  // OS-specific media keys like volume controls and browser controls.
  static const int FIRST_MEDIA_KEY = 166;
  static const int LAST_MEDIA_KEY = 183;

  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int SEMICOLON = 186;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int DASH = 189;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int EQUALS = 187;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int COMMA = 188;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int PERIOD = 190;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int SLASH = 191;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int APOSTROPHE = 192;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int TILDE = 192;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int SINGLE_QUOTE = 222;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int OPEN_SQUARE_BRACKET = 219;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int BACKSLASH = 220;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int CLOSE_SQUARE_BRACKET = 221;
  static const int WIN_KEY = 224;
  static const int MAC_FF_META = 224;
  static const int WIN_IME = 229;

  /** A sentinel value if the keycode could not be determined. */
  static const int UNKNOWN = -1;

  /**
   * Returns true if the keyCode produces a (US keyboard) character.
   * Note: This does not (yet) cover characters on non-US keyboards (Russian,
   * Hebrew, etc.).
   */
  static bool isCharacterKey(int keyCode) {
    if ((keyCode >= ZERO && keyCode <= NINE) ||
        (keyCode >= NUM_ZERO && keyCode <= NUM_MULTIPLY) ||
        (keyCode >= A && keyCode <= Z)) {
      return true;
    }

    // Safari sends zero key code for non-latin characters.
    if (Device.isWebKit && keyCode == 0) {
      return true;
    }

    return (keyCode == SPACE || keyCode == QUESTION_MARK || keyCode == NUM_PLUS
        || keyCode == NUM_MINUS || keyCode == NUM_PERIOD ||
        keyCode == NUM_DIVISION || keyCode == SEMICOLON ||
        keyCode == FF_SEMICOLON || keyCode == DASH || keyCode == EQUALS ||
        keyCode == FF_EQUALS || keyCode == COMMA || keyCode == PERIOD ||
        keyCode == SLASH || keyCode == APOSTROPHE || keyCode == SINGLE_QUOTE ||
        keyCode == OPEN_SQUARE_BRACKET || keyCode == BACKSLASH ||
        keyCode == CLOSE_SQUARE_BRACKET);
  }

  /**
   * Experimental helper function for converting keyCodes to keyNames for the
   * keyIdentifier attribute still used in browsers not updated with current
   * spec. This is an imperfect conversion! It will need to be refined, but
   * hopefully it can just completely go away once all the browsers update to
   * follow the DOM3 spec.
   */
  static String _convertKeyCodeToKeyName(int keyCode) {
    switch(keyCode) {
      case KeyCode.ALT: return _KeyName.ALT;
      case KeyCode.BACKSPACE: return _KeyName.BACKSPACE;
      case KeyCode.CAPS_LOCK: return _KeyName.CAPS_LOCK;
      case KeyCode.CTRL: return _KeyName.CONTROL;
      case KeyCode.DELETE: return _KeyName.DEL;
      case KeyCode.DOWN: return _KeyName.DOWN;
      case KeyCode.END: return _KeyName.END;
      case KeyCode.ENTER: return _KeyName.ENTER;
      case KeyCode.ESC: return _KeyName.ESC;
      case KeyCode.F1: return _KeyName.F1;
      case KeyCode.F2: return _KeyName.F2;
      case KeyCode.F3: return _KeyName.F3;
      case KeyCode.F4: return _KeyName.F4;
      case KeyCode.F5: return _KeyName.F5;
      case KeyCode.F6: return _KeyName.F6;
      case KeyCode.F7: return _KeyName.F7;
      case KeyCode.F8: return _KeyName.F8;
      case KeyCode.F9: return _KeyName.F9;
      case KeyCode.F10: return _KeyName.F10;
      case KeyCode.F11: return _KeyName.F11;
      case KeyCode.F12: return _KeyName.F12;
      case KeyCode.HOME: return _KeyName.HOME;
      case KeyCode.INSERT: return _KeyName.INSERT;
      case KeyCode.LEFT: return _KeyName.LEFT;
      case KeyCode.META: return _KeyName.META;
      case KeyCode.NUMLOCK: return _KeyName.NUM_LOCK;
      case KeyCode.PAGE_DOWN: return _KeyName.PAGE_DOWN;
      case KeyCode.PAGE_UP: return _KeyName.PAGE_UP;
      case KeyCode.PAUSE: return _KeyName.PAUSE;
      case KeyCode.PRINT_SCREEN: return _KeyName.PRINT_SCREEN;
      case KeyCode.RIGHT: return _KeyName.RIGHT;
      case KeyCode.SCROLL_LOCK: return _KeyName.SCROLL;
      case KeyCode.SHIFT: return _KeyName.SHIFT;
      case KeyCode.SPACE: return _KeyName.SPACEBAR;
      case KeyCode.TAB: return _KeyName.TAB;
      case KeyCode.UP: return _KeyName.UP;
      case KeyCode.WIN_IME:
      case KeyCode.WIN_KEY:
      case KeyCode.WIN_KEY_LEFT:
      case KeyCode.WIN_KEY_RIGHT:
        return _KeyName.WIN;
      default: return _KeyName.UNIDENTIFIED;
    }
    return _KeyName.UNIDENTIFIED;
  }
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * Defines the standard key locations returned by
 * KeyboardEvent.getKeyLocation.
 */
abstract class KeyLocation {

  /**
   * The event key is not distinguished as the left or right version
   * of the key, and did not originate from the numeric keypad (or did not
   * originate with a virtual key corresponding to the numeric keypad).
   */
  static const int STANDARD = 0;

  /**
   * The event key is in the left key location.
   */
  static const int LEFT = 1;

  /**
   * The event key is in the right key location.
   */
  static const int RIGHT = 2;

  /**
   * The event key originated on the numeric keypad or with a virtual key
   * corresponding to the numeric keypad.
   */
  static const int NUMPAD = 3;

  /**
   * The event key originated on a mobile device, either on a physical
   * keypad or a virtual keyboard.
   */
  static const int MOBILE = 4;

  /**
   * The event key originated on a game controller or a joystick on a mobile
   * device.
   */
  static const int JOYSTICK = 5;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * Defines the standard keyboard identifier names for keys that are returned
 * by KeyboardEvent.getKeyboardIdentifier when the key does not have a direct
 * unicode mapping.
 */
abstract class _KeyName {

  /** The Accept (Commit, OK) key */
  static const String ACCEPT = "Accept";

  /** The Add key */
  static const String ADD = "Add";

  /** The Again key */
  static const String AGAIN = "Again";

  /** The All Candidates key */
  static const String ALL_CANDIDATES = "AllCandidates";

  /** The Alphanumeric key */
  static const String ALPHANUMERIC = "Alphanumeric";

  /** The Alt (Menu) key */
  static const String ALT = "Alt";

  /** The Alt-Graph key */
  static const String ALT_GRAPH = "AltGraph";

  /** The Application key */
  static const String APPS = "Apps";

  /** The ATTN key */
  static const String ATTN = "Attn";

  /** The Browser Back key */
  static const String BROWSER_BACK = "BrowserBack";

  /** The Browser Favorites key */
  static const String BROWSER_FAVORTIES = "BrowserFavorites";

  /** The Browser Forward key */
  static const String BROWSER_FORWARD = "BrowserForward";

  /** The Browser Home key */
  static const String BROWSER_NAME = "BrowserHome";

  /** The Browser Refresh key */
  static const String BROWSER_REFRESH = "BrowserRefresh";

  /** The Browser Search key */
  static const String BROWSER_SEARCH = "BrowserSearch";

  /** The Browser Stop key */
  static const String BROWSER_STOP = "BrowserStop";

  /** The Camera key */
  static const String CAMERA = "Camera";

  /** The Caps Lock (Capital) key */
  static const String CAPS_LOCK = "CapsLock";

  /** The Clear key */
  static const String CLEAR = "Clear";

  /** The Code Input key */
  static const String CODE_INPUT = "CodeInput";

  /** The Compose key */
  static const String COMPOSE = "Compose";

  /** The Control (Ctrl) key */
  static const String CONTROL = "Control";

  /** The Crsel key */
  static const String CRSEL = "Crsel";

  /** The Convert key */
  static const String CONVERT = "Convert";

  /** The Copy key */
  static const String COPY = "Copy";

  /** The Cut key */
  static const String CUT = "Cut";

  /** The Decimal key */
  static const String DECIMAL = "Decimal";

  /** The Divide key */
  static const String DIVIDE = "Divide";

  /** The Down Arrow key */
  static const String DOWN = "Down";

  /** The diagonal Down-Left Arrow key */
  static const String DOWN_LEFT = "DownLeft";

  /** The diagonal Down-Right Arrow key */
  static const String DOWN_RIGHT = "DownRight";

  /** The Eject key */
  static const String EJECT = "Eject";

  /** The End key */
  static const String END = "End";

  /**
   * The Enter key. Note: This key value must also be used for the Return
   *  (Macintosh numpad) key
   */
  static const String ENTER = "Enter";

  /** The Erase EOF key */
  static const String ERASE_EOF= "EraseEof";

  /** The Execute key */
  static const String EXECUTE = "Execute";

  /** The Exsel key */
  static const String EXSEL = "Exsel";

  /** The Function switch key */
  static const String FN = "Fn";

  /** The F1 key */
  static const String F1 = "F1";

  /** The F2 key */
  static const String F2 = "F2";

  /** The F3 key */
  static const String F3 = "F3";

  /** The F4 key */
  static const String F4 = "F4";

  /** The F5 key */
  static const String F5 = "F5";

  /** The F6 key */
  static const String F6 = "F6";

  /** The F7 key */
  static const String F7 = "F7";

  /** The F8 key */
  static const String F8 = "F8";

  /** The F9 key */
  static const String F9 = "F9";

  /** The F10 key */
  static const String F10 = "F10";

  /** The F11 key */
  static const String F11 = "F11";

  /** The F12 key */
  static const String F12 = "F12";

  /** The F13 key */
  static const String F13 = "F13";

  /** The F14 key */
  static const String F14 = "F14";

  /** The F15 key */
  static const String F15 = "F15";

  /** The F16 key */
  static const String F16 = "F16";

  /** The F17 key */
  static const String F17 = "F17";

  /** The F18 key */
  static const String F18 = "F18";

  /** The F19 key */
  static const String F19 = "F19";

  /** The F20 key */
  static const String F20 = "F20";

  /** The F21 key */
  static const String F21 = "F21";

  /** The F22 key */
  static const String F22 = "F22";

  /** The F23 key */
  static const String F23 = "F23";

  /** The F24 key */
  static const String F24 = "F24";

  /** The Final Mode (Final) key used on some asian keyboards */
  static const String FINAL_MODE = "FinalMode";

  /** The Find key */
  static const String FIND = "Find";

  /** The Full-Width Characters key */
  static const String FULL_WIDTH = "FullWidth";

  /** The Half-Width Characters key */
  static const String HALF_WIDTH = "HalfWidth";

  /** The Hangul (Korean characters) Mode key */
  static const String HANGUL_MODE = "HangulMode";

  /** The Hanja (Korean characters) Mode key */
  static const String HANJA_MODE = "HanjaMode";

  /** The Help key */
  static const String HELP = "Help";

  /** The Hiragana (Japanese Kana characters) key */
  static const String HIRAGANA = "Hiragana";

  /** The Home key */
  static const String HOME = "Home";

  /** The Insert (Ins) key */
  static const String INSERT = "Insert";

  /** The Japanese-Hiragana key */
  static const String JAPANESE_HIRAGANA = "JapaneseHiragana";

  /** The Japanese-Katakana key */
  static const String JAPANESE_KATAKANA = "JapaneseKatakana";

  /** The Japanese-Romaji key */
  static const String JAPANESE_ROMAJI = "JapaneseRomaji";

  /** The Junja Mode key */
  static const String JUNJA_MODE = "JunjaMode";

  /** The Kana Mode (Kana Lock) key */
  static const String KANA_MODE = "KanaMode";

  /**
   * The Kanji (Japanese name for ideographic characters of Chinese origin)
   * Mode key
   */
  static const String KANJI_MODE = "KanjiMode";

  /** The Katakana (Japanese Kana characters) key */
  static const String KATAKANA = "Katakana";

  /** The Start Application One key */
  static const String LAUNCH_APPLICATION_1 = "LaunchApplication1";

  /** The Start Application Two key */
  static const String LAUNCH_APPLICATION_2 = "LaunchApplication2";

  /** The Start Mail key */
  static const String LAUNCH_MAIL = "LaunchMail";

  /** The Left Arrow key */
  static const String LEFT = "Left";

  /** The Menu key */
  static const String MENU = "Menu";

  /**
   * The Meta key. Note: This key value shall be also used for the Apple
   * Command key
   */
  static const String META = "Meta";

  /** The Media Next Track key */
  static const String MEDIA_NEXT_TRACK = "MediaNextTrack";

  /** The Media Play Pause key */
  static const String MEDIA_PAUSE_PLAY = "MediaPlayPause";

  /** The Media Previous Track key */
  static const String MEDIA_PREVIOUS_TRACK = "MediaPreviousTrack";

  /** The Media Stop key */
  static const String MEDIA_STOP = "MediaStop";

  /** The Mode Change key */
  static const String MODE_CHANGE = "ModeChange";

  /** The Next Candidate function key */
  static const String NEXT_CANDIDATE = "NextCandidate";

  /** The Nonconvert (Don't Convert) key */
  static const String NON_CONVERT = "Nonconvert";

  /** The Number Lock key */
  static const String NUM_LOCK = "NumLock";

  /** The Page Down (Next) key */
  static const String PAGE_DOWN = "PageDown";

  /** The Page Up key */
  static const String PAGE_UP = "PageUp";

  /** The Paste key */
  static const String PASTE = "Paste";

  /** The Pause key */
  static const String PAUSE = "Pause";

  /** The Play key */
  static const String PLAY = "Play";

  /**
   * The Power key. Note: Some devices may not expose this key to the
   * operating environment
   */
  static const String POWER = "Power";

  /** The Previous Candidate function key */
  static const String PREVIOUS_CANDIDATE = "PreviousCandidate";

  /** The Print Screen (PrintScrn, SnapShot) key */
  static const String PRINT_SCREEN = "PrintScreen";

  /** The Process key */
  static const String PROCESS = "Process";

  /** The Props key */
  static const String PROPS = "Props";

  /** The Right Arrow key */
  static const String RIGHT = "Right";

  /** The Roman Characters function key */
  static const String ROMAN_CHARACTERS = "RomanCharacters";

  /** The Scroll Lock key */
  static const String SCROLL = "Scroll";

  /** The Select key */
  static const String SELECT = "Select";

  /** The Select Media key */
  static const String SELECT_MEDIA = "SelectMedia";

  /** The Separator key */
  static const String SEPARATOR = "Separator";

  /** The Shift key */
  static const String SHIFT = "Shift";

  /** The Soft1 key */
  static const String SOFT_1 = "Soft1";

  /** The Soft2 key */
  static const String SOFT_2 = "Soft2";

  /** The Soft3 key */
  static const String SOFT_3 = "Soft3";

  /** The Soft4 key */
  static const String SOFT_4 = "Soft4";

  /** The Stop key */
  static const String STOP = "Stop";

  /** The Subtract key */
  static const String SUBTRACT = "Subtract";

  /** The Symbol Lock key */
  static const String SYMBOL_LOCK = "SymbolLock";

  /** The Up Arrow key */
  static const String UP = "Up";

  /** The diagonal Up-Left Arrow key */
  static const String UP_LEFT = "UpLeft";

  /** The diagonal Up-Right Arrow key */
  static const String UP_RIGHT = "UpRight";

  /** The Undo key */
  static const String UNDO = "Undo";

  /** The Volume Down key */
  static const String VOLUME_DOWN = "VolumeDown";

  /** The Volume Mute key */
  static const String VOLUMN_MUTE = "VolumeMute";

  /** The Volume Up key */
  static const String VOLUMN_UP = "VolumeUp";

  /** The Windows Logo key */
  static const String WIN = "Win";

  /** The Zoom key */
  static const String ZOOM = "Zoom";

  /**
   * The Backspace (Back) key. Note: This key value shall be also used for the
   * key labeled 'delete' MacOS keyboards when not modified by the 'Fn' key
   */
  static const String BACKSPACE = "Backspace";

  /** The Horizontal Tabulation (Tab) key */
  static const String TAB = "Tab";

  /** The Cancel key */
  static const String CANCEL = "Cancel";

  /** The Escape (Esc) key */
  static const String ESC = "Esc";

  /** The Space (Spacebar) key:   */
  static const String SPACEBAR = "Spacebar";

  /**
   * The Delete (Del) Key. Note: This key value shall be also used for the key
   * labeled 'delete' MacOS keyboards when modified by the 'Fn' key
   */
  static const String DEL = "Del";

  /** The Combining Grave Accent (Greek Varia, Dead Grave) key */
  static const String DEAD_GRAVE = "DeadGrave";

  /**
   * The Combining Acute Accent (Stress Mark, Greek Oxia, Tonos, Dead Eacute)
   * key
   */
  static const String DEAD_EACUTE = "DeadEacute";

  /** The Combining Circumflex Accent (Hat, Dead Circumflex) key */
  static const String DEAD_CIRCUMFLEX = "DeadCircumflex";

  /** The Combining Tilde (Dead Tilde) key */
  static const String DEAD_TILDE = "DeadTilde";

  /** The Combining Macron (Long, Dead Macron) key */
  static const String DEAD_MACRON = "DeadMacron";

  /** The Combining Breve (Short, Dead Breve) key */
  static const String DEAD_BREVE = "DeadBreve";

  /** The Combining Dot Above (Derivative, Dead Above Dot) key */
  static const String DEAD_ABOVE_DOT = "DeadAboveDot";

  /**
   * The Combining Diaeresis (Double Dot Abode, Umlaut, Greek Dialytika,
   * Double Derivative, Dead Diaeresis) key
   */
  static const String DEAD_UMLAUT = "DeadUmlaut";

  /** The Combining Ring Above (Dead Above Ring) key */
  static const String DEAD_ABOVE_RING = "DeadAboveRing";

  /** The Combining Double Acute Accent (Dead Doubleacute) key */
  static const String DEAD_DOUBLEACUTE = "DeadDoubleacute";

  /** The Combining Caron (Hacek, V Above, Dead Caron) key */
  static const String DEAD_CARON = "DeadCaron";

  /** The Combining Cedilla (Dead Cedilla) key */
  static const String DEAD_CEDILLA = "DeadCedilla";

  /** The Combining Ogonek (Nasal Hook, Dead Ogonek) key */
  static const String DEAD_OGONEK = "DeadOgonek";

  /**
   * The Combining Greek Ypogegrammeni (Greek Non-Spacing Iota Below, Iota
   * Subscript, Dead Iota) key
   */
  static const String DEAD_IOTA = "DeadIota";

  /**
   * The Combining Katakana-Hiragana Voiced Sound Mark (Dead Voiced Sound) key
   */
  static const String DEAD_VOICED_SOUND = "DeadVoicedSound";

  /**
   * The Combining Katakana-Hiragana Semi-Voiced Sound Mark (Dead Semivoiced
   * Sound) key
   */
  static const String DEC_SEMIVOICED_SOUND= "DeadSemivoicedSound";

  /**
   * Key value used when an implementation is unable to identify another key
   * value, due to either hardware, platform, or software constraints
   */
  static const String UNIDENTIFIED = "Unidentified";
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * Internal class that does the actual calculations to determine keyCode and
 * charCode for keydown, keypress, and keyup events for all browsers.
 */
class _KeyboardEventHandler extends EventStreamProvider<KeyEvent> {
  // This code inspired by Closure's KeyHandling library.
  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keyhandler.js.source.html

  /**
   * The set of keys that have been pressed down without seeing their
   * corresponding keyup event.
   */
  final List<KeyboardEvent> _keyDownList = <KeyboardEvent>[];

  /** The type of KeyEvent we are tracking (keyup, keydown, keypress). */
  final String _type;

  /** The element we are watching for events to happen on. */
  final EventTarget _target;

  // The distance to shift from upper case alphabet Roman letters to lower case.
  static final int _ROMAN_ALPHABET_OFFSET = "a".codeUnits[0] - "A".codeUnits[0];

  /** Custom Stream (Controller) to produce KeyEvents for the stream. */
  _CustomKeyEventStreamImpl _stream;

  static const _EVENT_TYPE = 'KeyEvent';

  /**
   * An enumeration of key identifiers currently part of the W3C draft for DOM3
   * and their mappings to keyCodes.
   * http://www.w3.org/TR/DOM-Level-3-Events/keyset.html#KeySet-Set
   */
  static const Map<String, int> _keyIdentifier = const {
    'Up': KeyCode.UP,
    'Down': KeyCode.DOWN,
    'Left': KeyCode.LEFT,
    'Right': KeyCode.RIGHT,
    'Enter': KeyCode.ENTER,
    'F1': KeyCode.F1,
    'F2': KeyCode.F2,
    'F3': KeyCode.F3,
    'F4': KeyCode.F4,
    'F5': KeyCode.F5,
    'F6': KeyCode.F6,
    'F7': KeyCode.F7,
    'F8': KeyCode.F8,
    'F9': KeyCode.F9,
    'F10': KeyCode.F10,
    'F11': KeyCode.F11,
    'F12': KeyCode.F12,
    'U+007F': KeyCode.DELETE,
    'Home': KeyCode.HOME,
    'End': KeyCode.END,
    'PageUp': KeyCode.PAGE_UP,
    'PageDown': KeyCode.PAGE_DOWN,
    'Insert': KeyCode.INSERT
  };

  /** Return a stream for KeyEvents for the specified target. */
  // Note: this actually functions like a factory constructor.
  CustomStream<KeyEvent> forTarget(EventTarget e, {bool useCapture: false}) {
    var handler = new _KeyboardEventHandler.initializeAllEventListeners(
        _type, e);
    return handler._stream;
  }

  /**
   * General constructor, performs basic initialization for our improved
   * KeyboardEvent controller.
   */
  _KeyboardEventHandler(this._type): super(_EVENT_TYPE),
      _stream = new _CustomKeyEventStreamImpl('event'), _target = null;

  /**
   * Hook up all event listeners under the covers so we can estimate keycodes
   * and charcodes when they are not provided.
   */
  _KeyboardEventHandler.initializeAllEventListeners(this._type, this._target) :
      super(_EVENT_TYPE) {
    Element.keyDownEvent.forTarget(_target, useCapture: true).listen(
        processKeyDown);
    Element.keyPressEvent.forTarget(_target, useCapture: true).listen(
        processKeyPress);
    Element.keyUpEvent.forTarget(_target, useCapture: true).listen(
        processKeyUp);
    _stream = new _CustomKeyEventStreamImpl(_type);
  }

  /** Determine if caps lock is one of the currently depressed keys. */
  bool get _capsLockOn =>
      _keyDownList.any((var element) => element.keyCode == KeyCode.CAPS_LOCK);

  /**
   * Given the previously recorded keydown key codes, see if we can determine
   * the keycode of this keypress [event]. (Generally browsers only provide
   * charCode information for keypress events, but with a little
   * reverse-engineering, we can also determine the keyCode.) Returns
   * KeyCode.UNKNOWN if the keycode could not be determined.
   */
  int _determineKeyCodeForKeypress(KeyboardEvent event) {
    // Note: This function is a work in progress. We'll expand this function
    // once we get more information about other keyboards.
    for (var prevEvent in _keyDownList) {
      if (prevEvent._shadowCharCode == event.charCode) {
        return prevEvent.keyCode;
      }
      if ((event.shiftKey || _capsLockOn) && event.charCode >= "A".codeUnits[0]
          && event.charCode <= "Z".codeUnits[0] && event.charCode +
          _ROMAN_ALPHABET_OFFSET == prevEvent._shadowCharCode) {
        return prevEvent.keyCode;
      }
    }
    return KeyCode.UNKNOWN;
  }

  /**
   * Given the charater code returned from a keyDown [event], try to ascertain
   * and return the corresponding charCode for the character that was pressed.
   * This information is not shown to the user, but used to help polyfill
   * keypress events.
   */
  int _findCharCodeKeyDown(KeyboardEvent event) {
    if (event.keyLocation == 3) { // Numpad keys.
      switch (event.keyCode) {
        case KeyCode.NUM_ZERO:
          // Even though this function returns _charCodes_, for some cases the
          // KeyCode == the charCode we want, in which case we use the keycode
          // constant for readability.
          return KeyCode.ZERO;
        case KeyCode.NUM_ONE:
          return KeyCode.ONE;
        case KeyCode.NUM_TWO:
          return KeyCode.TWO;
        case KeyCode.NUM_THREE:
          return KeyCode.THREE;
        case KeyCode.NUM_FOUR:
          return KeyCode.FOUR;
        case KeyCode.NUM_FIVE:
          return KeyCode.FIVE;
        case KeyCode.NUM_SIX:
          return KeyCode.SIX;
        case KeyCode.NUM_SEVEN:
          return KeyCode.SEVEN;
        case KeyCode.NUM_EIGHT:
          return KeyCode.EIGHT;
        case KeyCode.NUM_NINE:
          return KeyCode.NINE;
        case KeyCode.NUM_MULTIPLY:
          return 42; // Char code for *
        case KeyCode.NUM_PLUS:
          return 43; // +
        case KeyCode.NUM_MINUS:
          return 45; // -
        case KeyCode.NUM_PERIOD:
          return 46; // .
        case KeyCode.NUM_DIVISION:
          return 47; // /
      }
    } else if (event.keyCode >= 65 && event.keyCode <= 90) {
      // Set the "char code" for key down as the lower case letter. Again, this
      // will not show up for the user, but will be helpful in estimating
      // keyCode locations and other information during the keyPress event.
      return event.keyCode + _ROMAN_ALPHABET_OFFSET;
    }
    switch(event.keyCode) {
      case KeyCode.SEMICOLON:
        return KeyCode.FF_SEMICOLON;
      case KeyCode.EQUALS:
        return KeyCode.FF_EQUALS;
      case KeyCode.COMMA:
        return 44; // Ascii value for ,
      case KeyCode.DASH:
        return 45; // -
      case KeyCode.PERIOD:
        return 46; // .
      case KeyCode.SLASH:
        return 47; // /
      case KeyCode.APOSTROPHE:
        return 96; // `
      case KeyCode.OPEN_SQUARE_BRACKET:
        return 91; // [
      case KeyCode.BACKSLASH:
        return 92; // \
      case KeyCode.CLOSE_SQUARE_BRACKET:
        return 93; // ]
      case KeyCode.SINGLE_QUOTE:
        return 39; // '
    }
    return event.keyCode;
  }

  /**
   * Returns true if the key fires a keypress event in the current browser.
   */
  bool _firesKeyPressEvent(KeyEvent event) {
    if (!Device.isIE && !Device.isWebKit) {
      return true;
    }

    if (Device.userAgent.contains('Mac') && event.altKey) {
      return KeyCode.isCharacterKey(event.keyCode);
    }

    // Alt but not AltGr which is represented as Alt+Ctrl.
    if (event.altKey && !event.ctrlKey) {
      return false;
    }

    // Saves Ctrl or Alt + key for IE and WebKit, which won't fire keypress.
    if (!event.shiftKey &&
        (_keyDownList.last.keyCode == KeyCode.CTRL ||
         _keyDownList.last.keyCode == KeyCode.ALT ||
         Device.userAgent.contains('Mac') &&
         _keyDownList.last.keyCode == KeyCode.META)) {
      return false;
    }

    // Some keys with Ctrl/Shift do not issue keypress in WebKit.
    if (Device.isWebKit && event.ctrlKey && event.shiftKey && (
        event.keyCode == KeyCode.BACKSLASH ||
        event.keyCode == KeyCode.OPEN_SQUARE_BRACKET ||
        event.keyCode == KeyCode.CLOSE_SQUARE_BRACKET ||
        event.keyCode == KeyCode.TILDE ||
        event.keyCode == KeyCode.SEMICOLON || event.keyCode == KeyCode.DASH ||
        event.keyCode == KeyCode.EQUALS || event.keyCode == KeyCode.COMMA ||
        event.keyCode == KeyCode.PERIOD || event.keyCode == KeyCode.SLASH ||
        event.keyCode == KeyCode.APOSTROPHE ||
        event.keyCode == KeyCode.SINGLE_QUOTE)) {
      return false;
    }

    switch (event.keyCode) {
      case KeyCode.ENTER:
        // IE9 does not fire keypress on ENTER.
        return !Device.isIE;
      case KeyCode.ESC:
        return !Device.isWebKit;
    }

    return KeyCode.isCharacterKey(event.keyCode);
  }

  /**
   * Normalize the keycodes to the IE KeyCodes (this is what Chrome, IE, and
   * Opera all use).
   */
  int _normalizeKeyCodes(KeyboardEvent event) {
    // Note: This may change once we get input about non-US keyboards.
    if (Device.isFirefox) {
      switch(event.keyCode) {
        case KeyCode.FF_EQUALS:
          return KeyCode.EQUALS;
        case KeyCode.FF_SEMICOLON:
          return KeyCode.SEMICOLON;
        case KeyCode.MAC_FF_META:
          return KeyCode.META;
        case KeyCode.WIN_KEY_FF_LINUX:
          return KeyCode.WIN_KEY;
      }
    }
    return event.keyCode;
  }

  /** Handle keydown events. */
  void processKeyDown(KeyboardEvent e) {
    // Ctrl-Tab and Alt-Tab can cause the focus to be moved to another window
    // before we've caught a key-up event.  If the last-key was one of these
    // we reset the state.
    if (_keyDownList.length > 0 &&
        (_keyDownList.last.keyCode == KeyCode.CTRL && !e.ctrlKey ||
         _keyDownList.last.keyCode == KeyCode.ALT && !e.altKey ||
         Device.userAgent.contains('Mac') &&
         _keyDownList.last.keyCode == KeyCode.META && !e.metaKey)) {
      _keyDownList.clear();
    }

    var event = new KeyEvent.wrap(e);
    event._shadowKeyCode = _normalizeKeyCodes(event);
    // Technically a "keydown" event doesn't have a charCode. This is
    // calculated nonetheless to provide us with more information in giving
    // as much information as possible on keypress about keycode and also
    // charCode.
    event._shadowCharCode = _findCharCodeKeyDown(event);
    if (_keyDownList.length > 0 && event.keyCode != _keyDownList.last.keyCode &&
        !_firesKeyPressEvent(event)) {
      // Some browsers have quirks not firing keypress events where all other
      // browsers do. This makes them more consistent.
      processKeyPress(e);
    }
    _keyDownList.add(event);
    _stream.add(event);
  }

  /** Handle keypress events. */
  void processKeyPress(KeyboardEvent event) {
    var e = new KeyEvent.wrap(event);
    // IE reports the character code in the keyCode field for keypress events.
    // There are two exceptions however, Enter and Escape.
    if (Device.isIE) {
      if (e.keyCode == KeyCode.ENTER || e.keyCode == KeyCode.ESC) {
        e._shadowCharCode = 0;
      } else {
        e._shadowCharCode = e.keyCode;
      }
    } else if (Device.isOpera) {
      // Opera reports the character code in the keyCode field.
      e._shadowCharCode = KeyCode.isCharacterKey(e.keyCode) ? e.keyCode : 0;
    }
    // Now we guestimate about what the keycode is that was actually
    // pressed, given previous keydown information.
    e._shadowKeyCode = _determineKeyCodeForKeypress(e);

    // Correct the key value for certain browser-specific quirks.
    if (e._shadowKeyIdentifier != null &&
        _keyIdentifier.containsKey(e._shadowKeyIdentifier)) {
      // This is needed for Safari Windows because it currently doesn't give a
      // keyCode/which for non printable keys.
      e._shadowKeyCode = _keyIdentifier[e._shadowKeyIdentifier];
    }
    e._shadowAltKey = _keyDownList.any((var element) => element.altKey);
    _stream.add(e);
  }

  /** Handle keyup events. */
  void processKeyUp(KeyboardEvent event) {
    var e = new KeyEvent.wrap(event);
    KeyboardEvent toRemove = null;
    for (var key in _keyDownList) {
      if (key.keyCode == e.keyCode) {
        toRemove = key;
      }
    }
    if (toRemove != null) {
      _keyDownList.removeWhere((element) => element == toRemove);
    } else if (_keyDownList.length > 0) {
      // This happens when we've reached some international keyboard case we
      // haven't accounted for or we haven't correctly eliminated all browser
      // inconsistencies. Filing bugs on when this is reached is welcome!
      _keyDownList.removeLast();
    }
    _stream.add(e);
  }
}


/**
 * Records KeyboardEvents that occur on a particular element, and provides a
 * stream of outgoing KeyEvents with cross-browser consistent keyCode and
 * charCode values despite the fact that a multitude of browsers that have
 * varying keyboard default behavior.
 *
 * Example usage:
 *
 *     KeyboardEventStream.onKeyDown(document.body).listen(
 *         keydownHandlerTest);
 *
 * This class is very much a work in progress, and we'd love to get information
 * on how we can make this class work with as many international keyboards as
 * possible. Bugs welcome!
 */
class KeyboardEventStream {

  /** Named constructor to produce a stream for onKeyPress events. */
  static CustomStream<KeyEvent> onKeyPress(EventTarget target) =>
      new _KeyboardEventHandler('keypress').forTarget(target);

  /** Named constructor to produce a stream for onKeyUp events. */
  static CustomStream<KeyEvent> onKeyUp(EventTarget target) =>
      new _KeyboardEventHandler('keyup').forTarget(target);

  /** Named constructor to produce a stream for onKeyDown events. */
  static CustomStream<KeyEvent> onKeyDown(EventTarget target) =>
      new _KeyboardEventHandler('keydown').forTarget(target);
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.



/**
 * Class which helps construct standard node validation policies.
 *
 * By default this will not accept anything, but the 'allow*' functions can be
 * used to expand what types of elements or attributes are allowed.
 *
 * All allow functions are additive- elements will be accepted if they are
 * accepted by any specific rule.
 *
 * It is important to remember that sanitization is not just intended to prevent
 * cross-site scripting attacks, but also to prevent information from being
 * displayed in unexpected ways. For example something displaying basic
 * formatted text may not expect `<video>` tags to appear. In this case an
 * empty NodeValidatorBuilder with just [allowTextElements] might be
 * appropriate.
 */
class NodeValidatorBuilder implements NodeValidator {

  final List<NodeValidator> _validators = <NodeValidator>[];

  NodeValidatorBuilder() {
  }

  /**
   * Creates a new NodeValidatorBuilder which accepts common constructs.
   *
   * By default this will accept HTML5 elements and attributes with the default
   * [UriPolicy] and templating elements.
   *
   * Notable syntax which is filtered:
   *
   * * Only known-good HTML5 elements and attributes are allowed.
   * * All URLs must be same-origin, use [allowNavigation] and [allowImages] to
   * specify additional URI policies.
   * * Inline-styles are not allowed.
   * * Custom element tags are disallowed, use [allowCustomElement].
   * * Custom tags extensions are disallowed, use [allowTagExtension].
   * * SVG Elements are not allowed, use [allowSvg].
   *
   * For scenarios where the HTML should only contain formatted text
   * [allowTextElements] is more appropriate.
   *
   * Use [allowSvg] to allow SVG elements.
   */
  NodeValidatorBuilder.common() {
    allowHtml5();
    allowTemplating();
  }

  /**
   * Allows navigation elements- Form and Anchor tags, along with common
   * attributes.
   *
   * The UriPolicy can be used to restrict the locations the navigation elements
   * are allowed to direct to. By default this will use the default [UriPolicy].
   */
  void allowNavigation([UriPolicy uriPolicy]) {
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }
    add(new _SimpleNodeValidator.allowNavigation(uriPolicy));
  }

  /**
   * Allows image elements.
   *
   * The UriPolicy can be used to restrict the locations the images may be
   * loaded from. By default this will use the default [UriPolicy].
   */
  void allowImages([UriPolicy uriPolicy]) {
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }
    add(new _SimpleNodeValidator.allowImages(uriPolicy));
  }

  /**
   * Allow basic text elements.
   *
   * This allows a subset of HTML5 elements, specifically just these tags and
   * no attributes.
   *
   * * B
   * * BLOCKQUOTE
   * * BR
   * * EM
   * * H1
   * * H2
   * * H3
   * * H4
   * * H5
   * * H6
   * * HR
   * * I
   * * LI
   * * OL
   * * P
   * * SPAN
   * * UL
   */
  void allowTextElements() {
    add(new _SimpleNodeValidator.allowTextElements());
  }

  /**
   * Allow inline styles on elements.
   *
   * If [tagName] is not specified then this allows inline styles on all
   * elements. Otherwise tagName limits the styles to the specified elements.
   */
  void allowInlineStyles({String tagName}) {
    if (tagName == null) {
      tagName = '*';
    } else {
      tagName = tagName.toUpperCase();
    }
    add(new _SimpleNodeValidator(null, allowedAttributes: ['$tagName::style']));
  }

  /**
   * Allow common safe HTML5 elements and attributes.
   *
   * This list is based off of the Caja whitelists at:
   * https://code.google.com/p/google-caja/wiki/CajaWhitelists.
   *
   * Common things which are not allowed are script elements, style attributes
   * and any script handlers.
   */
  void allowHtml5({UriPolicy uriPolicy}) {
    add(new _Html5NodeValidator(uriPolicy: uriPolicy));
  }

  /**
   * Allow SVG elements and attributes except for known bad ones.
   */
  void allowSvg() {
    add(new _SvgNodeValidator());
  }

  /**
   * Allow custom elements with the specified tag name and specified attributes.
   *
   * This will allow the elements as custom tags (such as <x-foo></x-foo>),
   * but will not allow tag extensions. Use [allowTagExtension] to allow
   * tag extensions.
   */
  void allowCustomElement(String tagName,
      {UriPolicy uriPolicy,
      Iterable<String> attributes,
      Iterable<String> uriAttributes}) {

    var tagNameUpper = tagName.toUpperCase();
    var attrs;
    if (attributes != null) {
      attrs =
          attributes.map((name) => '$tagNameUpper::${name.toLowerCase()}');
    }
    var uriAttrs;
    if (uriAttributes != null) {
      uriAttrs =
          uriAttributes.map((name) => '$tagNameUpper::${name.toLowerCase()}');
    }
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }

    add(new _CustomElementNodeValidator(
        uriPolicy,
        [tagNameUpper],
        attrs,
        uriAttrs,
        false,
        true));
  }

  /**
   * Allow custom tag extensions with the specified type name and specified
   * attributes.
   *
   * This will allow tag extensions (such as <div is="x-foo"></div>),
   * but will not allow custom tags. Use [allowCustomElement] to allow
   * custom tags.
   */
  void allowTagExtension(String tagName, String baseName,
      {UriPolicy uriPolicy,
      Iterable<String> attributes,
      Iterable<String> uriAttributes}) {

    var baseNameUpper = baseName.toUpperCase();
    var tagNameUpper = tagName.toUpperCase();
    var attrs;
    if (attributes != null) {
      attrs =
          attributes.map((name) => '$baseNameUpper::${name.toLowerCase()}');
    }
    var uriAttrs;
    if (uriAttributes != null) {
      uriAttrs =
          uriAttributes.map((name) => '$baseNameUpper::${name.toLowerCase()}');
    }
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }

    add(new _CustomElementNodeValidator(
        uriPolicy,
        [tagNameUpper, baseNameUpper],
        attrs,
        uriAttrs,
        true,
        false));
  }

  void allowElement(String tagName, {UriPolicy uriPolicy,
    Iterable<String> attributes,
    Iterable<String> uriAttributes}) {

    allowCustomElement(tagName, uriPolicy: uriPolicy,
        attributes: attributes,
        uriAttributes: uriAttributes);
  }

  /**
   * Allow templating elements (such as <template> and template-related
   * attributes.
   *
   * This still requires other validators to allow regular attributes to be
   * bound (such as [allowHtml5]).
   */
  void allowTemplating() {
    add(new _TemplatingNodeValidator());
  }

  /**
   * Add an additional validator to the current list of validators.
   *
   * Elements and attributes will be accepted if they are accepted by any
   * validators.
   */
  void add(NodeValidator validator) {
    _validators.add(validator);
  }

  bool allowsElement(Element element) {
    return _validators.any((v) => v.allowsElement(element));
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    return _validators.any(
        (v) => v.allowsAttribute(element, attributeName, value));
  }
}

class _SimpleNodeValidator implements NodeValidator {
  final Set<String> allowedElements;
  final Set<String> allowedAttributes;
  final Set<String> allowedUriAttributes;
  final UriPolicy uriPolicy;

  factory _SimpleNodeValidator.allowNavigation(UriPolicy uriPolicy) {
    return new _SimpleNodeValidator(uriPolicy,
      allowedElements: [
        'A',
        'FORM'],
      allowedAttributes: [
        'A::accesskey',
        'A::coords',
        'A::hreflang',
        'A::name',
        'A::shape',
        'A::tabindex',
        'A::target',
        'A::type',
        'FORM::accept',
        'FORM::autocomplete',
        'FORM::enctype',
        'FORM::method',
        'FORM::name',
        'FORM::novalidate',
        'FORM::target',
      ],
      allowedUriAttributes: [
        'A::href',
        'FORM::action',
      ]);
  }

  factory _SimpleNodeValidator.allowImages(UriPolicy uriPolicy) {
    return new _SimpleNodeValidator(uriPolicy,
      allowedElements: [
        'IMG'
      ],
      allowedAttributes: [
        'IMG::align',
        'IMG::alt',
        'IMG::border',
        'IMG::height',
        'IMG::hspace',
        'IMG::ismap',
        'IMG::name',
        'IMG::usemap',
        'IMG::vspace',
        'IMG::width',
      ],
      allowedUriAttributes: [
        'IMG::src',
      ]);
  }

  factory _SimpleNodeValidator.allowTextElements() {
    return new _SimpleNodeValidator(null,
      allowedElements: [
        'B',
        'BLOCKQUOTE',
        'BR',
        'EM',
        'H1',
        'H2',
        'H3',
        'H4',
        'H5',
        'H6',
        'HR',
        'I',
        'LI',
        'OL',
        'P',
        'SPAN',
        'UL',
      ]);
  }

  /**
   * Elements must be uppercased tag names. For example `'IMG'`.
   * Attributes must be uppercased tag name followed by :: followed by
   * lowercase attribute name. For example `'IMG:src'`.
   */
  _SimpleNodeValidator(this.uriPolicy,
      {Iterable<String> allowedElements, Iterable<String> allowedAttributes,
      Iterable<String> allowedUriAttributes}):
      this.allowedElements = allowedElements != null ?
          new Set.from(allowedElements) : new Set(),
      this.allowedAttributes = allowedAttributes != null ?
          new Set.from(allowedAttributes) : new Set(),
      this.allowedUriAttributes = allowedUriAttributes != null ?
          new Set.from(allowedUriAttributes) : new Set();

  bool allowsElement(Element element) {
    return allowedElements.contains(element.tagName);
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    var tagName = element.tagName;
    if (allowedUriAttributes.contains('$tagName::$attributeName')) {
      return uriPolicy.allowsUri(value);
    } else if (allowedUriAttributes.contains('*::$attributeName')) {
      return uriPolicy.allowsUri(value);
    } else if (allowedAttributes.contains('$tagName::$attributeName')) {
      return true;
    } else if (allowedAttributes.contains('*::$attributeName')) {
      return true;
    } else if (allowedAttributes.contains('$tagName::*')) {
      return true;
    } else if (allowedAttributes.contains('*::*')) {
      return true;
    }
    return false;
  }
}

class _CustomElementNodeValidator extends _SimpleNodeValidator {
  final bool allowTypeExtension;
  final bool allowCustomTag;

  _CustomElementNodeValidator(UriPolicy uriPolicy,
      Iterable<String> allowedElements,
      Iterable<String> allowedAttributes,
      Iterable<String> allowedUriAttributes,
      bool allowTypeExtension,
      bool allowCustomTag):

      super(uriPolicy,
          allowedElements: allowedElements,
          allowedAttributes: allowedAttributes,
          allowedUriAttributes: allowedUriAttributes),
      this.allowTypeExtension = allowTypeExtension == true,
      this.allowCustomTag = allowCustomTag == true;

  bool allowsElement(Element element) {
    if (allowTypeExtension) {
      var isAttr = element.attributes['is'];
      if (isAttr != null) {
        return allowedElements.contains(isAttr.toUpperCase()) &&
          allowedElements.contains(element.tagName);
      }
    }
    return allowCustomTag && allowedElements.contains(element.tagName);
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
   if (allowsElement(element)) {
      if (allowTypeExtension && attributeName == 'is' &&
          allowedElements.contains(value.toUpperCase())) {
        return true;
      }
      return super.allowsAttribute(element, attributeName, value);
    }
    return false;
  }
}

class _TemplatingNodeValidator extends _SimpleNodeValidator {
  static const _TEMPLATE_ATTRS =
      const <String>['bind', 'if', 'ref', 'repeat', 'syntax'];

  final Set<String> _templateAttrs;

  _TemplatingNodeValidator():
      super(null,
          allowedElements: [
            'TEMPLATE'
          ],
          allowedAttributes: _TEMPLATE_ATTRS.map((attr) => 'TEMPLATE::$attr')),
      _templateAttrs = new Set<String>.from(_TEMPLATE_ATTRS) {
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (super.allowsAttribute(element, attributeName, value)) {
      return true;
    }

    if (attributeName == 'template' && value == "") {
      return true;
    }

    if (element.attributes['template'] == "" ) {
      return _templateAttrs.contains(attributeName);
    }
    return false;
  }
}


class _SvgNodeValidator implements NodeValidator {
  bool allowsElement(Element element) {
    if (element is svg.ScriptElement) {
      return false;
    }
    if (element is svg.SvgElement) {
      return true;
    }
    return false;
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (attributeName == 'is' || attributeName.startsWith('on')) {
      return false;
    }
    return allowsElement(element);
  }
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * Contains the set of standard values returned by HTMLDocument.getReadyState.
 */
abstract class ReadyState {
  /**
   * Indicates the document is still loading and parsing.
   */
  static const String LOADING = "loading";

  /**
   * Indicates the document is finished parsing but is still loading
   * subresources.
   */
  static const String INTERACTIVE = "interactive";

  /**
   * Indicates the document and all subresources have been loaded.
   */
  static const String COMPLETE = "complete";
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.



/**
 * Interface used to validate that only accepted elements and attributes are
 * allowed while parsing HTML strings into DOM nodes.
 *
 * In general, customization of validation behavior should be done via the
 * [NodeValidatorBuilder] class to mitigate the chances of incorrectly
 * implementing validation rules.
 */
abstract class NodeValidator {

  /**
   * Construct a default NodeValidator which only accepts whitelisted HTML5
   * elements and attributes.
   *
   * If a uriPolicy is not specified then the default uriPolicy will be used.
   */
  factory NodeValidator({UriPolicy uriPolicy}) =>
      new _Html5NodeValidator(uriPolicy: uriPolicy);

  factory NodeValidator.throws(NodeValidator base) =>
      new _ThrowsNodeValidator(base);

  /**
   * Returns true if the tagName is an accepted type.
   */
  bool allowsElement(Element element);

  /**
   * Returns true if the attribute is allowed.
   *
   * The attributeName parameter will always be in lowercase.
   *
   * See [allowsElement] for format of tagName.
   */
  bool allowsAttribute(Element element, String attributeName, String value);
}

/**
 * Performs sanitization of a node tree after construction to ensure that it
 * does not contain any disallowed elements or attributes.
 *
 * In general custom implementations of this class should not be necessary and
 * all validation customization should be done in custom NodeValidators, but
 * custom implementations of this class can be created to perform more complex
 * tree sanitization.
 */
abstract class NodeTreeSanitizer {

  /**
   * Constructs a default tree sanitizer which will remove all elements and
   * attributes which are not allowed by the provided validator.
   */
  factory NodeTreeSanitizer(NodeValidator validator) =>
      new _ValidatingTreeSanitizer(validator);

  /**
   * Called with the root of the tree which is to be sanitized.
   *
   * This method needs to walk the entire tree and either remove elements and
   * attributes which are not recognized as safe or throw an exception which
   * will mark the entire tree as unsafe.
   */
  void sanitizeTree(Node node);
}

/**
 * Defines the policy for what types of uris are allowed for particular
 * attribute values.
 *
 * This can be used to provide custom rules such as allowing all http:// URIs
 * for image attributes but only same-origin URIs for anchor tags.
 */
abstract class UriPolicy {
  /**
   * Constructs the default UriPolicy which is to only allow Uris to the same
   * origin as the application was launched from.
   *
   * This will block all ftp: mailto: URIs. It will also block accessing
   * https://example.com if the app is running from http://example.com.
   */
  factory UriPolicy() => new _SameOriginUriPolicy();

  /**
   * Checks if the uri is allowed on the specified attribute.
   *
   * The uri provided may or may not be a relative path.
   */
  bool allowsUri(String uri);
}

/**
 * Allows URIs to the same origin as the current application was loaded from
 * (such as https://example.com:80).
 */
class _SameOriginUriPolicy implements UriPolicy {
  final AnchorElement _hiddenAnchor = new AnchorElement();
  final Location _loc = window.location;

  bool allowsUri(String uri) {
    _hiddenAnchor.href = uri;
    // IE leaves an empty hostname for same-origin URIs.
    return (_hiddenAnchor.hostname == _loc.hostname &&
        _hiddenAnchor.port == _loc.port &&
        _hiddenAnchor.protocol == _loc.protocol) ||
        (_hiddenAnchor.hostname == '' &&
        _hiddenAnchor.port == '' &&
        _hiddenAnchor.protocol == ':');
  }
}


class _ThrowsNodeValidator implements NodeValidator {
  final NodeValidator validator;

  _ThrowsNodeValidator(this.validator) {}

  bool allowsElement(Element element) {
    if (!validator.allowsElement(element)) {
      throw new ArgumentError(element.tagName);
    }
    return true;
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (!validator.allowsAttribute(element, attributeName, value)) {
      throw new ArgumentError('${element.tagName}[$attributeName="$value"]');
    }
  }
}


/**
 * Standard tree sanitizer which validates a node tree against the provided
 * validator and removes any nodes or attributes which are not allowed.
 */
class _ValidatingTreeSanitizer implements NodeTreeSanitizer {
  NodeValidator validator;
  _ValidatingTreeSanitizer(this.validator) {}

  void sanitizeTree(Node node) {
    void walk(Node node) {
      sanitizeNode(node);

      var child = node.lastChild;
      while (child != null) {
        // Child may be removed during the walk.
        var nextChild = child.previousNode;
        walk(child);
        child = nextChild;
      }
    }
    walk(node);
  }

  void sanitizeNode(Node node) {
    switch (node.nodeType) {
      case Node.ELEMENT_NODE:
        Element element = node;
        var attrs = element.attributes;
        if (!validator.allowsElement(element)) {
          window.console.warn(
              'Removing disallowed element <${element.tagName}>');
          element.remove();
          break;
        }

        var isAttr = attrs['is'];
        if (isAttr != null) {
          if (!validator.allowsAttribute(element, 'is', isAttr)) {
            window.console.warn('Removing disallowed type extension '
                '<${element.tagName} is="$isAttr">');
            element.remove();
            break;
          }
        }

        // TODO(blois): Need to be able to get all attributes, irrespective of
        // XMLNS.
        var keys = attrs.keys.toList();
        for (var i = attrs.length - 1; i >= 0; --i) {
          var name = keys[i];
          if (!validator.allowsAttribute(element, name.toLowerCase(),
              attrs[name])) {
            window.console.warn('Removing disallowed attribute '
                '<${element.tagName} $name="${attrs[name]}">');
            attrs.remove(name);
          }
        }

        if (element is TemplateElement) {
          TemplateElement template = element;
          sanitizeTree(template.content);
        }
        break;
      case Node.COMMENT_NODE:
      case Node.DOCUMENT_FRAGMENT_NODE:
      case Node.TEXT_NODE:
      case Node.CDATA_SECTION_NODE:
        break;
      default:
        node.remove();
    }
  }
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * A list which just wraps another list, for either intercepting list calls or
 * retyping the list (for example, from List<A> to List<B> where B extends A).
 */
class _WrappedList<E extends Node> extends ListBase<E>
    implements NodeListWrapper {
  final List _list;

  _WrappedList(this._list);

  // Iterable APIs

  Iterator<E> get iterator => new _WrappedIterator(_list.iterator);

  int get length => _list.length;

  // Collection APIs

  void add(E element) { _list.add(element); }

  bool remove(Object element) => _list.remove(element);

  void clear() { _list.clear(); }

  // List APIs

  E operator [](int index) => _list[index];

  void operator []=(int index, E value) { _list[index] = value; }

  void set length(int newLength) { _list.length = newLength; }

  void sort([int compare(E a, E b)]) { _list.sort(compare); }

  int indexOf(Object element, [int start = 0]) => _list.indexOf(element, start);

  int lastIndexOf(Object element, [int start]) => _list.lastIndexOf(element, start);

  void insert(int index, E element) => _list.insert(index, element);

  E removeAt(int index) => _list.removeAt(index);

  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
    _list.setRange(start, end, iterable, skipCount);
  }

  void removeRange(int start, int end) { _list.removeRange(start, end); }

  void replaceRange(int start, int end, Iterable<E> iterable) {
    _list.replaceRange(start, end, iterable);
  }

  void fillRange(int start, int end, [E fillValue]) {
    _list.fillRange(start, end, fillValue);
  }

  List<Node> get rawList => _list;
}

/**
 * Iterator wrapper for _WrappedList.
 */
class _WrappedIterator<E> implements Iterator<E> {
  Iterator _iterator;

  _WrappedIterator(this._iterator);

  bool moveNext() {
    return _iterator.moveNext();
  }

  E get current => _iterator.current;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


class _HttpRequestUtils {

  // Helper for factory HttpRequest.get
  static HttpRequest get(String url,
                            onComplete(HttpRequest request),
                            bool withCredentials) {
    final request = new HttpRequest();
    request.open('GET', url, async: true);

    request.withCredentials = withCredentials;

    request.onReadyStateChange.listen((e) {
      if (request.readyState == HttpRequest.DONE) {
        onComplete(request);
      }
    });

    request.send();

    return request;
  }
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


// Iterator for arrays with fixed size.
class FixedSizeListIterator<T> implements Iterator<T> {
  final List<T> _array;
  final int _length;  // Cache array length for faster access.
  int _position;
  T _current;
  
  FixedSizeListIterator(List<T> array)
      : _array = array,
        _position = -1,
        _length = array.length;

  bool moveNext() {
    int nextPosition = _position + 1;
    if (nextPosition < _length) {
      _current = _array[nextPosition];
      _position = nextPosition;
      return true;
    }
    _current = null;
    _position = _length;
    return false;
  }

  T get current => _current;
}

// Iterator for arrays with variable size.
class _VariableSizeListIterator<T> implements Iterator<T> {
  final List<T> _array;
  int _position;
  T _current;

  _VariableSizeListIterator(List<T> array)
      : _array = array,
        _position = -1;

  bool moveNext() {
    int nextPosition = _position + 1;
    if (nextPosition < _array.length) {
      _current = _array[nextPosition];
      _position = nextPosition;
      return true;
    }
    _current = null;
    _position = _array.length;
    return false;
  }

  T get current => _current;
}
// Copyright (c) 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.


/// Dartium ElementUpgrader implementation.
class _VMElementUpgrader implements ElementUpgrader {
  final Type _type;
  final Type _nativeType;

  _VMElementUpgrader(Document document, Type type, String extendsTag) :
      _type = type,
      _nativeType = _validateCustomType(type).reflectedType {

    if (extendsTag == null) {
      if (_nativeType != HtmlElement) {
        throw new UnsupportedError('Class must provide extendsTag if base '
              'native class is not HtmlElement');
      }
    } else {
      if (document.createElement(extendsTag).runtimeType != _nativeType) {
        throw new UnsupportedError(
            'extendsTag does not match base native class');
      }
    }
  }

  Element upgrade(Element element) {
    if (element.runtimeType != _nativeType) {
      throw new UnsupportedError('Element is incorrect type');
    }
    return _Utils.changeElementWrapper(element, _type);
  }
}

/// Validates that the custom type is properly formed-
///
/// * Is a user-defined class.
/// * Has a created constructor with zero args.
/// * Derives from an Element subclass.
///
/// Then returns the native base class.
ClassMirror _validateCustomType(Type type) {
  ClassMirror cls = reflectClass(type);
  if (_isBuiltinType(cls)) {
    throw new UnsupportedError('Invalid custom element from '
        '${(cls.owner as LibraryMirror).uri}.');
  }

  var className = MirrorSystem.getName(cls.simpleName);
  var createdConstructor = cls.declarations[new Symbol('$className.created')];
  if (createdConstructor == null ||
      createdConstructor is! MethodMirror ||
      !createdConstructor.isConstructor) {
    throw new UnsupportedError(
        'Class is missing constructor $className.created');
  }

  if (createdConstructor.parameters.length > 0) {
    throw new UnsupportedError(
        'Constructor $className.created must take zero arguments');
  }

  Symbol objectName = reflectClass(Object).qualifiedName;
  bool isRoot(ClassMirror cls) =>
      cls == null || cls.qualifiedName == objectName;
  Symbol elementName = reflectClass(HtmlElement).qualifiedName;
  bool isElement(ClassMirror cls) =>
      cls != null && cls.qualifiedName == elementName;
  ClassMirror superClass = cls.superclass;
  ClassMirror nativeClass = _isBuiltinType(superClass) ? superClass : null;
  while(!isRoot(superClass) && !isElement(superClass)) {
    superClass = superClass.superclass;
    if (nativeClass == null && _isBuiltinType(superClass)) {
      nativeClass = superClass;
    }
  }
  return nativeClass;
}


bool _isBuiltinType(ClassMirror cls) {
  // TODO(vsm): Find a less hackish way to do this.
  LibraryMirror lib = cls.owner;
  String libName = lib.uri.toString();
  return libName.startsWith('dart:');
}
/**
 * A custom KeyboardEvent that attempts to eliminate cross-browser
 * inconsistencies, and also provide both keyCode and charCode information
 * for all key events (when such information can be determined).
 *
 * KeyEvent tries to provide a higher level, more polished keyboard event
 * information on top of the "raw" [KeyboardEvent].
 *
 * The mechanics of using KeyEvents is a little different from the underlying
 * [KeyboardEvent]. To use KeyEvents, you need to create a stream and then add
 * KeyEvents to the stream, rather than using the [EventTarget.dispatchEvent].
 * Here's an example usage:
 *
 *     // Initialize a stream for the KeyEvents:
 *     var stream = KeyEvent.keyPressEvent.forTarget(document.body);
 *     // Start listening to the stream of KeyEvents.
 *     stream.listen((keyEvent) =>
 *         window.console.log('KeyPress event detected ${keyEvent.charCode}'));
 *     ...
 *     // Add a new KeyEvent of someone pressing the 'A' key to the stream so
 *     // listeners can know a KeyEvent happened.
 *     stream.add(new KeyEvent('keypress', keyCode: 65, charCode: 97));
 *
 * This class is very much a work in progress, and we'd love to get information
 * on how we can make this class work with as many international keyboards as
 * possible. Bugs welcome!
 */

@Experimental()
class KeyEvent extends _WrappedEvent implements KeyboardEvent {
  /** The parent KeyboardEvent that this KeyEvent is wrapping and "fixing". */
  KeyboardEvent _parent;

  /** The "fixed" value of whether the alt key is being pressed. */
  bool _shadowAltKey;

  /** Caculated value of what the estimated charCode is for this event. */
  int _shadowCharCode;

  /** Caculated value of what the estimated keyCode is for this event. */
  int _shadowKeyCode;

  /** Caculated value of what the estimated keyCode is for this event. */
  int get keyCode => _shadowKeyCode;

  /** Caculated value of what the estimated charCode is for this event. */
  int get charCode => this.type == 'keypress' ? _shadowCharCode : 0;

  /** Caculated value of whether the alt key is pressed is for this event. */
  bool get altKey => _shadowAltKey;

  /** Caculated value of what the estimated keyCode is for this event. */
  int get which => keyCode;

  /** Accessor to the underlying keyCode value is the parent event. */
  int get _realKeyCode => _parent.keyCode;

  /** Accessor to the underlying charCode value is the parent event. */
  int get _realCharCode => _parent.charCode;

  /** Accessor to the underlying altKey value is the parent event. */
  bool get _realAltKey => _parent.altKey;

  /** Shadows on top of the parent's currentTarget. */
  EventTarget _currentTarget;

  /** 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 == null? window :
        _parent.currentTarget;
  }

  /** Programmatically create a new KeyEvent (and KeyboardEvent). */
   factory KeyEvent(String type,
      {Window view, bool canBubble: true, bool cancelable: true, int keyCode: 0,
      int charCode: 0, int keyLocation: 1, bool ctrlKey: false,
      bool altKey: false, bool shiftKey: false, bool metaKey: false,
       EventTarget currentTarget}) {
     var parent = new KeyboardEvent(type, view: view, canBubble: canBubble,
        cancelable: cancelable, keyLocation: keyLocation, ctrlKey: ctrlKey,
        altKey: altKey, shiftKey: shiftKey, metaKey: metaKey);
     var keyEvent = new KeyEvent.wrap(parent);
     keyEvent._shadowAltKey = altKey;
     keyEvent._shadowCharCode = charCode;
     keyEvent._shadowKeyCode = keyCode;
     keyEvent._currentTarget = currentTarget == null ? window : currentTarget;
     return keyEvent;
   }

  /** 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');

  /** The currently registered target for this event. */
  EventTarget get currentTarget => _currentTarget;

  /** Accessor to the clipboardData available for this event. */
  DataTransfer get clipboardData => _parent.clipboardData;
  /** True if the ctrl key is pressed during this event. */
  bool get ctrlKey => _parent.ctrlKey;
  int get detail => _parent.detail;
  /**
   * Accessor to the part of the keyboard that the key was pressed from (one of
   * KeyLocation.STANDARD, KeyLocation.RIGHT, KeyLocation.LEFT,
   * KeyLocation.NUMPAD, KeyLocation.MOBILE, KeyLocation.JOYSTICK).
   */
  int get keyLocation => _parent.keyLocation;
  Point get layer => _parent.layer;
  /** True if the Meta (or Mac command) key is pressed during this event. */
  bool get metaKey => _parent.metaKey;
  Point get page => _parent.page;
  /** True if the shift key was pressed during this event. */
  bool get shiftKey => _parent.shiftKey;
  Window get view => _parent.view;
  void _initUIEvent(String type, bool canBubble, bool cancelable,
      Window view, int detail) {
    throw new UnsupportedError("Cannot initialize a UI Event from a KeyEvent.");
  }
  String get _shadowKeyIdentifier => _parent._keyIdentifier;

  int get _charCode => charCode;
  int get _keyCode => keyCode;
  String get _keyIdentifier {
    throw new UnsupportedError("keyIdentifier is unsupported.");
  }
  void _initKeyboardEvent(String type, bool canBubble, bool cancelable,
      Window view, String keyIdentifier, int keyLocation, bool ctrlKey,
      bool altKey, bool shiftKey, bool metaKey) {
    throw new UnsupportedError(
        "Cannot initialize a KeyboardEvent from a KeyEvent.");
  }
  int get _layerX => throw new UnsupportedError('Not applicable to KeyEvent');
  int get _layerY => throw new UnsupportedError('Not applicable to KeyEvent');
  int get _pageX => throw new UnsupportedError('Not applicable to KeyEvent');
  int get _pageY => throw new UnsupportedError('Not applicable to KeyEvent');
  @Experimental() // untriaged
  bool getModifierState(String keyArgument) => throw new UnimplementedError();
  @Experimental() // untriaged
  int get location => throw new UnimplementedError();
  @Experimental() // untriaged
  bool get repeat => throw new UnimplementedError();
  dynamic get _get_view => throw new UnimplementedError();
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


class Platform {
  /**
   * Returns true if dart:typed_data types are supported on this
   * browser.  If false, using these types will generate a runtime
   * error.
   */
  static final supportsTypedData = true;

  /**
   * 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 = true;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * Helper class to implement custom events which wrap DOM events.
 */
class _WrappedEvent implements Event {
  final Event wrapped;

  /** The CSS selector involved with event delegation. */
  String _selector;

  _WrappedEvent(this.wrapped);

  bool get bubbles => wrapped.bubbles;

  bool get cancelable => wrapped.cancelable;

  DataTransfer get clipboardData => wrapped.clipboardData;

  EventTarget get currentTarget => wrapped.currentTarget;

  bool get defaultPrevented => wrapped.defaultPrevented;

  int get eventPhase => wrapped.eventPhase;

  EventTarget get target => wrapped.target;

  int get timeStamp => wrapped.timeStamp;

  String get type => wrapped.type;

  void _initEvent(String eventTypeArg, bool canBubbleArg,
      bool cancelableArg) {
    throw new UnsupportedError(
        'Cannot initialize this Event.');
  }

  void preventDefault() {
    wrapped.preventDefault();
  }

  void stopImmediatePropagation() {
    wrapped.stopImmediatePropagation();
  }

  void stopPropagation() {
    wrapped.stopPropagation();
  }

  /**
   * A pointer to the element whose CSS selector matched within which an event
   * was fired. If this Event was not associated with any Event delegation,
   * accessing this value will throw an [UnsupportedError].
   */
  Element get matchingTarget {
    if (_selector == null) {
      throw new UnsupportedError('Cannot call matchingTarget if this Event did'
          ' not arise as a result of event delegation.');
    }
    var currentTarget = this.currentTarget;
    var target = this.target;
    var matchedTarget;
    do {
      if (target.matches(_selector)) return target;
      target = target.parent;
    } while (target != null && target != currentTarget.parent);
    throw new StateError('No selector matched for populating matchedTarget.');
  }

  /**
   * This event's path, taking into account shadow DOM.
   *
   * ## Other resources
   *
   * * [Shadow DOM extensions to Event]
   * (http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event) from
   * W3C.
   */
  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#extensions-to-event
  @Experimental()
  List<Node> get path => wrapped.path;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


_wrapZone(callback(arg)) {
  // For performance reasons avoid wrapping if we are in the root zone.
  if (Zone.current == Zone.ROOT) return callback;
  if (callback == null) return null;
  return Zone.current.bindUnaryCallback(callback, runGuarded: true);
}

_wrapBinaryZone(callback(arg1, arg2)) {
  if (Zone.current == Zone.ROOT) return callback;
  if (callback == null) return null;
  return Zone.current.bindBinaryCallback(callback, runGuarded: true);
}

/**
 * Alias for [querySelector]. Note this function is deprecated because its
 * semantics will be changing in the future.
 */
@deprecated
@Experimental()
Element query(String relativeSelectors) => document.query(relativeSelectors);
/**
 * Alias for [querySelectorAll]. Note this function is deprecated because its
 * semantics will be changing in the future.
 */
@deprecated
@Experimental()
ElementList queryAll(String relativeSelectors) => document.queryAll(relativeSelectors);

/**
 * Finds the first descendant element of this document that matches the
 * specified group of selectors.
 *
 * Unless your webpage contains multiple documents, the top-level
 * [querySelector]
 * method behaves the same as this method, so you should use it instead to
 * save typing a few characters.
 *
 * [selectors] should be a string using CSS selector syntax.
 *
 *     var element1 = document.querySelector('.className');
 *     var element2 = document.querySelector('#id');
 *
 * For details about CSS selector syntax, see the
 * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
 */
Element querySelector(String selectors) => document.querySelector(selectors);

/**
 * Finds all descendant elements of this document that match the specified
 * group of selectors.
 *
 * Unless your webpage contains multiple documents, the top-level
 * [querySelectorAll]
 * method behaves the same as this method, so you should use it instead to
 * save typing a few characters.
 *
 * [selectors] should be a string using CSS selector syntax.
 *
 *     var items = document.querySelectorAll('.itemClassName');
 *
 * For details about CSS selector syntax, see the
 * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
 */
ElementList querySelectorAll(String selectors) => document.querySelectorAll(selectors);

/// A utility for changing the Dart wrapper type for elements.
abstract class ElementUpgrader {
  /// Upgrade the specified element to be of the Dart type this was created for.
  ///
  /// After upgrading the element passed in is invalid and the returned value
  /// should be used instead.
  Element upgrade(Element element);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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 _Property {
  _Property(this.name) :
      _hasValue = false,
      writable = false,
      isMethod = false,
      isOwn = true,
      wasThrown = false;

  bool get hasValue => _hasValue;
  get value => _value;
  set value(v) {
    _value = v;
    _hasValue = true;
  }

  final String name;
  Function setter;
  Function getter;
  var _value;
  bool _hasValue;
  bool writable;
  bool isMethod;
  bool isOwn;
  bool wasThrown;
}

class _ConsoleVariables {
  Map<String, Object> _data = new Map<String, Object>();

  /**
   * Forward member accesses to the backing JavaScript object.
   */
  noSuchMethod(Invocation invocation) {
    String member = MirrorSystem.getName(invocation.memberName);
    if (invocation.isGetter) {
      return _data[member];
    } else if (invocation.isSetter) {
      assert(member.endsWith('='));
      member = member.substring(0, member.length - 1);
      _data[member] = invocation.positionalArguments[0];
    } else {
      return Function.apply(_data[member], invocation.positionalArguments,
          invocation.namedArguments);
    }
  }

  void clear() => _data.clear();

  /**
   * List all variables currently defined.
   */
  List variables() => _data.keys.toList();

  void setVariable(String name, value) {
    _data[name] = value;
  }
}

/**
 * Base class for invocation trampolines used to closurize methods, getters
 * and setters.
 */
abstract class _Trampoline implements Function {
  final ObjectMirror _receiver;
  final MethodMirror _methodMirror;
  final Symbol _selector;

  _Trampoline(this._receiver, this._methodMirror, this._selector);
}

class _MethodTrampoline extends _Trampoline {
  _MethodTrampoline(ObjectMirror receiver, MethodMirror methodMirror,
      Symbol selector) :
      super(receiver, methodMirror, selector);

  noSuchMethod(Invocation msg) {
    if (msg.memberName != #call) return super.noSuchMethod(msg);
    return _receiver.invoke(_selector,
                            msg.positionalArguments,
                            msg.namedArguments).reflectee;
  }
}

/**
 * Invocation trampoline class used to closurize getters.
 */
class _GetterTrampoline extends _Trampoline {
  _GetterTrampoline(ObjectMirror receiver, MethodMirror methodMirror,
      Symbol selector) :
      super(receiver, methodMirror, selector);

  call() => _receiver.getField(_selector).reflectee;
}

/**
 * Invocation trampoline class used to closurize setters.
 */
class _SetterTrampoline extends _Trampoline {
  _SetterTrampoline(ObjectMirror receiver, MethodMirror methodMirror,
      Symbol selector) :
      super(receiver, methodMirror, selector);

  call(value) {
    _receiver.setField(_selector, value);
  }
}

class _Utils {
  static double dateTimeToDouble(DateTime dateTime) =>
      dateTime.millisecondsSinceEpoch.toDouble();
  static DateTime doubleToDateTime(double dateTime) {
    try {
      return new DateTime.fromMillisecondsSinceEpoch(dateTime.toInt());
    } catch(_) {
      // TODO(antonnm): treat exceptions properly in bindings and
      // find out how to treat NaNs.
      return null;
    }
  }

  static List convertToList(List list) {
    // FIXME: [possible optimization]: do not copy the array if Dart_IsArray is fine w/ it.
    final length = list.length;
    List result = new List(length);
    result.setRange(0, length, list);
    return result;
  }

  static List convertMapToList(Map map) {
    List result = [];
    map.forEach((k, v) => result.addAll([k, v]));
    return result;
  }

  static int convertCanvasElementGetContextMap(Map map) {
    int result = 0;
    if (map['alpha'] == true) result |= 0x01;
    if (map['depth'] == true) result |= 0x02;
    if (map['stencil'] == true) result |= 0x4;
    if (map['antialias'] == true) result |= 0x08;
    if (map['premultipliedAlpha'] == true) result |= 0x10;
    if (map['preserveDrawingBuffer'] == true) result |= 0x20;

    return result;
  }

  static void populateMap(Map result, List list) {
    for (int i = 0; i < list.length; i += 2) {
      result[list[i]] = list[i + 1];
    }
  }

  static bool isMap(obj) => obj is Map;

  static List toListIfIterable(obj) => obj is Iterable ? obj.toList() : null;

  static Map createMap() => {};

  static parseJson(String jsonSource) => const JsonDecoder().convert(jsonSource);

  static makeUnimplementedError(String fileName, int lineNo) {
    return new UnsupportedError('[info: $fileName:$lineNo]');
  }

  static bool isTypeSubclassOf(Type type, Type other) {
    if (type == other) {
      return true;
    }
    var superclass = reflectClass(type).superclass;
    if (superclass != null) {
      return isTypeSubclassOf(superclass.reflectedType, other);
    }
    return false;
  }

  static Element getAndValidateNativeType(Type type, String tagName) {
    var element = new Element.tag(tagName);
    if (!isTypeSubclassOf(type, element.runtimeType)) {
      return null;
    }
    return element;
  }

  static window() => _blink.Blink_Utils.window();
  static forwardingPrint(String message) => _blink.Blink_Utils.forwardingPrint(message);
  // TODO(vsm): Make this API compatible with spawnUri.  It should also
  // return a Future<Isolate>.
  static spawnDomUri(String uri) => _blink.Blink_Utils.spawnDomUri(uri);

  // The following methods were added for debugger integration to make working
  // with the Dart C mirrors API simpler.
  // TODO(jacobr): consider moving them to a separate library.
  // If Dart supported dynamic code injection, we would only inject this code
  // when the debugger is invoked.

  /**
   * Strips the private secret prefix from member names of the form
   * someName@hash.
   */
  static String stripMemberName(String name) {
    int endIndex = name.indexOf('@');
    return endIndex > 0 ? name.substring(0, endIndex) : name;
  }

  /**
   * Takes a list containing variable names and corresponding values and
   * returns a map from normalized names to values. Variable names are assumed
   * to have list offsets 2*n values at offset 2*n+1. This method is required
   * because Dart_GetLocalVariables returns a list instead of an object that
   * can be queried to lookup names and values.
   */
  static Map<String, dynamic> createLocalVariablesMap(List localVariables) {
    var map = {};
    for (int i = 0; i < localVariables.length; i+=2) {
      map[stripMemberName(localVariables[i])] = localVariables[i+1];
    }
    return map;
  }

  static _ConsoleVariables _consoleTempVariables = new _ConsoleVariables();

  /**
   * Takes an [expression] and a list of [local] variable and returns an
   * expression for a closure with a body matching the original expression
   * where locals are passed in as arguments. Returns a list containing the
   * String expression for the closure and the list of arguments that should
   * be passed to it. The expression should then be evaluated using
   * Dart_EvaluateExpr which will generate a closure that should be invoked
   * with the list of arguments passed to this method.
   *
   * For example:
   * <code>
   * _consoleTempVariables = {'a' : someValue, 'b': someOtherValue}
   * wrapExpressionAsClosure("foo + bar + a", ["bar", 40, "foo", 2], true)
   * </code>
   * will return:
   * <code>
   * ["""(final $consoleVariables, final bar, final foo, final a, final b) =>
   * (foo + bar + a
   * )""",
   * [_consoleTempVariables, 40, 2, someValue, someOtherValue]]
   * </code>
   */
  static List wrapExpressionAsClosure(String expression, List locals,
      bool includeCommandLineAPI) {
    var args = {};
    var sb = new StringBuffer("(");
    addArg(arg, value) {
      arg = stripMemberName(arg);
      if (args.containsKey(arg)) return;
      // We ignore arguments with the name 'this' rather than throwing an
      // exception because Dart_GetLocalVariables includes 'this' and it
      // is more convenient to filter it out here than from C++ code.
      // 'this' needs to be handled by calling Dart_EvaluateExpr with
      // 'this' as the target rather than by passing it as an argument.
      if (arg == 'this') return;
      if (args.isNotEmpty) {
        sb.write(", ");
      }
      sb.write("final $arg");
      args[arg] = value;
    }

    if (includeCommandLineAPI) {
      addArg("\$consoleVariables", _consoleTempVariables);

      // FIXME: use a real Dart tokenizer. The following regular expressions
      // only allow setting variables at the immediate start of the expression
      // to limit the number of edge cases we have to handle.

      // Match expressions that start with "var x"
      final _VARIABLE_DECLARATION = new RegExp("^(\\s*)var\\s+(\\w+)");
      // Match expressions that start with "someExistingConsoleVar ="
      final _SET_VARIABLE = new RegExp("^(\\s*)(\\w+)(\\s*=)");
      // Match trailing semicolons.
      final _ENDING_SEMICOLONS = new RegExp("(;\\s*)*\$");
      expression = expression.replaceAllMapped(_VARIABLE_DECLARATION,
          (match) {
            var variableName = match[2];
            // Set the console variable if it isn't already set.
            if (!_consoleTempVariables._data.containsKey(variableName)) {
              _consoleTempVariables._data[variableName] = null;
            }
            return "${match[1]}\$consoleVariables.${variableName}";
          });

      expression = expression.replaceAllMapped(_SET_VARIABLE,
          (match) {
            var variableName = match[2];
            // Only rewrite if the name matches an existing console variable.
            if (_consoleTempVariables._data.containsKey(variableName)) {
              return "${match[1]}\$consoleVariables.${variableName}${match[3]}";
            } else {
              return match[0];
            }
          });

      // We only allow dart expressions not Dart statements. Silently remove
      // trailing semicolons the user might have added by accident to reduce the
      // number of spurious compile errors.
      expression = expression.replaceFirst(_ENDING_SEMICOLONS, "");
    }

    if (locals != null) {
      for (int i = 0; i < locals.length; i+= 2) {
        addArg(locals[i], locals[i+1]);
      }
    }
    // Inject all the already defined console variables.
    _consoleTempVariables._data.forEach(addArg);

    // TODO(jacobr): remove the parentheses around the expresson once
    // dartbug.com/13723 is fixed. Currently we wrap expression in parentheses
    // to ensure only valid Dart expressions are allowed. Otherwise the DartVM
    // quietly ignores trailing Dart statements resulting in user confusion
    // when part of an invalid expression they entered is ignored.
    sb..write(') => (\n$expression\n)');
    return [sb.toString(), args.values.toList(growable: false)];
  }

  static String _getShortSymbolName(Symbol symbol,
                                    DeclarationMirror declaration) {
    var name = MirrorSystem.getName(symbol);
    if (declaration is MethodMirror) {
      if (declaration.isSetter && name[name.length-1] == "=") {
        return name.substring(0, name.length-1);
      }
      if (declaration.isConstructor) {
        return name.substring(name.indexOf('.') + 1);
      }
    }
    return name;
  }

  /**
   * Returns a list of completions to use if the receiver is o.
   */
  static List<String> getCompletions(o) {
    MirrorSystem system = currentMirrorSystem();
    var completions = new Set<String>();
    addAll(Map<Symbol, dynamic> map, bool isStatic) {
      map.forEach((symbol, mirror) {
        if (mirror.isStatic == isStatic && !mirror.isPrivate) {
          var name = MirrorSystem.getName(symbol);
          if (mirror is MethodMirror && mirror.isSetter)
            name = name.substring(0, name.length - 1);
          completions.add(name);
        }
      });
    }

    addForClass(ClassMirror mirror, bool isStatic) {
      if (mirror == null)
        return;
      addAll(mirror.declarations, isStatic);
      if (mirror.superclass != null)
        addForClass(mirror.superclass, isStatic);
      for (var interface in mirror.superinterfaces) {
        addForClass(interface, isStatic);
      }
    }

    if (o is Type) {
      addForClass(reflectClass(o), true);
    } else {
      addForClass(reflect(o).type, false);
    }
    return completions.toList(growable: false);
  }

  /**
   * Adds all candidate String completitions from [declarations] to [output]
   * filtering based on [staticContext] and [includePrivate].
   */
  static void _getCompletionsHelper(ClassMirror classMirror,
      bool staticContext, LibraryMirror libraryMirror, Set<String> output) {
    bool includePrivate = libraryMirror == classMirror.owner;
    classMirror.declarations.forEach((symbol, declaration) {
      if (!includePrivate && declaration.isPrivate) return;
      if (declaration is VariableMirror) {
        if (staticContext != declaration.isStatic) return;
      } else if (declaration is MethodMirror) {
        if (declaration.isOperator) return;
        if (declaration.isConstructor) {
          if (!staticContext) return;
          var name = MirrorSystem.getName(declaration.constructorName);
          if (name.isNotEmpty) output.add(name);
          return;
        }
        if (staticContext != declaration.isStatic) return;
      } else if (declaration is TypeMirror) {
        return;
      }
      output.add(_getShortSymbolName(symbol, declaration));
    });

    if (!staticContext) {
      for (var interface in classMirror.superinterfaces) {
        _getCompletionsHelper(interface, staticContext,
            libraryMirror, output);
      }
      if (classMirror.superclass != null) {
        _getCompletionsHelper(classMirror.superclass, staticContext,
            libraryMirror, output);
      }
    }
  }

  static void _getLibraryCompletionsHelper(
      LibraryMirror library, bool includePrivate, Set<String> output) {
    library.declarations.forEach((symbol, declaration) {
      if (!includePrivate && declaration.isPrivate) return;
      output.add(_getShortSymbolName(symbol, declaration));
    });
  }

  static LibraryMirror getLibraryMirror(String url) =>
      currentMirrorSystem().libraries[Uri.parse(url)];

  /**
   * Get code completions for [o] only showing privates from [libraryUrl].
   */
  static List<String> getObjectCompletions(o, String libraryUrl) {
    var classMirror;
    bool staticContext;
    if (o is Type) {
      classMirror = reflectClass(o);
      staticContext = true;
    } else {
      classMirror = reflect(o).type;
      staticContext = false;
    }
    var names = new Set<String>();
    getClassCompletions(classMirror, names, staticContext, libraryUrl);
    return names.toList()..sort();
  }

  static void getClassCompletions(ClassMirror classMirror, Set<String> names,
      bool staticContext, String libraryUrl) {
    LibraryMirror libraryMirror = getLibraryMirror(libraryUrl);
    _getCompletionsHelper(classMirror, staticContext, libraryMirror, names);
  }

  static List<String> getLibraryCompletions(String url) {
    var names = new Set<String>();
    _getLibraryCompletionsHelper(getLibraryMirror(url), true, names);
    return names.toList();
  }

  /**
   * Get valid code completitions from within a library and all libraries
   * imported by that library.
   */
  static List<String> getLibraryCompletionsIncludingImports(String url) {
    var names = new Set<String>();
    var libraryMirror = getLibraryMirror(url);
    _getLibraryCompletionsHelper(libraryMirror, true, names);
    for (var dependency in libraryMirror.libraryDependencies) {
      if (dependency.isImport) {
        if (dependency.prefix == null) {
          _getLibraryCompletionsHelper(dependency.targetLibrary, false, names);
        } else {
          names.add(MirrorSystem.getName(dependency.prefix));
        }
      }
    }
    return names.toList();
  }

  static final SIDE_EFFECT_FREE_LIBRARIES = new Set<String>()
      ..add('dart:html')
      ..add('dart:indexed_db')
      ..add('dart:svg')
      ..add('dart:typed_data')
      ..add('dart:web_audio')
      ..add('dart:web_gl')
      ..add('dart:web_sql');

  static LibraryMirror _getLibrary(MethodMirror methodMirror) {
    var owner = methodMirror.owner;
    if (owner is ClassMirror) {
      return owner;
    } else if (owner is LibraryMirror) {
      return owner;
    }
    return null;
  }

  /**
   * For parity with the JavaScript debugger, we treat some getters as if
   * they are fields so that users can see their values immediately.
   * This matches JavaScript's behavior for getters on DOM objects.
   * In the future we should consider adding an annotation to tag getters
   * in user libraries as side effect free.
   */
  static bool _isSideEffectFreeGetter(MethodMirror methodMirror,
      LibraryMirror libraryMirror) {
    // This matches JavaScript behavior. We should consider displaying
    // getters for all dart platform libraries rather than just the DOM
    // libraries.
    return libraryMirror.uri.scheme == 'dart' &&
        SIDE_EFFECT_FREE_LIBRARIES.contains(libraryMirror.uri.toString());
  }
  
  /**
   * Whether we should treat a property as a field for the purposes of the
   * debugger.
   */
  static bool treatPropertyAsField(MethodMirror methodMirror,
      LibraryMirror libraryMirror) {
    return (methodMirror.isGetter || methodMirror.isSetter) &&
          (methodMirror.isSynthetic ||
              _isSideEffectFreeGetter(methodMirror,libraryMirror));
  }

  // TODO(jacobr): generate more concise function descriptions instead of
  // dumping the entire function source.
  static String describeFunction(function) {
    if (function is _Trampoline) return function._methodMirror.source;
    try {
      var mirror = reflect(function);
      return mirror.function.source;
    } catch (e) {
      return function.toString();
    }
  }

  static List getInvocationTrampolineDetails(_Trampoline method) {
    var loc = method._methodMirror.location;
    return [loc.line, loc.column, loc.sourceUri.toString(),
        MirrorSystem.getName(method._selector)];
  }

  static List getLibraryProperties(String libraryUrl, bool ownProperties,
      bool accessorPropertiesOnly) {
    var properties = new Map<String, _Property>();
    var libraryMirror = getLibraryMirror(libraryUrl);
    _addInstanceMirrors(libraryMirror, libraryMirror,
        libraryMirror.declarations,
        ownProperties, accessorPropertiesOnly, false, false,
        properties);
    if (!accessorPropertiesOnly) {
      // We need to add class properties for all classes in the library.
      libraryMirror.declarations.forEach((symbol, declarationMirror) {
        if (declarationMirror is ClassMirror) {
          var name = MirrorSystem.getName(symbol);
          if (declarationMirror.hasReflectedType
              && !properties.containsKey(name)) {
            properties[name] = new _Property(name)
                ..value = declarationMirror.reflectedType;
          }
        }
      });
    }
    return packageProperties(properties);
  }

  static List getObjectProperties(o, bool ownProperties,
      bool accessorPropertiesOnly) {
    var properties = new Map<String, _Property>();
    var names = new Set<String>();
    var objectMirror = reflect(o);
    var classMirror = objectMirror.type;
    _addInstanceMirrors(objectMirror, classMirror.owner,
        classMirror.instanceMembers,
        ownProperties, accessorPropertiesOnly, false, true,
        properties);
    return packageProperties(properties);
  }

  static List getObjectClassProperties(o, bool ownProperties,
      bool accessorPropertiesOnly) {
    var properties = new Map<String, _Property>();
    var objectMirror = reflect(o);
    var classMirror = objectMirror.type;
    _addInstanceMirrors(objectMirror, classMirror.owner,
        classMirror.instanceMembers,
        ownProperties, accessorPropertiesOnly, true, false,
        properties);
    _addStatics(classMirror, properties, accessorPropertiesOnly);
    return packageProperties(properties);
  }

  static List getClassProperties(Type t, bool ownProperties,
      bool accessorPropertiesOnly) {
    var properties = new Map<String, _Property>();
    var classMirror = reflectClass(t);
    _addStatics(classMirror, properties, accessorPropertiesOnly);
    return packageProperties(properties);
  }

  static void _addStatics(ClassMirror classMirror,
                          Map<String, _Property> properties,
                          bool accessorPropertiesOnly) {
    var libraryMirror = classMirror.owner;
    classMirror.declarations.forEach((symbol, declaration) {
      var name = _getShortSymbolName(symbol, declaration);
      if (name.isEmpty) return;
      if (declaration is VariableMirror) {
        if (accessorPropertiesOnly) return;
        if (!declaration.isStatic) return;
        properties.putIfAbsent(name, () => new _Property(name))
            ..value = classMirror.getField(symbol).reflectee
            ..writable = !declaration.isFinal && !declaration.isConst;
      } else if (declaration is MethodMirror) {
        MethodMirror methodMirror = declaration;
        // FIXMEDART: should we display constructors?
        if (methodMirror.isConstructor) return;
        if (!methodMirror.isStatic) return;
        if (accessorPropertiesOnly) {
          if (methodMirror.isRegularMethod ||
              treatPropertyAsField(methodMirror, libraryMirror)) {
            return;
          }
        } else if (!methodMirror.isRegularMethod &&
            !treatPropertyAsField(methodMirror, libraryMirror)) {
          return;
        }
        var property = properties.putIfAbsent(name, () => new _Property(name));
        _fillMethodMirrorProperty(libraryMirror, classMirror, methodMirror,
            symbol, accessorPropertiesOnly, property);
      }
    });
  }

  static void _fillMethodMirrorProperty(LibraryMirror libraryMirror,
        methodOwner, MethodMirror methodMirror, Symbol symbol,
        bool accessorPropertiesOnly, _Property property) {
    if (methodMirror.isRegularMethod) {
      property
          ..value = new _MethodTrampoline(methodOwner, methodMirror, symbol)
          ..isMethod = true;
    } else if (methodMirror.isGetter) {
      if (treatPropertyAsField(methodMirror, libraryMirror)) {
        try {
          property.value = methodOwner.getField(symbol).reflectee;
        } catch (e) {
          property
              ..wasThrown = true
              ..value = e;
        }
      } else if (accessorPropertiesOnly) {
        property.getter = new _GetterTrampoline(methodOwner,
            methodMirror, symbol);
      }
    } else if (methodMirror.isSetter) {
      if (accessorPropertiesOnly &&
          !treatPropertyAsField(methodMirror, libraryMirror)) {
        property.setter = new _SetterTrampoline(methodOwner,
            methodMirror, MirrorSystem.getSymbol(property.name, libraryMirror));
      }
      property.writable = true;
    }
  }

  /**
   * Helper method that handles collecting up properties from classes
   * or libraries using the filters [ownProperties], [accessorPropertiesOnly],
   * [hideFields], and [hideMethods] to determine which properties are
   * collected. [accessorPropertiesOnly] specifies whether all properties
   * should be returned or just accessors. [hideFields] specifies whether
   * fields should be hidden. hideMethods specifies whether methods should be
   * shown or hidden. [ownProperties] is not currently used but is part of the
   * Blink devtools API for enumerating properties.
   */
  static void _addInstanceMirrors(
      ObjectMirror objectMirror,
      LibraryMirror libraryMirror,
      Map<Symbol, Mirror> declarations,
      bool ownProperties, bool accessorPropertiesOnly,
      bool hideFields, bool hideMethods,
      Map<String, _Property> properties) {
    declarations.forEach((symbol, declaration) {
      if (declaration is TypedefMirror || declaration is ClassMirror) return;
      var name = _getShortSymbolName(symbol, declaration);
      if (name.isEmpty) return;
      bool isField = declaration is VariableMirror ||
          (declaration is MethodMirror &&
              treatPropertyAsField(declaration, libraryMirror));
      if ((isField && hideFields) || (hideMethods && !isField)) return;
      if (accessorPropertiesOnly) {
        if (declaration is VariableMirror || declaration.isRegularMethod ||
            isField) {
          return;
        }
      } else if (declaration is MethodMirror &&
          (declaration.isGetter || declaration.isSetter) &&
          !treatPropertyAsField(declaration, libraryMirror)) {
        return;
      }
      var property = properties.putIfAbsent(name, () => new _Property(name));
      if (declaration is VariableMirror) {
        property
            ..value = objectMirror.getField(symbol).reflectee
            ..writable = !declaration.isFinal && !declaration.isConst;
        return;
      }
      _fillMethodMirrorProperty(libraryMirror, objectMirror, declaration,
          symbol, accessorPropertiesOnly, property);
    });
  }

  /**
   * Flatten down the properties data structure into a List that is easy to
   * access from native code.
   */
  static List packageProperties(Map<String, _Property> properties) {
    var ret = [];
    for (var property in properties.values) {
      ret.addAll([property.name,
                  property.setter,
                  property.getter,
                  property.value,
                  property.hasValue,
                  property.writable,
                  property.isMethod,
                  property.isOwn,
                  property.wasThrown]);
    }
    return ret;
  }
  
  /**
   * Get a property, returning null if the property does not exist.
   * For private property names, we attempt to resolve the property in the
   * context of each library that the property name could be associated with.
   */
  static getObjectPropertySafe(o, String propertyName) {
    var objectMirror = reflect(o);
    var classMirror = objectMirror.type;
    if (propertyName.startsWith("_")) {
      var attemptedLibraries = new Set<LibraryMirror>(); 
      while (classMirror != null) {
        LibraryMirror library = classMirror.owner;
        if (!attemptedLibraries.contains(library)) {
          try {
            return objectMirror.getField(
                MirrorSystem.getSymbol(propertyName, library)).reflectee;
          } catch (e) { }
          attemptedLibraries.add(library);
        }
        classMirror = classMirror.superclass;
      }
      return null;     
    }
    try {
      return objectMirror.getField(
          MirrorSystem.getSymbol(propertyName)).reflectee;
    } catch (e) {
      return null;
    }
  }

  /**
   * Helper to wrap the inspect method on InjectedScriptHost to provide the
   * inspect method required for the 
   */
  static List consoleApi(host) {
    return [
        "inspect",
        (o) {
          host.inspect(o, null);
          return o;
        },
        "dir",
        window().console.dir,
        "dirxml",
        window().console.dirxml
        // FIXME: add copy method.
        ];
  }

  static List getMapKeyList(Map map) => map.keys.toList();

  static bool isNoSuchMethodError(obj) => obj is NoSuchMethodError;

  static void register(Document document, String tag, Type type,
      String extendsTagName) {
    var nativeClass = _validateCustomType(type);

    if (extendsTagName == null) {
      if (nativeClass.reflectedType != HtmlElement) {
        throw new UnsupportedError('Class must provide extendsTag if base '
            'native class is not HTMLElement');
      }
    }

    _register(document, tag, type, extendsTagName);
  }

  static void _register(Document document, String tag, Type customType,
    String extendsTagName) => _blink.Blink_Utils.register(document, tag, customType, extendsTagName);

  static Element createElement(Document document, String tagName) =>
    _blink.Blink_Utils.createElement(document, tagName);

  static void initializeCustomElement(HtmlElement element) =>
    _blink.Blink_Utils.initializeCustomElement(element);

  static Element changeElementWrapper(HtmlElement element, Type type) =>
    _blink.Blink_Utils.changeElementWrapper(element, type);
}

class _DOMWindowCrossFrame extends NativeFieldWrapperClass2 implements
    WindowBase {
  _DOMWindowCrossFrame.internal();

  // Fields.
  HistoryBase get history => _blink.Blink_DOMWindowCrossFrame.get_history(this);
  LocationBase get location => _blink.Blink_DOMWindowCrossFrame.get_location(this);
  bool get closed => _blink.Blink_DOMWindowCrossFrame.get_closed(this);
  WindowBase get opener => _blink.Blink_DOMWindowCrossFrame.get_opener(this);
  WindowBase get parent => _blink.Blink_DOMWindowCrossFrame.get_parent(this);
  WindowBase get top => _blink.Blink_DOMWindowCrossFrame.get_top(this);

  // Methods.
  void close() => _blink.Blink_DOMWindowCrossFrame.close(this);
  void postMessage(/*SerializedScriptValue*/ message, String targetOrigin, [List messagePorts]) =>
    _blink.Blink_DOMWindowCrossFrame.postMessage(this, message, targetOrigin, messagePorts);

  // Implementation support.
  String get typeName => "Window";

  // 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 _HistoryCrossFrame extends NativeFieldWrapperClass2 implements HistoryBase {
  _HistoryCrossFrame.internal();

  // Methods.
  void back() => _blink.Blink_HistoryCrossFrame.back(this);
  void forward() => _blink.Blink_HistoryCrossFrame.forward(this);
  void go(int distance) => _blink.Blink_HistoryCrossFrame.go(this, distance);

  // Implementation support.
  String get typeName => "History";
}

class _LocationCrossFrame extends NativeFieldWrapperClass2 implements LocationBase {
  _LocationCrossFrame.internal();

  // Fields.
  void set href(String h) => _blink.Blink_LocationCrossFrame.set_href(this, h);

  // Implementation support.
  String get typeName => "Location";
}

class _DOMStringMap extends NativeFieldWrapperClass2 implements Map<String, String> {
  _DOMStringMap.internal();

  bool containsValue(String value) => Maps.containsValue(this, value);
  bool containsKey(String key) => _blink.Blink_DOMStringMap.containsKey(this, key);
  String operator [](String key) => _blink.Blink_DOMStringMap.item(this, key);
  void operator []=(String key, String value) => _blink.Blink_DOMStringMap.setItem(this, key, value);
  String putIfAbsent(String key, String ifAbsent()) => Maps.putIfAbsent(this, key, ifAbsent);
  String remove(String key) => _blink.Blink_DOMStringMap.remove(this, key);
  void clear() => Maps.clear(this);
  void forEach(void f(String key, String value)) => Maps.forEach(this, f);
  Iterable<String> get keys => _blink.Blink_DOMStringMap.get_keys(this);
  Iterable<String> get values => Maps.getValues(this);
  int get length => Maps.length(this);
  bool get isEmpty => Maps.isEmpty(this);
  bool get isNotEmpty => Maps.isNotEmpty(this);
  void addAll(Map<String, String> other) {
    other.forEach((key, value) => this[key] = value);
  }
}

final _printClosure = (s) => window.console.log(s);
final _pureIsolatePrintClosure = (s) {
  throw new UnimplementedError("Printing from a background isolate "
                               "is not supported in the browser");
};

final _forwardingPrintClosure = _Utils.forwardingPrint;

final _uriBaseClosure = () => Uri.parse(window.location.href);

final _pureIsolateUriBaseClosure = () {
  throw new UnimplementedError("Uri.base on a background isolate "
                               "is not supported in the browser");
};

class _Timer implements Timer {
  static const int _STATE_TIMEOUT = 0;
  static const int _STATE_INTERVAL = 1;
  int _state;

  _Timer(int milliSeconds, void callback(Timer timer), bool repeating) {
    if (repeating) {
      _state = (window._setInterval(() {
        callback(this);
      }, milliSeconds) << 1) | _STATE_INTERVAL;
    } else {
      _state = (window._setTimeout(() {
        _state = null;
        callback(this);
      }, milliSeconds) << 1) | _STATE_TIMEOUT;
    }
  }

  void cancel() {
    if (_state == null) return;
    int id = _state >> 1;
    if ((_state & 1) == _STATE_TIMEOUT) {
      window._clearTimeout(id);
    } else {
      window._clearInterval(id);
    }
    _state = null;
  }

  bool get isActive => _state != null;
}

get _timerFactoryClosure =>
    (int milliSeconds, void callback(Timer timer), bool repeating) {
  return new _Timer(milliSeconds, callback, repeating);
};

get _pureIsolateTimerFactoryClosure =>
    ((int milliSeconds, void callback(Timer time), bool repeating) =>
  throw new UnimplementedError("Timers on background isolates "
                               "are not supported in the browser"));

class _ScheduleImmediateHelper {
  MutationObserver _observer;
  final DivElement _div = new DivElement();
  Function _callback;

  _ScheduleImmediateHelper() {
    // Run in the root-zone as the DOM callback would otherwise execute in the
    // current zone.
    Zone.ROOT.run(() {
      // Mutation events get fired as soon as the current event stack is unwound
      // so we just make a dummy event and listen for that.
      _observer = new MutationObserver(_handleMutation);
      _observer.observe(_div, attributes: true);
    });
  }

  void _schedule(callback) {
    if (_callback != null) {
      throw new StateError(
          'Only one immediate callback can be scheduled at once');
    }
    _callback = callback;
    // Toggle it to trigger the mutation event.
    _div.hidden = !_div.hidden;
  }

  _handleMutation(List<MutationRecord> mutations, MutationObserver observer) {
    var tmp = _callback;
    _callback = null;
    tmp();
  }
}

final _ScheduleImmediateHelper _scheduleImmediateHelper =
    new _ScheduleImmediateHelper();

get _scheduleImmediateClosure => (void callback()) {
  _scheduleImmediateHelper._schedule(callback);
};

get _pureIsolateScheduleImmediateClosure => ((void callback()) =>
  throw new UnimplementedError("scheduleMicrotask in background isolates "
                               "are not supported in the browser"));

void _initializeCustomElement(Element e) {
  _Utils.initializeCustomElement(e);
}

// Class for unsupported native browser 'DOM' objects.
class _UnsupportedBrowserObject extends NativeFieldWrapperClass2 {
}
