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

import 'dart:async';
import 'dart:collection';
import 'dart:_internal' hide Symbol;
import 'dart:html_common';
import 'dart:indexed_db';
import 'dart: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;
import 'dart:developer';
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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 = js.JsNative.toTypedObject(js.context);
  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?
@Deprecated("Internal Use Only")
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,
  // We have to call .instanceRuntimeType as these classes have a private
  // implementation class defined dynamically at runtime via a patch file.
  'JSObject': () => js.JSObject.instanceRuntimeType,
  'JSFunction': () => js.JSFunction.instanceRuntimeType,
  'JSArray': () => js.JSArray.instanceRuntimeType,
  'AbstractWorker': () => AbstractWorker.instanceRuntimeType,
  'Animation': () => Animation.instanceRuntimeType,
  'AnimationEffectReadOnly': () => AnimationEffectReadOnly.instanceRuntimeType,
  'AnimationEffectTiming': () => AnimationEffectTiming.instanceRuntimeType,
  'AnimationEvent': () => AnimationEvent.instanceRuntimeType,
  'AnimationPlayerEvent': () => AnimationPlayerEvent.instanceRuntimeType,
  'AnimationTimeline': () => AnimationTimeline.instanceRuntimeType,
  'AppBannerPromptResult': () => AppBannerPromptResult.instanceRuntimeType,
  'ApplicationCache': () => ApplicationCache.instanceRuntimeType,
  'ApplicationCacheErrorEvent': () => ApplicationCacheErrorEvent.instanceRuntimeType,
  'Attr': () => _Attr.instanceRuntimeType,
  'AudioTrack': () => AudioTrack.instanceRuntimeType,
  'AudioTrackList': () => AudioTrackList.instanceRuntimeType,
  'AutocompleteErrorEvent': () => AutocompleteErrorEvent.instanceRuntimeType,
  'BarProp': () => BarProp.instanceRuntimeType,
  'BatteryManager': () => BatteryManager.instanceRuntimeType,
  'BeforeInstallPromptEvent': () => BeforeInstallPromptEvent.instanceRuntimeType,
  'BeforeUnloadEvent': () => BeforeUnloadEvent.instanceRuntimeType,
  'Blob': () => Blob.instanceRuntimeType,
  'Bluetooth': () => Bluetooth.instanceRuntimeType,
  'BluetoothDevice': () => BluetoothDevice.instanceRuntimeType,
  'BluetoothGATTCharacteristic': () => BluetoothGattCharacteristic.instanceRuntimeType,
  'BluetoothGATTRemoteServer': () => BluetoothGattRemoteServer.instanceRuntimeType,
  'BluetoothGATTService': () => BluetoothGattService.instanceRuntimeType,
  'BluetoothUUID': () => BluetoothUuid.instanceRuntimeType,
  'Body': () => Body.instanceRuntimeType,
  'CDATASection': () => CDataSection.instanceRuntimeType,
  'CHROMIUMValuebuffer': () => ChromiumValuebuffer.instanceRuntimeType,
  'CSS': () => Css.instanceRuntimeType,
  'CSSCharsetRule': () => CssCharsetRule.instanceRuntimeType,
  'CSSFontFaceRule': () => CssFontFaceRule.instanceRuntimeType,
  'CSSGroupingRule': () => CssGroupingRule.instanceRuntimeType,
  'CSSImportRule': () => CssImportRule.instanceRuntimeType,
  'CSSKeyframeRule': () => CssKeyframeRule.instanceRuntimeType,
  'CSSKeyframesRule': () => CssKeyframesRule.instanceRuntimeType,
  'CSSMediaRule': () => CssMediaRule.instanceRuntimeType,
  'CSSPageRule': () => CssPageRule.instanceRuntimeType,
  'CSSRule': () => CssRule.instanceRuntimeType,
  'CSSRuleList': () => _CssRuleList.instanceRuntimeType,
  'CSSStyleDeclaration': () => CssStyleDeclaration.instanceRuntimeType,
  'CSSStyleRule': () => CssStyleRule.instanceRuntimeType,
  'CSSStyleSheet': () => CssStyleSheet.instanceRuntimeType,
  'CSSSupportsRule': () => CssSupportsRule.instanceRuntimeType,
  'CSSViewportRule': () => CssViewportRule.instanceRuntimeType,
  'Cache': () => _Cache.instanceRuntimeType,
  'CacheStorage': () => CacheStorage.instanceRuntimeType,
  'CanvasGradient': () => CanvasGradient.instanceRuntimeType,
  'CanvasPathMethods': () => _CanvasPathMethods.instanceRuntimeType,
  'CanvasPattern': () => CanvasPattern.instanceRuntimeType,
  'CanvasRenderingContext2D': () => CanvasRenderingContext2D.instanceRuntimeType,
  'CharacterData': () => CharacterData.instanceRuntimeType,
  'ChildNode': () => ChildNode.instanceRuntimeType,
  'CircularGeofencingRegion': () => CircularGeofencingRegion.instanceRuntimeType,
  'Client': () => Client.instanceRuntimeType,
  'ClientRect': () => _ClientRect.instanceRuntimeType,
  'ClientRectList': () => _ClientRectList.instanceRuntimeType,
  'Clients': () => Clients.instanceRuntimeType,
  'ClipboardEvent': () => ClipboardEvent.instanceRuntimeType,
  'CloseEvent': () => CloseEvent.instanceRuntimeType,
  'Comment': () => Comment.instanceRuntimeType,
  'CompositionEvent': () => CompositionEvent.instanceRuntimeType,
  'CompositorProxy': () => CompositorProxy.instanceRuntimeType,
  'CompositorWorker': () => CompositorWorker.instanceRuntimeType,
  'CompositorWorkerGlobalScope': () => CompositorWorkerGlobalScope.instanceRuntimeType,
  'Console': () => Console.instanceRuntimeType,
  'ConsoleBase': () => ConsoleBase.instanceRuntimeType,
  'Coordinates': () => Coordinates.instanceRuntimeType,
  'Credential': () => Credential.instanceRuntimeType,
  'CredentialsContainer': () => CredentialsContainer.instanceRuntimeType,
  'CrossOriginConnectEvent': () => CrossOriginConnectEvent.instanceRuntimeType,
  'CrossOriginServiceWorkerClient': () => CrossOriginServiceWorkerClient.instanceRuntimeType,
  'Crypto': () => Crypto.instanceRuntimeType,
  'CryptoKey': () => CryptoKey.instanceRuntimeType,
  'CustomEvent': () => CustomEvent.instanceRuntimeType,
  'DOMError': () => DomError.instanceRuntimeType,
  'DOMException': () => DomException.instanceRuntimeType,
  'DOMFileSystem': () => FileSystem.instanceRuntimeType,
  'DOMFileSystemSync': () => _DOMFileSystemSync.instanceRuntimeType,
  'DOMImplementation': () => DomImplementation.instanceRuntimeType,
  'DOMMatrix': () => DomMatrix.instanceRuntimeType,
  'DOMMatrixReadOnly': () => DomMatrixReadOnly.instanceRuntimeType,
  'DOMParser': () => DomParser.instanceRuntimeType,
  'DOMPoint': () => DomPoint.instanceRuntimeType,
  'DOMPointReadOnly': () => DomPointReadOnly.instanceRuntimeType,
  'DOMRect': () => _DomRect.instanceRuntimeType,
  'DOMRectReadOnly': () => DomRectReadOnly.instanceRuntimeType,
  'DOMSettableTokenList': () => DomSettableTokenList.instanceRuntimeType,
  'DOMStringList': () => DomStringList.instanceRuntimeType,
  'DOMStringMap': () => DomStringMap.instanceRuntimeType,
  'DOMTokenList': () => DomTokenList.instanceRuntimeType,
  'DataTransfer': () => DataTransfer.instanceRuntimeType,
  'DataTransferItem': () => DataTransferItem.instanceRuntimeType,
  'DataTransferItemList': () => DataTransferItemList.instanceRuntimeType,
  'DedicatedWorkerGlobalScope': () => DedicatedWorkerGlobalScope.instanceRuntimeType,
  'DefaultSessionStartEvent': () => DefaultSessionStartEvent.instanceRuntimeType,
  'DeprecatedStorageInfo': () => DeprecatedStorageInfo.instanceRuntimeType,
  'DeprecatedStorageQuota': () => DeprecatedStorageQuota.instanceRuntimeType,
  'DeviceAcceleration': () => DeviceAcceleration.instanceRuntimeType,
  'DeviceLightEvent': () => DeviceLightEvent.instanceRuntimeType,
  'DeviceMotionEvent': () => DeviceMotionEvent.instanceRuntimeType,
  'DeviceOrientationEvent': () => DeviceOrientationEvent.instanceRuntimeType,
  'DeviceRotationRate': () => DeviceRotationRate.instanceRuntimeType,
  'DirectoryEntry': () => DirectoryEntry.instanceRuntimeType,
  'DirectoryEntrySync': () => _DirectoryEntrySync.instanceRuntimeType,
  'DirectoryReader': () => DirectoryReader.instanceRuntimeType,
  'DirectoryReaderSync': () => _DirectoryReaderSync.instanceRuntimeType,
  'Document': () => Document.instanceRuntimeType,
  'DocumentFragment': () => DocumentFragment.instanceRuntimeType,
  'DocumentType': () => _DocumentType.instanceRuntimeType,
  'EffectModel': () => EffectModel.instanceRuntimeType,
  'Element': () => Element.instanceRuntimeType,
  'Entry': () => Entry.instanceRuntimeType,
  'EntrySync': () => _EntrySync.instanceRuntimeType,
  'ErrorEvent': () => ErrorEvent.instanceRuntimeType,
  'Event': () => Event.instanceRuntimeType,
  'EventSource': () => EventSource.instanceRuntimeType,
  'EventTarget': () => EventTarget.instanceRuntimeType,
  'ExtendableEvent': () => ExtendableEvent.instanceRuntimeType,
  'FederatedCredential': () => FederatedCredential.instanceRuntimeType,
  'FetchEvent': () => FetchEvent.instanceRuntimeType,
  'File': () => File.instanceRuntimeType,
  'FileEntry': () => FileEntry.instanceRuntimeType,
  'FileEntrySync': () => _FileEntrySync.instanceRuntimeType,
  'FileError': () => FileError.instanceRuntimeType,
  'FileList': () => FileList.instanceRuntimeType,
  'FileReader': () => FileReader.instanceRuntimeType,
  'FileReaderSync': () => _FileReaderSync.instanceRuntimeType,
  'FileWriter': () => FileWriter.instanceRuntimeType,
  'FileWriterSync': () => _FileWriterSync.instanceRuntimeType,
  'FocusEvent': () => FocusEvent.instanceRuntimeType,
  'FontFace': () => FontFace.instanceRuntimeType,
  'FontFaceSet': () => FontFaceSet.instanceRuntimeType,
  'FontFaceSetLoadEvent': () => FontFaceSetLoadEvent.instanceRuntimeType,
  'FormData': () => FormData.instanceRuntimeType,
  'Gamepad': () => Gamepad.instanceRuntimeType,
  'GamepadButton': () => GamepadButton.instanceRuntimeType,
  'GamepadEvent': () => GamepadEvent.instanceRuntimeType,
  'GamepadList': () => _GamepadList.instanceRuntimeType,
  'Geofencing': () => Geofencing.instanceRuntimeType,
  'GeofencingEvent': () => GeofencingEvent.instanceRuntimeType,
  'GeofencingRegion': () => GeofencingRegion.instanceRuntimeType,
  'Geolocation': () => Geolocation.instanceRuntimeType,
  'Geoposition': () => Geoposition.instanceRuntimeType,
  'GlobalEventHandlers': () => GlobalEventHandlers.instanceRuntimeType,
  'HMDVRDevice': () => HmdvrDevice.instanceRuntimeType,
  'HTMLAllCollection': () => _HTMLAllCollection.instanceRuntimeType,
  'HTMLAnchorElement': () => AnchorElement.instanceRuntimeType,
  'HTMLAppletElement': () => _HTMLAppletElement.instanceRuntimeType,
  'HTMLAreaElement': () => AreaElement.instanceRuntimeType,
  'HTMLAudioElement': () => AudioElement.instanceRuntimeType,
  'HTMLBRElement': () => BRElement.instanceRuntimeType,
  'HTMLBaseElement': () => BaseElement.instanceRuntimeType,
  'HTMLBodyElement': () => BodyElement.instanceRuntimeType,
  'HTMLButtonElement': () => ButtonElement.instanceRuntimeType,
  'HTMLCanvasElement': () => CanvasElement.instanceRuntimeType,
  'HTMLCollection': () => HtmlCollection.instanceRuntimeType,
  'HTMLContentElement': () => ContentElement.instanceRuntimeType,
  'HTMLDListElement': () => DListElement.instanceRuntimeType,
  'HTMLDataListElement': () => DataListElement.instanceRuntimeType,
  'HTMLDetailsElement': () => DetailsElement.instanceRuntimeType,
  'HTMLDialogElement': () => DialogElement.instanceRuntimeType,
  'HTMLDirectoryElement': () => _HTMLDirectoryElement.instanceRuntimeType,
  'HTMLDivElement': () => DivElement.instanceRuntimeType,
  'HTMLDocument': () => HtmlDocument.instanceRuntimeType,
  'HTMLElement': () => HtmlElement.instanceRuntimeType,
  'HTMLEmbedElement': () => EmbedElement.instanceRuntimeType,
  'HTMLFieldSetElement': () => FieldSetElement.instanceRuntimeType,
  'HTMLFontElement': () => _HTMLFontElement.instanceRuntimeType,
  'HTMLFormControlsCollection': () => HtmlFormControlsCollection.instanceRuntimeType,
  'HTMLFormElement': () => FormElement.instanceRuntimeType,
  'HTMLFrameElement': () => _HTMLFrameElement.instanceRuntimeType,
  'HTMLFrameSetElement': () => _HTMLFrameSetElement.instanceRuntimeType,
  'HTMLHRElement': () => HRElement.instanceRuntimeType,
  'HTMLHeadElement': () => HeadElement.instanceRuntimeType,
  'HTMLHeadingElement': () => HeadingElement.instanceRuntimeType,
  'HTMLHtmlElement': () => HtmlHtmlElement.instanceRuntimeType,
  'HTMLIFrameElement': () => IFrameElement.instanceRuntimeType,
  'HTMLImageElement': () => ImageElement.instanceRuntimeType,
  'HTMLInputElement': () => InputElement.instanceRuntimeType,
  'HTMLKeygenElement': () => KeygenElement.instanceRuntimeType,
  'HTMLLIElement': () => LIElement.instanceRuntimeType,
  'HTMLLabelElement': () => LabelElement.instanceRuntimeType,
  'HTMLLegendElement': () => LegendElement.instanceRuntimeType,
  'HTMLLinkElement': () => LinkElement.instanceRuntimeType,
  'HTMLMapElement': () => MapElement.instanceRuntimeType,
  'HTMLMarqueeElement': () => _HTMLMarqueeElement.instanceRuntimeType,
  'HTMLMediaElement': () => MediaElement.instanceRuntimeType,
  'HTMLMenuElement': () => MenuElement.instanceRuntimeType,
  'HTMLMenuItemElement': () => MenuItemElement.instanceRuntimeType,
  'HTMLMetaElement': () => MetaElement.instanceRuntimeType,
  'HTMLMeterElement': () => MeterElement.instanceRuntimeType,
  'HTMLModElement': () => ModElement.instanceRuntimeType,
  'HTMLOListElement': () => OListElement.instanceRuntimeType,
  'HTMLObjectElement': () => ObjectElement.instanceRuntimeType,
  'HTMLOptGroupElement': () => OptGroupElement.instanceRuntimeType,
  'HTMLOptionElement': () => OptionElement.instanceRuntimeType,
  'HTMLOptionsCollection': () => HtmlOptionsCollection.instanceRuntimeType,
  'HTMLOutputElement': () => OutputElement.instanceRuntimeType,
  'HTMLParagraphElement': () => ParagraphElement.instanceRuntimeType,
  'HTMLParamElement': () => ParamElement.instanceRuntimeType,
  'HTMLPictureElement': () => PictureElement.instanceRuntimeType,
  'HTMLPreElement': () => PreElement.instanceRuntimeType,
  'HTMLProgressElement': () => ProgressElement.instanceRuntimeType,
  'HTMLQuoteElement': () => QuoteElement.instanceRuntimeType,
  'HTMLScriptElement': () => ScriptElement.instanceRuntimeType,
  'HTMLSelectElement': () => SelectElement.instanceRuntimeType,
  'HTMLShadowElement': () => ShadowElement.instanceRuntimeType,
  'HTMLSourceElement': () => SourceElement.instanceRuntimeType,
  'HTMLSpanElement': () => SpanElement.instanceRuntimeType,
  'HTMLStyleElement': () => StyleElement.instanceRuntimeType,
  'HTMLTableCaptionElement': () => TableCaptionElement.instanceRuntimeType,
  'HTMLTableCellElement': () => TableCellElement.instanceRuntimeType,
  'HTMLTableColElement': () => TableColElement.instanceRuntimeType,
  'HTMLTableElement': () => TableElement.instanceRuntimeType,
  'HTMLTableRowElement': () => TableRowElement.instanceRuntimeType,
  'HTMLTableSectionElement': () => TableSectionElement.instanceRuntimeType,
  'HTMLTemplateElement': () => TemplateElement.instanceRuntimeType,
  'HTMLTextAreaElement': () => TextAreaElement.instanceRuntimeType,
  'HTMLTitleElement': () => TitleElement.instanceRuntimeType,
  'HTMLTrackElement': () => TrackElement.instanceRuntimeType,
  'HTMLUListElement': () => UListElement.instanceRuntimeType,
  'HTMLUnknownElement': () => UnknownElement.instanceRuntimeType,
  'HTMLVideoElement': () => VideoElement.instanceRuntimeType,
  'HashChangeEvent': () => HashChangeEvent.instanceRuntimeType,
  'Headers': () => Headers.instanceRuntimeType,
  'History': () => History.instanceRuntimeType,
  'ImageBitmap': () => ImageBitmap.instanceRuntimeType,
  'ImageData': () => ImageData.instanceRuntimeType,
  'InjectedScriptHost': () => InjectedScriptHost.instanceRuntimeType,
  'InputDevice': () => InputDevice.instanceRuntimeType,
  'Iterator': () => DomIterator.instanceRuntimeType,
  'KeyboardEvent': () => KeyboardEvent.instanceRuntimeType,
  'KeyframeEffect': () => KeyframeEffect.instanceRuntimeType,
  'Location': () => Location.instanceRuntimeType,
  'MIDIAccess': () => MidiAccess.instanceRuntimeType,
  'MIDIConnectionEvent': () => MidiConnectionEvent.instanceRuntimeType,
  'MIDIInput': () => MidiInput.instanceRuntimeType,
  'MIDIInputMap': () => MidiInputMap.instanceRuntimeType,
  'MIDIMessageEvent': () => MidiMessageEvent.instanceRuntimeType,
  'MIDIOutput': () => MidiOutput.instanceRuntimeType,
  'MIDIOutputMap': () => MidiOutputMap.instanceRuntimeType,
  'MIDIPort': () => MidiPort.instanceRuntimeType,
  'MediaController': () => MediaController.instanceRuntimeType,
  'MediaDeviceInfo': () => MediaDeviceInfo.instanceRuntimeType,
  'MediaDevices': () => MediaDevices.instanceRuntimeType,
  'MediaEncryptedEvent': () => MediaEncryptedEvent.instanceRuntimeType,
  'MediaError': () => MediaError.instanceRuntimeType,
  'MediaKeyError': () => MediaKeyError.instanceRuntimeType,
  'MediaKeyEvent': () => MediaKeyEvent.instanceRuntimeType,
  'MediaKeyMessageEvent': () => MediaKeyMessageEvent.instanceRuntimeType,
  'MediaKeySession': () => MediaKeySession.instanceRuntimeType,
  'MediaKeyStatusMap': () => MediaKeyStatusMap.instanceRuntimeType,
  'MediaKeySystemAccess': () => MediaKeySystemAccess.instanceRuntimeType,
  'MediaKeys': () => MediaKeys.instanceRuntimeType,
  'MediaList': () => MediaList.instanceRuntimeType,
  'MediaQueryList': () => MediaQueryList.instanceRuntimeType,
  'MediaQueryListEvent': () => MediaQueryListEvent.instanceRuntimeType,
  'MediaSession': () => MediaSession.instanceRuntimeType,
  'MediaSource': () => MediaSource.instanceRuntimeType,
  'MediaStream': () => MediaStream.instanceRuntimeType,
  'MediaStreamEvent': () => MediaStreamEvent.instanceRuntimeType,
  'MediaStreamTrack': () => MediaStreamTrack.instanceRuntimeType,
  'MediaStreamTrackEvent': () => MediaStreamTrackEvent.instanceRuntimeType,
  'MemoryInfo': () => MemoryInfo.instanceRuntimeType,
  'MessageChannel': () => MessageChannel.instanceRuntimeType,
  'MessageEvent': () => MessageEvent.instanceRuntimeType,
  'MessagePort': () => MessagePort.instanceRuntimeType,
  'Metadata': () => Metadata.instanceRuntimeType,
  'MimeType': () => MimeType.instanceRuntimeType,
  'MimeTypeArray': () => MimeTypeArray.instanceRuntimeType,
  'MouseEvent': () => MouseEvent.instanceRuntimeType,
  'MutationObserver': () => MutationObserver.instanceRuntimeType,
  'MutationRecord': () => MutationRecord.instanceRuntimeType,
  'NamedNodeMap': () => _NamedNodeMap.instanceRuntimeType,
  'Navigator': () => Navigator.instanceRuntimeType,
  'NavigatorCPU': () => NavigatorCpu.instanceRuntimeType,
  'NavigatorID': () => NavigatorID.instanceRuntimeType,
  'NavigatorLanguage': () => NavigatorLanguage.instanceRuntimeType,
  'NavigatorOnLine': () => NavigatorOnLine.instanceRuntimeType,
  'NavigatorStorageUtils': () => NavigatorStorageUtils.instanceRuntimeType,
  'NavigatorUserMediaError': () => NavigatorUserMediaError.instanceRuntimeType,
  'NetworkInformation': () => NetworkInformation.instanceRuntimeType,
  'Node': () => Node.instanceRuntimeType,
  'NodeFilter': () => NodeFilter.instanceRuntimeType,
  'NodeIterator': () => NodeIterator.instanceRuntimeType,
  'NodeList': () => NodeList.instanceRuntimeType,
  'NonDocumentTypeChildNode': () => NonDocumentTypeChildNode.instanceRuntimeType,
  'NonElementParentNode': () => NonElementParentNode.instanceRuntimeType,
  'Notification': () => Notification.instanceRuntimeType,
  'NotificationEvent': () => NotificationEvent.instanceRuntimeType,
  'PagePopupController': () => _PagePopupController.instanceRuntimeType,
  'PageTransitionEvent': () => PageTransitionEvent.instanceRuntimeType,
  'ParentNode': () => ParentNode.instanceRuntimeType,
  'PasswordCredential': () => PasswordCredential.instanceRuntimeType,
  'Path2D': () => Path2D.instanceRuntimeType,
  'Performance': () => Performance.instanceRuntimeType,
  'PerformanceCompositeTiming': () => PerformanceCompositeTiming.instanceRuntimeType,
  'PerformanceEntry': () => PerformanceEntry.instanceRuntimeType,
  'PerformanceMark': () => PerformanceMark.instanceRuntimeType,
  'PerformanceMeasure': () => PerformanceMeasure.instanceRuntimeType,
  'PerformanceNavigation': () => PerformanceNavigation.instanceRuntimeType,
  'PerformanceRenderTiming': () => PerformanceRenderTiming.instanceRuntimeType,
  'PerformanceResourceTiming': () => PerformanceResourceTiming.instanceRuntimeType,
  'PerformanceTiming': () => PerformanceTiming.instanceRuntimeType,
  'PeriodicSyncEvent': () => PeriodicSyncEvent.instanceRuntimeType,
  'PeriodicSyncManager': () => PeriodicSyncManager.instanceRuntimeType,
  'PeriodicSyncRegistration': () => PeriodicSyncRegistration.instanceRuntimeType,
  'PermissionStatus': () => PermissionStatus.instanceRuntimeType,
  'Permissions': () => Permissions.instanceRuntimeType,
  'Plugin': () => Plugin.instanceRuntimeType,
  'PluginArray': () => PluginArray.instanceRuntimeType,
  'PluginPlaceholderElement': () => PluginPlaceholderElement.instanceRuntimeType,
  'PointerEvent': () => PointerEvent.instanceRuntimeType,
  'PopStateEvent': () => PopStateEvent.instanceRuntimeType,
  'PositionError': () => PositionError.instanceRuntimeType,
  'PositionSensorVRDevice': () => PositionSensorVRDevice.instanceRuntimeType,
  'Presentation': () => Presentation.instanceRuntimeType,
  'PresentationAvailability': () => PresentationAvailability.instanceRuntimeType,
  'PresentationSession': () => PresentationSession.instanceRuntimeType,
  'ProcessingInstruction': () => ProcessingInstruction.instanceRuntimeType,
  'ProgressEvent': () => ProgressEvent.instanceRuntimeType,
  'PromiseRejectionEvent': () => PromiseRejectionEvent.instanceRuntimeType,
  'PushEvent': () => PushEvent.instanceRuntimeType,
  'PushManager': () => PushManager.instanceRuntimeType,
  'PushMessageData': () => PushMessageData.instanceRuntimeType,
  'PushSubscription': () => PushSubscription.instanceRuntimeType,
  'RTCDTMFSender': () => RtcDtmfSender.instanceRuntimeType,
  'RTCDTMFToneChangeEvent': () => RtcDtmfToneChangeEvent.instanceRuntimeType,
  'RTCDataChannel': () => RtcDataChannel.instanceRuntimeType,
  'RTCDataChannelEvent': () => RtcDataChannelEvent.instanceRuntimeType,
  'RTCIceCandidate': () => RtcIceCandidate.instanceRuntimeType,
  'RTCIceCandidateEvent': () => RtcIceCandidateEvent.instanceRuntimeType,
  'RTCPeerConnection': () => RtcPeerConnection.instanceRuntimeType,
  'RTCSessionDescription': () => RtcSessionDescription.instanceRuntimeType,
  'RTCStatsReport': () => RtcStatsReport.instanceRuntimeType,
  'RTCStatsResponse': () => RtcStatsResponse.instanceRuntimeType,
  'RadioNodeList': () => _RadioNodeList.instanceRuntimeType,
  'Range': () => Range.instanceRuntimeType,
  'ReadableByteStream': () => ReadableByteStream.instanceRuntimeType,
  'ReadableByteStreamReader': () => ReadableByteStreamReader.instanceRuntimeType,
  'ReadableStream': () => ReadableStream.instanceRuntimeType,
  'ReadableStreamReader': () => ReadableStreamReader.instanceRuntimeType,
  'RelatedEvent': () => RelatedEvent.instanceRuntimeType,
  'Request': () => _Request.instanceRuntimeType,
  'ResourceProgressEvent': () => _ResourceProgressEvent.instanceRuntimeType,
  'Response': () => _Response.instanceRuntimeType,
  'Screen': () => Screen.instanceRuntimeType,
  'ScreenOrientation': () => ScreenOrientation.instanceRuntimeType,
  'ScrollState': () => ScrollState.instanceRuntimeType,
  'SecurityPolicyViolationEvent': () => SecurityPolicyViolationEvent.instanceRuntimeType,
  'Selection': () => Selection.instanceRuntimeType,
  'ServicePort': () => ServicePort.instanceRuntimeType,
  'ServicePortCollection': () => ServicePortCollection.instanceRuntimeType,
  'ServicePortConnectEvent': () => ServicePortConnectEvent.instanceRuntimeType,
  'ServiceWorker': () => _ServiceWorker.instanceRuntimeType,
  'ServiceWorkerContainer': () => ServiceWorkerContainer.instanceRuntimeType,
  'ServiceWorkerGlobalScope': () => ServiceWorkerGlobalScope.instanceRuntimeType,
  'ServiceWorkerMessageEvent': () => ServiceWorkerMessageEvent.instanceRuntimeType,
  'ServiceWorkerRegistration': () => ServiceWorkerRegistration.instanceRuntimeType,
  'ShadowRoot': () => ShadowRoot.instanceRuntimeType,
  'SharedArrayBuffer': () => SharedArrayBuffer.instanceRuntimeType,
  'SharedWorker': () => SharedWorker.instanceRuntimeType,
  'SharedWorkerGlobalScope': () => SharedWorkerGlobalScope.instanceRuntimeType,
  'SourceBuffer': () => SourceBuffer.instanceRuntimeType,
  'SourceBufferList': () => SourceBufferList.instanceRuntimeType,
  'SourceInfo': () => SourceInfo.instanceRuntimeType,
  'SpeechGrammar': () => SpeechGrammar.instanceRuntimeType,
  'SpeechGrammarList': () => SpeechGrammarList.instanceRuntimeType,
  'SpeechRecognition': () => SpeechRecognition.instanceRuntimeType,
  'SpeechRecognitionAlternative': () => SpeechRecognitionAlternative.instanceRuntimeType,
  'SpeechRecognitionError': () => SpeechRecognitionError.instanceRuntimeType,
  'SpeechRecognitionEvent': () => SpeechRecognitionEvent.instanceRuntimeType,
  'SpeechRecognitionResult': () => SpeechRecognitionResult.instanceRuntimeType,
  'SpeechRecognitionResultList': () => _SpeechRecognitionResultList.instanceRuntimeType,
  'SpeechSynthesis': () => SpeechSynthesis.instanceRuntimeType,
  'SpeechSynthesisEvent': () => SpeechSynthesisEvent.instanceRuntimeType,
  'SpeechSynthesisUtterance': () => SpeechSynthesisUtterance.instanceRuntimeType,
  'SpeechSynthesisVoice': () => SpeechSynthesisVoice.instanceRuntimeType,
  'StashedMessagePort': () => StashedMessagePort.instanceRuntimeType,
  'StashedPortCollection': () => StashedPortCollection.instanceRuntimeType,
  'Storage': () => Storage.instanceRuntimeType,
  'StorageEvent': () => StorageEvent.instanceRuntimeType,
  'StorageInfo': () => StorageInfo.instanceRuntimeType,
  'StorageQuota': () => StorageQuota.instanceRuntimeType,
  'Stream': () => FileStream.instanceRuntimeType,
  'StyleMedia': () => StyleMedia.instanceRuntimeType,
  'StyleSheet': () => StyleSheet.instanceRuntimeType,
  'StyleSheetList': () => _StyleSheetList.instanceRuntimeType,
  'SubtleCrypto': () => _SubtleCrypto.instanceRuntimeType,
  'SyncEvent': () => SyncEvent.instanceRuntimeType,
  'SyncManager': () => SyncManager.instanceRuntimeType,
  'SyncRegistration': () => SyncRegistration.instanceRuntimeType,
  'Text': () => Text.instanceRuntimeType,
  'TextEvent': () => TextEvent.instanceRuntimeType,
  'TextMetrics': () => TextMetrics.instanceRuntimeType,
  'TextTrack': () => TextTrack.instanceRuntimeType,
  'TextTrackCue': () => TextTrackCue.instanceRuntimeType,
  'TextTrackCueList': () => TextTrackCueList.instanceRuntimeType,
  'TextTrackList': () => TextTrackList.instanceRuntimeType,
  'TimeRanges': () => TimeRanges.instanceRuntimeType,
  'Touch': () => Touch.instanceRuntimeType,
  'TouchEvent': () => TouchEvent.instanceRuntimeType,
  'TouchList': () => TouchList.instanceRuntimeType,
  'TrackDefault': () => TrackDefault.instanceRuntimeType,
  'TrackDefaultList': () => TrackDefaultList.instanceRuntimeType,
  'TrackEvent': () => TrackEvent.instanceRuntimeType,
  'TransitionEvent': () => TransitionEvent.instanceRuntimeType,
  'TreeWalker': () => TreeWalker.instanceRuntimeType,
  'UIEvent': () => UIEvent.instanceRuntimeType,
  'URL': () => Url.instanceRuntimeType,
  'URLUtils': () => UrlUtils.instanceRuntimeType,
  'URLUtilsReadOnly': () => UrlUtilsReadOnly.instanceRuntimeType,
  'VRDevice': () => VRDevice.instanceRuntimeType,
  'VREyeParameters': () => VREyeParameters.instanceRuntimeType,
  'VRFieldOfView': () => VRFieldOfView.instanceRuntimeType,
  'VRPositionState': () => VRPositionState.instanceRuntimeType,
  'VTTCue': () => VttCue.instanceRuntimeType,
  'VTTRegion': () => VttRegion.instanceRuntimeType,
  'VTTRegionList': () => VttRegionList.instanceRuntimeType,
  'ValidityState': () => ValidityState.instanceRuntimeType,
  'VideoPlaybackQuality': () => VideoPlaybackQuality.instanceRuntimeType,
  'VideoTrack': () => VideoTrack.instanceRuntimeType,
  'VideoTrackList': () => VideoTrackList.instanceRuntimeType,
  'WebKitCSSMatrix': () => _WebKitCSSMatrix.instanceRuntimeType,
  'WebSocket': () => WebSocket.instanceRuntimeType,
  'WheelEvent': () => WheelEvent.instanceRuntimeType,
  'Window': () => Window.instanceRuntimeType,
  'WindowBase64': () => WindowBase64.instanceRuntimeType,
  'WindowClient': () => WindowClient.instanceRuntimeType,
  'WindowEventHandlers': () => WindowEventHandlers.instanceRuntimeType,
  'WindowTimers': () => _WindowTimers.instanceRuntimeType,
  'Worker': () => Worker.instanceRuntimeType,
  'WorkerConsole': () => WorkerConsole.instanceRuntimeType,
  'WorkerGlobalScope': () => WorkerGlobalScope.instanceRuntimeType,
  'WorkerLocation': () => _WorkerLocation.instanceRuntimeType,
  'WorkerNavigator': () => _WorkerNavigator.instanceRuntimeType,
  'WorkerPerformance': () => WorkerPerformance.instanceRuntimeType,
  'XMLDocument': () => XmlDocument.instanceRuntimeType,
  'XMLHttpRequest': () => HttpRequest.instanceRuntimeType,
  'XMLHttpRequestEventTarget': () => HttpRequestEventTarget.instanceRuntimeType,
  'XMLHttpRequestProgressEvent': () => _XMLHttpRequestProgressEvent.instanceRuntimeType,
  'XMLHttpRequestUpload': () => HttpRequestUpload.instanceRuntimeType,
  'XMLSerializer': () => XmlSerializer.instanceRuntimeType,
  'XPathEvaluator': () => XPathEvaluator.instanceRuntimeType,
  'XPathExpression': () => XPathExpression.instanceRuntimeType,
  'XPathNSResolver': () => XPathNSResolver.instanceRuntimeType,
  'XPathResult': () => XPathResult.instanceRuntimeType,
  'XSLTProcessor': () => XsltProcessor.instanceRuntimeType,

};

// TODO(leafp): We may want to move this elsewhere if html becomes
// a package to avoid dartium depending on pkg:html.
@Deprecated("Internal Use Only")
getHtmlCreateType(String key) => _getType(key);

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

// TODO(jacobr): it would be nice to place these conversion methods in a consistent place for dart2js and dartium.

WindowBase _convertNativeToDart_Window(win) {
  if (win == null) return null;
  return _DOMWindowCrossFrame._createSafe(win);
}

EventTarget _convertNativeToDart_EventTarget(e) {
  if (e == null) {
    return null;
  }
  // Assume it's a Window if it contains the postMessage property.  It may be
  // from a different frame - without a patched prototype - so we cannot
  // rely on Dart type checking.
  try {
    if (js.JsNative.hasProperty(e, "postMessage")) {
      var window = _DOMWindowCrossFrame._createSafe(e);
      // If it's a native window.
      if (window is EventTarget) {
        return window;
      }
      return null;
    }
  } catch (err) {
    print("Error calling _convertNativeToDart_EventTarget... $err");
  }
  return e;
}

EventTarget _convertDartToNative_EventTarget(e) {
  // _DOMWindowCrossFrame uses an interceptor so we don't need to do anything unlike Dart2Js.
  return e;
}

_convertNativeToDart_XHR_Response(o) {
  if (o is Document) {
    return o;
  }
  return convertNativeToDart_SerializedScriptValue(o);
}


/******************************************************************************
 **********                                                          **********
 **********                    JS Interop Support                    **********
 **********                                                          **********
 ******************************************************************************/

String _getCustomElementExtends(object) {
  var entry = getCustomElementEntry(object);
  if (entry != null) {
    return entry['extends'];
  }
  return null;
}

// Return the tag name or is attribute of the custom element or data binding.
String _getCustomElementName(element) {
  var jsObject;
  var tag = "";
  var runtimeType = element.runtimeType;
  if (runtimeType == TemplateElement) {
    // Data binding with a Dart class.
    tag = element.attributes['is'];
  } else if (element is HtmlElement) {
    tag = element.attributes['is'];
    if (tag == null) {
      // It's a custom element we want the local name.
      tag = element.localName;
    }
  } else {
    throw new UnsupportedError('Element is incorrect type. Got ${runtimeType}, expected HtmlElement/HtmlTemplate/JsObject.');
  }

  return tag;
}

/// An abstract class for all DOM objects we wrap in dart:html and related
///  libraries.
@Deprecated("Internal Use Only")
class DartHtmlDomObject extends js.JSObject {
  DartHtmlDomObject() : super.internal();
}

@Deprecated("Internal Use Only")
class DebugAssertException implements Exception {
  String message;
  DebugAssertException(this.message);
}

@Deprecated("Internal Use Only")
debug_or_assert(message, expression) {
  if (!expression) {
    throw new DebugAssertException("$message");
  }
}

@Deprecated("Internal Use Only")
Map<String, dynamic> convertNativeObjectToDartMap(js.JsObject jsObject) {
  var result = new Map();
  var keys = js.JsNative.callMethod(js.JsNative.getProperty(js.context, 'Object'), 'keys', [jsObject]);
  for (var key in keys) {
    result[key] = js.JsNative.getProperty(jsObject, key);
  }
  return result;
}

/**
 * Upgrade the JS HTMLElement to the Dart class.  Used by Dart's Polymer.
 */
_createCustomUpgrader(Type customElementClass, $this) {
  return _blink.Blink_Utils.setInstanceInterceptor($this, customElementClass, customElement: 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.


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

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

  /// Stream of `error` events handled by this [AbstractWorker].
  @DomName('AbstractWorker.onerror')
  @DocsEditable()
  Stream<Event> get onError => errorEvent.forTarget(this);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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}) {
    AnchorElement e = document.createElement("a");
    if (href != null) e.href = href;
    return e;
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  AnchorElement.internal_() : super.internal_();

  /**
   * 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()
  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()
  set hreflang(String value) => _blink.BlinkHTMLAnchorElement.instance.hreflang_Setter_(this, value);
  
  @DomName('HTMLAnchorElement.rel')
  @DocsEditable()
  String get rel => _blink.BlinkHTMLAnchorElement.instance.rel_Getter_(this);
  
  @DomName('HTMLAnchorElement.rel')
  @DocsEditable()
  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()
  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()
  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()
  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()
  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()
  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()
  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
  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()
  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()
  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()
  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()
  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
  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 EventTarget {
  // To suppress missing implicit constructor warnings.
  factory Animation._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Animation.internal_() : super.internal_();


  /// Checks if this type is supported on the current platform.
  static bool get supported => true;

  @DomName('Animation.currentTime')
  @DocsEditable()
  @Experimental() // untriaged
  num get currentTime => _blink.BlinkAnimation.instance.currentTime_Getter_(this);
  
  @DomName('Animation.currentTime')
  @DocsEditable()
  @Experimental() // untriaged
  set currentTime(num value) => _blink.BlinkAnimation.instance.currentTime_Setter_(this, value);
  
  @DomName('Animation.effect')
  @DocsEditable()
  @Experimental() // untriaged
  AnimationEffectReadOnly get effect => _blink.BlinkAnimation.instance.effect_Getter_(this);
  
  @DomName('Animation.effect')
  @DocsEditable()
  @Experimental() // untriaged
  set effect(AnimationEffectReadOnly value) => _blink.BlinkAnimation.instance.effect_Setter_(this, value);
  
  @DomName('Animation.endClip')
  @DocsEditable()
  @Experimental() // untriaged
  num get endClip => _blink.BlinkAnimation.instance.endClip_Getter_(this);
  
  @DomName('Animation.endClip')
  @DocsEditable()
  @Experimental() // untriaged
  set endClip(num value) => _blink.BlinkAnimation.instance.endClip_Setter_(this, value);
  
  @DomName('Animation.finished')
  @DocsEditable()
  @Experimental() // untriaged
  Future get finished => convertNativePromiseToDartFuture(_blink.BlinkAnimation.instance.finished_Getter_(this));
  
  @DomName('Animation.playState')
  @DocsEditable()
  @Experimental() // untriaged
  String get playState => _blink.BlinkAnimation.instance.playState_Getter_(this);
  
  @DomName('Animation.playbackRate')
  @DocsEditable()
  @Experimental() // untriaged
  num get playbackRate => _blink.BlinkAnimation.instance.playbackRate_Getter_(this);
  
  @DomName('Animation.playbackRate')
  @DocsEditable()
  @Experimental() // untriaged
  set playbackRate(num value) => _blink.BlinkAnimation.instance.playbackRate_Setter_(this, value);
  
  @DomName('Animation.ready')
  @DocsEditable()
  @Experimental() // untriaged
  Future get ready => convertNativePromiseToDartFuture(_blink.BlinkAnimation.instance.ready_Getter_(this));
  
  @DomName('Animation.startClip')
  @DocsEditable()
  @Experimental() // untriaged
  num get startClip => _blink.BlinkAnimation.instance.startClip_Getter_(this);
  
  @DomName('Animation.startClip')
  @DocsEditable()
  @Experimental() // untriaged
  set startClip(num value) => _blink.BlinkAnimation.instance.startClip_Setter_(this, value);
  
  @DomName('Animation.startTime')
  @DocsEditable()
  @Experimental() // untriaged
  num get startTime => _blink.BlinkAnimation.instance.startTime_Getter_(this);
  
  @DomName('Animation.startTime')
  @DocsEditable()
  @Experimental() // untriaged
  set startTime(num value) => _blink.BlinkAnimation.instance.startTime_Setter_(this, value);
  
  @DomName('Animation.cancel')
  @DocsEditable()
  @Experimental() // untriaged
  void cancel() => _blink.BlinkAnimation.instance.cancel_Callback_0_(this);
  
  @DomName('Animation.finish')
  @DocsEditable()
  @Experimental() // untriaged
  void finish() => _blink.BlinkAnimation.instance.finish_Callback_0_(this);
  
  @DomName('Animation.pause')
  @DocsEditable()
  @Experimental() // untriaged
  void pause() => _blink.BlinkAnimation.instance.pause_Callback_0_(this);
  
  @DomName('Animation.play')
  @DocsEditable()
  @Experimental() // untriaged
  void play() => _blink.BlinkAnimation.instance.play_Callback_0_(this);
  
  @DomName('Animation.reverse')
  @DocsEditable()
  @Experimental() // untriaged
  void reverse() => _blink.BlinkAnimation.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('AnimationEffectReadOnly')
@Experimental() // untriaged
class AnimationEffectReadOnly extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory AnimationEffectReadOnly._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  AnimationEffectReadOnly.internal_() { }

  @DomName('AnimationEffectReadOnly.computedTiming')
  @DocsEditable()
  @Experimental() // untriaged
   get computedTiming => convertNativeDictionaryToDartDictionary((_blink.BlinkAnimationEffectReadOnly.instance.computedTiming_Getter_(this)));
  
  @DomName('AnimationEffectReadOnly.timing')
  @DocsEditable()
  @Experimental() // untriaged
  AnimationEffectTiming get timing => _blink.BlinkAnimationEffectReadOnly.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('AnimationEffectTiming')
@Experimental() // untriaged
class AnimationEffectTiming extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory AnimationEffectTiming._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  AnimationEffectTiming.internal_() { }

  @DomName('AnimationEffectTiming.delay')
  @DocsEditable()
  @Experimental() // untriaged
  num get delay => _blink.BlinkAnimationEffectTiming.instance.delay_Getter_(this);
  
  @DomName('AnimationEffectTiming.delay')
  @DocsEditable()
  @Experimental() // untriaged
  set delay(num value) => _blink.BlinkAnimationEffectTiming.instance.delay_Setter_(this, value);
  
  @DomName('AnimationEffectTiming.direction')
  @DocsEditable()
  @Experimental() // untriaged
  String get direction => _blink.BlinkAnimationEffectTiming.instance.direction_Getter_(this);
  
  @DomName('AnimationEffectTiming.direction')
  @DocsEditable()
  @Experimental() // untriaged
  set direction(String value) => _blink.BlinkAnimationEffectTiming.instance.direction_Setter_(this, value);
  
  @DomName('AnimationEffectTiming.duration')
  @DocsEditable()
  @Experimental() // untriaged
  Object get duration => (_blink.BlinkAnimationEffectTiming.instance.duration_Getter_(this));
  
  @DomName('AnimationEffectTiming.duration')
  @DocsEditable()
  @Experimental() // untriaged
  set duration(Object value) => _blink.BlinkAnimationEffectTiming.instance.duration_Setter_(this, value);
  
  @DomName('AnimationEffectTiming.easing')
  @DocsEditable()
  @Experimental() // untriaged
  String get easing => _blink.BlinkAnimationEffectTiming.instance.easing_Getter_(this);
  
  @DomName('AnimationEffectTiming.easing')
  @DocsEditable()
  @Experimental() // untriaged
  set easing(String value) => _blink.BlinkAnimationEffectTiming.instance.easing_Setter_(this, value);
  
  @DomName('AnimationEffectTiming.endDelay')
  @DocsEditable()
  @Experimental() // untriaged
  num get endDelay => _blink.BlinkAnimationEffectTiming.instance.endDelay_Getter_(this);
  
  @DomName('AnimationEffectTiming.endDelay')
  @DocsEditable()
  @Experimental() // untriaged
  set endDelay(num value) => _blink.BlinkAnimationEffectTiming.instance.endDelay_Setter_(this, value);
  
  @DomName('AnimationEffectTiming.fill')
  @DocsEditable()
  @Experimental() // untriaged
  String get fill => _blink.BlinkAnimationEffectTiming.instance.fill_Getter_(this);
  
  @DomName('AnimationEffectTiming.fill')
  @DocsEditable()
  @Experimental() // untriaged
  set fill(String value) => _blink.BlinkAnimationEffectTiming.instance.fill_Setter_(this, value);
  
  @DomName('AnimationEffectTiming.iterationStart')
  @DocsEditable()
  @Experimental() // untriaged
  num get iterationStart => _blink.BlinkAnimationEffectTiming.instance.iterationStart_Getter_(this);
  
  @DomName('AnimationEffectTiming.iterationStart')
  @DocsEditable()
  @Experimental() // untriaged
  set iterationStart(num value) => _blink.BlinkAnimationEffectTiming.instance.iterationStart_Setter_(this, value);
  
  @DomName('AnimationEffectTiming.iterations')
  @DocsEditable()
  @Experimental() // untriaged
  num get iterations => _blink.BlinkAnimationEffectTiming.instance.iterations_Getter_(this);
  
  @DomName('AnimationEffectTiming.iterations')
  @DocsEditable()
  @Experimental() // untriaged
  set iterations(num value) => _blink.BlinkAnimationEffectTiming.instance.iterations_Setter_(this, value);
  
  @DomName('AnimationEffectTiming.playbackRate')
  @DocsEditable()
  @Experimental() // untriaged
  num get playbackRate => _blink.BlinkAnimationEffectTiming.instance.playbackRate_Getter_(this);
  
  @DomName('AnimationEffectTiming.playbackRate')
  @DocsEditable()
  @Experimental() // untriaged
  set playbackRate(num value) => _blink.BlinkAnimationEffectTiming.instance.playbackRate_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('AnimationEvent')
@Experimental() // untriaged
class AnimationEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory AnimationEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('AnimationEvent.AnimationEvent')
  @DocsEditable()
  factory AnimationEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkAnimationEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkAnimationEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  AnimationEvent.internal_() : super.internal_();


  @DomName('AnimationEvent.animationName')
  @DocsEditable()
  @Experimental() // untriaged
  String get animationName => _blink.BlinkAnimationEvent.instance.animationName_Getter_(this);
  
  @DomName('AnimationEvent.elapsedTime')
  @DocsEditable()
  @Experimental() // untriaged
  num get elapsedTime => _blink.BlinkAnimationEvent.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('AnimationPlayerEvent')
@Experimental() // untriaged
class AnimationPlayerEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory AnimationPlayerEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('AnimationPlayerEvent.AnimationPlayerEvent')
  @DocsEditable()
  factory AnimationPlayerEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkAnimationPlayerEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkAnimationPlayerEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  AnimationPlayerEvent.internal_() : super.internal_();


  @DomName('AnimationPlayerEvent.currentTime')
  @DocsEditable()
  @Experimental() // untriaged
  num get currentTime => _blink.BlinkAnimationPlayerEvent.instance.currentTime_Getter_(this);
  
  @DomName('AnimationPlayerEvent.timelineTime')
  @DocsEditable()
  @Experimental() // untriaged
  num 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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory AnimationTimeline._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  AnimationTimeline.internal_() { }

  @DomName('AnimationTimeline.currentTime')
  @DocsEditable()
  @Experimental() // untriaged
  num get currentTime => _blink.BlinkAnimationTimeline.instance.currentTime_Getter_(this);
  
  @DomName('AnimationTimeline.currentTime')
  @DocsEditable()
  @Experimental() // untriaged
  set currentTime(num value) => _blink.BlinkAnimationTimeline.instance.currentTime_Setter_(this, value);
  
  @DomName('AnimationTimeline.playbackRate')
  @DocsEditable()
  @Experimental() // untriaged
  num get playbackRate => _blink.BlinkAnimationTimeline.instance.playbackRate_Getter_(this);
  
  @DomName('AnimationTimeline.playbackRate')
  @DocsEditable()
  @Experimental() // untriaged
  set playbackRate(num value) => _blink.BlinkAnimationTimeline.instance.playbackRate_Setter_(this, value);
  
  @DomName('AnimationTimeline.getAnimations')
  @DocsEditable()
  @Experimental() // untriaged
  List<Animation> getAnimations() => (_blink.BlinkAnimationTimeline.instance.getAnimations_Callback_0_(this));
  
  @DomName('AnimationTimeline.play')
  @DocsEditable()
  @Experimental() // untriaged
  Animation play(AnimationEffectReadOnly 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()
@DomName('AppBannerPromptResult')
@Experimental() // untriaged
class AppBannerPromptResult extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory AppBannerPromptResult._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  AppBannerPromptResult.internal_() { }

  @DomName('AppBannerPromptResult.outcome')
  @DocsEditable()
  @Experimental() // untriaged
  String get outcome => _blink.BlinkAppBannerPromptResult.instance.outcome_Getter_(this);
  
  @DomName('AppBannerPromptResult.platform')
  @DocsEditable()
  @Experimental() // untriaged
  String get platform => _blink.BlinkAppBannerPromptResult.instance.platform_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()
/**
 * 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');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ApplicationCache.internal_() : super.internal_();


  /// 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.ApplicationCacheErrorEvent')
  @DocsEditable()
  factory ApplicationCacheErrorEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkApplicationCacheErrorEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkApplicationCacheErrorEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ApplicationCacheErrorEvent.internal_() : super.internal_();


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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  AreaElement.internal_() : super.internal_();

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


@DocsEditable()
@DomName('HTMLAudioElement')
class AudioElement extends MediaElement {

  @DomName('HTMLAudioElement.HTMLAudioElement')
  @DocsEditable()
  factory AudioElement._([String src]) {
    return _blink.BlinkHTMLAudioElement.instance.constructorCallback_1_(src);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  AudioElement.internal_() : super.internal_();

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

  factory AudioElement([String src]) {
    if (src == null)
      return _blink.BlinkHTMLAudioElement.instance.constructorCallback_0_();
    else
      return _blink.BlinkHTMLAudioElement.instance.constructorCallback_1_(src);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  AudioTrack.internal_() { }

  @DomName('AudioTrack.enabled')
  @DocsEditable()
  @Experimental() // untriaged
  bool get enabled => _blink.BlinkAudioTrack.instance.enabled_Getter_(this);
  
  @DomName('AudioTrack.enabled')
  @DocsEditable()
  @Experimental() // untriaged
  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');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  AudioTrackList.internal_() : super.internal_();


  @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.AutocompleteErrorEvent')
  @DocsEditable()
  factory AutocompleteErrorEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkAutocompleteErrorEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkAutocompleteErrorEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  AutocompleteErrorEvent.internal_() : super.internal_();


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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  BRElement.internal_() : super.internal_();

  /**
   * 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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory BarProp._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  BarProp.internal_() { }

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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  BaseElement.internal_() : super.internal_();

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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  BatteryManager.internal_() : super.internal_();


  @DomName('BatteryManager.charging')
  @DocsEditable()
  bool get charging => _blink.BlinkBatteryManager.instance.charging_Getter_(this);
  
  @DomName('BatteryManager.chargingTime')
  @DocsEditable()
  num get chargingTime => _blink.BlinkBatteryManager.instance.chargingTime_Getter_(this);
  
  @DomName('BatteryManager.dischargingTime')
  @DocsEditable()
  num get dischargingTime => _blink.BlinkBatteryManager.instance.dischargingTime_Getter_(this);
  
  @DomName('BatteryManager.level')
  @DocsEditable()
  num 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('BeforeInstallPromptEvent')
@Experimental() // untriaged
class BeforeInstallPromptEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory BeforeInstallPromptEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('BeforeInstallPromptEvent.BeforeInstallPromptEvent')
  @DocsEditable()
  factory BeforeInstallPromptEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkBeforeInstallPromptEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkBeforeInstallPromptEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  BeforeInstallPromptEvent.internal_() : super.internal_();


  @DomName('BeforeInstallPromptEvent.platforms')
  @DocsEditable()
  @Experimental() // untriaged
  List<String> get platforms => _blink.BlinkBeforeInstallPromptEvent.instance.platforms_Getter_(this);
  
  @DomName('BeforeInstallPromptEvent.userChoice')
  @DocsEditable()
  @Experimental() // untriaged
  Future get userChoice => convertNativePromiseToDartFuture(_blink.BlinkBeforeInstallPromptEvent.instance.userChoice_Getter_(this));
  
  @DomName('BeforeInstallPromptEvent.prompt')
  @DocsEditable()
  @Experimental() // untriaged
  Future prompt() => convertNativePromiseToDartFuture(_blink.BlinkBeforeInstallPromptEvent.instance.prompt_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('BeforeUnloadEvent')
class BeforeUnloadEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory BeforeUnloadEvent._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  BeforeUnloadEvent.internal_() : super.internal_();


  @DomName('BeforeUnloadEvent.returnValue')
  @DocsEditable()
  String get returnValue => _blink.BlinkBeforeUnloadEvent.instance.returnValue_Getter_(this);
  
  @DomName('BeforeUnloadEvent.returnValue')
  @DocsEditable()
  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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory Blob._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Blob.internal_() { }

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

  factory Blob(List blobParts, [String type, String endings]) {
    // TODO: any coercions on the elements of blobParts, e.g. coerce a typed
    // array to ArrayBuffer if it is a total view.

    var parts = convertDartToNative_List(blobParts);
    if (type == null && endings == null) {
      return _blink.BlinkBlob.instance.constructorCallback_1_(parts);
    }
    var bag = {};
    if (type != null) bag['type'] = type;
    if (endings != null) bag['endings'] = endings;
    return _blink.BlinkBlob.instance.constructorCallback_2_(parts,
        convertDartToNative_Dictionary(bag));
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Bluetooth.internal_() { }

  @DomName('Bluetooth.requestDevice')
  @DocsEditable()
  @Experimental() // untriaged
  Future requestDevice(Map options) => convertNativePromiseToDartFuture(_blink.BlinkBluetooth.instance.requestDevice_Callback_1_(this, convertDartToNative_Dictionary(options)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  BluetoothDevice.internal_() { }

  @DomName('BluetoothDevice.deviceClass')
  @DocsEditable()
  @Experimental() // untriaged
  int get deviceClass => _blink.BlinkBluetoothDevice.instance.deviceClass_Getter_(this);
  
  @DomName('BluetoothDevice.instanceID')
  @DocsEditable()
  @Experimental() // untriaged
  String get instanceID => _blink.BlinkBluetoothDevice.instance.instanceID_Getter_(this);
  
  @DomName('BluetoothDevice.name')
  @DocsEditable()
  @Experimental() // untriaged
  String get name => _blink.BlinkBluetoothDevice.instance.name_Getter_(this);
  
  @DomName('BluetoothDevice.paired')
  @DocsEditable()
  @Experimental() // untriaged
  bool get paired => _blink.BlinkBluetoothDevice.instance.paired_Getter_(this);
  
  @DomName('BluetoothDevice.productID')
  @DocsEditable()
  @Experimental() // untriaged
  int get productID => _blink.BlinkBluetoothDevice.instance.productID_Getter_(this);
  
  @DomName('BluetoothDevice.productVersion')
  @DocsEditable()
  @Experimental() // untriaged
  int get productVersion => _blink.BlinkBluetoothDevice.instance.productVersion_Getter_(this);
  
  @DomName('BluetoothDevice.vendorID')
  @DocsEditable()
  @Experimental() // untriaged
  int get vendorID => _blink.BlinkBluetoothDevice.instance.vendorID_Getter_(this);
  
  @DomName('BluetoothDevice.vendorIDSource')
  @DocsEditable()
  @Experimental() // untriaged
  String get vendorIDSource => _blink.BlinkBluetoothDevice.instance.vendorIDSource_Getter_(this);
  
  @DomName('BluetoothDevice.connectGATT')
  @DocsEditable()
  @Experimental() // untriaged
  Future connectGatt() => convertNativePromiseToDartFuture(_blink.BlinkBluetoothDevice.instance.connectGATT_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('BluetoothGATTCharacteristic')
@Experimental() // untriaged
class BluetoothGattCharacteristic extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory BluetoothGattCharacteristic._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  BluetoothGattCharacteristic.internal_() { }

  @DomName('BluetoothGATTCharacteristic.uuid')
  @DocsEditable()
  @Experimental() // untriaged
  String get uuid => _blink.BlinkBluetoothGATTCharacteristic.instance.uuid_Getter_(this);
  
  @DomName('BluetoothGATTCharacteristic.readValue')
  @DocsEditable()
  @Experimental() // untriaged
  Future readValue() => convertNativePromiseToDartFuture(_blink.BlinkBluetoothGATTCharacteristic.instance.readValue_Callback_0_(this));
  
  @DomName('BluetoothGATTCharacteristic.writeValue')
  @DocsEditable()
  @Experimental() // untriaged
  Future writeValue(/*BufferSource*/ value) => convertNativePromiseToDartFuture(_blink.BlinkBluetoothGATTCharacteristic.instance.writeValue_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('BluetoothGATTRemoteServer')
@Experimental() // untriaged
class BluetoothGattRemoteServer extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory BluetoothGattRemoteServer._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  BluetoothGattRemoteServer.internal_() { }

  @DomName('BluetoothGATTRemoteServer.connected')
  @DocsEditable()
  @Experimental() // untriaged
  bool get connected => _blink.BlinkBluetoothGATTRemoteServer.instance.connected_Getter_(this);
  
  @DomName('BluetoothGATTRemoteServer.getPrimaryService')
  @DocsEditable()
  @Experimental() // untriaged
  Future getPrimaryService(/*BluetoothServiceUUID*/ service) => convertNativePromiseToDartFuture(_blink.BlinkBluetoothGATTRemoteServer.instance.getPrimaryService_Callback_1_(this, service));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  BluetoothGattService.internal_() { }

  @DomName('BluetoothGATTService.isPrimary')
  @DocsEditable()
  @Experimental() // untriaged
  bool get isPrimary => _blink.BlinkBluetoothGATTService.instance.isPrimary_Getter_(this);
  
  @DomName('BluetoothGATTService.uuid')
  @DocsEditable()
  @Experimental() // untriaged
  String get uuid => _blink.BlinkBluetoothGATTService.instance.uuid_Getter_(this);
  
  @DomName('BluetoothGATTService.getCharacteristic')
  @DocsEditable()
  @Experimental() // untriaged
  Future getCharacteristic(/*BluetoothCharacteristicUUID*/ characteristic) => convertNativePromiseToDartFuture(_blink.BlinkBluetoothGATTService.instance.getCharacteristic_Callback_1_(this, characteristic));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  BluetoothUuid.internal_() { }

  @DomName('BluetoothUUID.canonicalUUID')
  @DocsEditable()
  @Experimental() // untriaged
  static String canonicalUuid(int alias) => _blink.BlinkBluetoothUUID.instance.canonicalUUID_Callback_1_(alias);
  
  @DomName('BluetoothUUID.getCharacteristic')
  @DocsEditable()
  @Experimental() // untriaged
  static String getCharacteristic(Object name) => _blink.BlinkBluetoothUUID.instance.getCharacteristic_Callback_1_(name);
  
  @DomName('BluetoothUUID.getDescriptor')
  @DocsEditable()
  @Experimental() // untriaged
  static String getDescriptor(Object name) => _blink.BlinkBluetoothUUID.instance.getDescriptor_Callback_1_(name);
  
  @DomName('BluetoothUUID.getService')
  @DocsEditable()
  @Experimental() // untriaged
  static String getService(Object name) => _blink.BlinkBluetoothUUID.instance.getService_Callback_1_(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('Body')
@Experimental() // untriaged
class Body extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory Body._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Body.internal_() { }

  @DomName('Body.bodyUsed')
  @DocsEditable()
  @Experimental() // untriaged
  bool get bodyUsed => _blink.BlinkBody.instance.bodyUsed_Getter_(this);
  
  @DomName('Body.arrayBuffer')
  @DocsEditable()
  @Experimental() // untriaged
  Future arrayBuffer() => convertNativePromiseToDartFuture(_blink.BlinkBody.instance.arrayBuffer_Callback_0_(this));
  
  @DomName('Body.blob')
  @DocsEditable()
  @Experimental() // untriaged
  Future blob() => convertNativePromiseToDartFuture(_blink.BlinkBody.instance.blob_Callback_0_(this));
  
  @DomName('Body.json')
  @DocsEditable()
  @Experimental() // untriaged
  Future json() => convertNativePromiseToDartFuture(_blink.BlinkBody.instance.json_Callback_0_(this));
  
  @DomName('Body.text')
  @DocsEditable()
  @Experimental() // untriaged
  Future text() => convertNativePromiseToDartFuture(_blink.BlinkBody.instance.text_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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  BodyElement.internal_() : super.internal_();

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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ButtonElement.internal_() : super.internal_();

  /**
   * 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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() => _blink.BlinkHTMLButtonElement.instance.reportValidity_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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CDataSection.internal_() : super.internal_();


}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory CacheStorage._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CacheStorage.internal_() { }

  @DomName('CacheStorage.delete')
  @DocsEditable()
  @Experimental() // untriaged
  Future delete(String cacheName) => convertNativePromiseToDartFuture(_blink.BlinkCacheStorage.instance.delete_Callback_1_(this, cacheName));
  
  @DomName('CacheStorage.has')
  @DocsEditable()
  @Experimental() // untriaged
  Future has(String cacheName) => convertNativePromiseToDartFuture(_blink.BlinkCacheStorage.instance.has_Callback_1_(this, cacheName));
  
  @DomName('CacheStorage.keys')
  @DocsEditable()
  @Experimental() // untriaged
  Future keys() => convertNativePromiseToDartFuture(_blink.BlinkCacheStorage.instance.keys_Callback_0_(this));
  
  Future match(/*RequestInfo*/ request, [Map options]) {
    if (options != null) {
      return _blink.BlinkCacheStorage.instance.match_Callback_2_(this, request, convertDartToNative_Dictionary(options));
    }
    return _blink.BlinkCacheStorage.instance.match_Callback_1_(this, request);
  }

  @DomName('CacheStorage.open')
  @DocsEditable()
  @Experimental() // untriaged
  Future open(String cacheName) => convertNativePromiseToDartFuture(_blink.BlinkCacheStorage.instance.open_Callback_1_(this, cacheName));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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}) {
    CanvasElement e = document.createElement("canvas");
    if (width != null) e.width = width;
    if (height != null) e.height = height;
    return e;
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CanvasElement.internal_() : super.internal_();

  /**
   * 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()
  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()
  set width(int value) => _blink.BlinkHTMLCanvasElement.instance.width_Setter_(this, value);
  
  Object getContext(String contextId, [Map attributes]) {
    if (attributes != null) {
      return _blink.BlinkHTMLCanvasElement.instance.getContext_Callback_2_(this, contextId, convertDartToNative_Dictionary(attributes));
    }
    return _blink.BlinkHTMLCanvasElement.instance.getContext_Callback_1_(this, contextId);
  }

  String _toDataUrl(String type, [arguments_OR_quality]) {
    if ((type is String || type == null) && arguments_OR_quality == null) {
      return _blink.BlinkHTMLCanvasElement.instance.toDataURL_Callback_1_(this, type);
    }
    if (arguments_OR_quality != null && (type is String || type == null)) {
      return _blink.BlinkHTMLCanvasElement.instance.toDataURL_Callback_2_(this, type, arguments_OR_quality);
    }
    if ((type is String || type == null) && arguments_OR_quality == null) {
      return _blink.BlinkHTMLCanvasElement.instance.toDataURL_Callback_1_(this, type);
    }
    if ((arguments_OR_quality is num || arguments_OR_quality == null) && (type is String || type == null)) {
      return _blink.BlinkHTMLCanvasElement.instance.toDataURL_Callback_2_(this, type, arguments_OR_quality);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CanvasGradient.internal_() { }

  /**
   * 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](https://html.spec.whatwg.org/multipage/scripting.html#canvaspattern)
 *   from WHATWG.
 * * [CanvasPattern](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvaspattern) from W3C.
 */
@DomName('CanvasPattern')
class CanvasPattern extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory CanvasPattern._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CanvasPattern.internal_() { }

  @DomName('CanvasPattern.setTransform')
  @DocsEditable()
  @Experimental() // untriaged
  void setTransform(Matrix transform) => _blink.BlinkCanvasPattern.instance.setTransform_Callback_1_(this, transform);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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 DartHtmlDomObject implements CanvasRenderingContext {
  // To suppress missing implicit constructor warnings.
  factory CanvasRenderingContext2D._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CanvasRenderingContext2D.internal_() { }

  @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
  set currentTransform(Matrix value) => _blink.BlinkCanvasRenderingContext2D.instance.currentTransform_Setter_(this, value);
  
  @DomName('CanvasRenderingContext2D.direction')
  @DocsEditable()
  @Experimental() // untriaged
  String get direction => _blink.BlinkCanvasRenderingContext2D.instance.direction_Getter_(this);
  
  @DomName('CanvasRenderingContext2D.direction')
  @DocsEditable()
  @Experimental() // untriaged
  set direction(String value) => _blink.BlinkCanvasRenderingContext2D.instance.direction_Setter_(this, value);
  
  @DomName('CanvasRenderingContext2D.fillStyle')
  @DocsEditable()
  Object get fillStyle => (_blink.BlinkCanvasRenderingContext2D.instance.fillStyle_Getter_(this));
  
  @DomName('CanvasRenderingContext2D.fillStyle')
  @DocsEditable()
  set fillStyle(Object value) => _blink.BlinkCanvasRenderingContext2D.instance.fillStyle_Setter_(this, value);
  
  @DomName('CanvasRenderingContext2D.filter')
  @DocsEditable()
  @Experimental() // untriaged
  String get filter => _blink.BlinkCanvasRenderingContext2D.instance.filter_Getter_(this);
  
  @DomName('CanvasRenderingContext2D.filter')
  @DocsEditable()
  @Experimental() // untriaged
  set filter(String value) => _blink.BlinkCanvasRenderingContext2D.instance.filter_Setter_(this, value);
  
  @DomName('CanvasRenderingContext2D.font')
  @DocsEditable()
  String get font => _blink.BlinkCanvasRenderingContext2D.instance.font_Getter_(this);
  
  @DomName('CanvasRenderingContext2D.font')
  @DocsEditable()
  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()
  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()
  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](https://html.spec.whatwg.org/multipage/scripting.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](https://html.spec.whatwg.org/multipage/scripting.html#image-smoothing)
   *   from WHATWG.
   */
  @DomName('CanvasRenderingContext2D.imageSmoothingEnabled')
  @DocsEditable()
  @Experimental() // untriaged
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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, convertDartToNative_Dictionary(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");
  }

  ImageData createImageData(imagedata_OR_sw, [num sh]) {
    if ((imagedata_OR_sw is ImageData) && sh == null) {
      return _blink.BlinkCanvasRenderingContext2D.instance.createImageData_Callback_1_(this, imagedata_OR_sw);
    }
    if ((sh is num) && (imagedata_OR_sw is num)) {
      return _blink.BlinkCanvasRenderingContext2D.instance.createImageData_Callback_2_(this, imagedata_OR_sw, sh);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @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);
  
  @DomName('CanvasRenderingContext2D.createPattern')
  @DocsEditable()
  CanvasPattern createPattern(Object 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(Object image, 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) && image != null && sw_OR_width == null && height_OR_sh == null && dx == null && dy == null && dw == null && dh == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_3_(this, image, 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) && image != null && dx == null && dy == null && dw == null && dh == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_5_(this, image, 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) && image != null) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_9_(this, image, 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()
   getContextAttributes() => convertNativeDictionaryToDartDictionary((_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, convertDartToNative_ImageData(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, convertDartToNative_ImageData(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);
  

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

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

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

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

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

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

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

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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CharacterData.internal_() : super.internal_();


  @DomName('CharacterData.data')
  @DocsEditable()
  String get data => _blink.BlinkCharacterData.instance.data_Getter_(this);
  
  @DomName('CharacterData.data')
  @DocsEditable()
  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 count) => _blink.BlinkCharacterData.instance.deleteData_Callback_2_(this, offset, count);
  
  @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 count, String data) => _blink.BlinkCharacterData.instance.replaceData_Callback_3_(this, offset, count, data);
  
  @DomName('CharacterData.substringData')
  @DocsEditable()
  String substringData(int offset, int count) => _blink.BlinkCharacterData.instance.substringData_Callback_2_(this, offset, count);
  
  @DomName('CharacterData.after')
  @DocsEditable()
  @Experimental() // untriaged
  void after(Object nodes) => _blink.BlinkCharacterData.instance.after_Callback_1_(this, nodes);
  
  @DomName('CharacterData.before')
  @DocsEditable()
  @Experimental() // untriaged
  void before(Object nodes) => _blink.BlinkCharacterData.instance.before_Callback_1_(this, nodes);
  
  @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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory ChildNode._() { throw new UnsupportedError("Not supported"); }

  @DomName('ChildNode.after')
  @DocsEditable()
  @Experimental() // untriaged
  void after(Object nodes);

  @DomName('ChildNode.before')
  @DocsEditable()
  @Experimental() // untriaged
  void before(Object nodes);

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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ChromiumValuebuffer.internal_() { }

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

// WARNING: Do not edit - generated code.


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

  @DomName('CircularGeofencingRegion.CircularGeofencingRegion')
  @DocsEditable()
  factory CircularGeofencingRegion(Map init) {
    var init_1 = convertDartToNative_Dictionary(init);
    return _blink.BlinkCircularGeofencingRegion.instance.constructorCallback_1_(init_1);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CircularGeofencingRegion.internal_() : super.internal_();


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

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

  @DomName('CircularGeofencingRegion.latitude')
  @DocsEditable()
  @Experimental() // untriaged
  num get latitude => _blink.BlinkCircularGeofencingRegion.instance.latitude_Getter_(this);
  
  @DomName('CircularGeofencingRegion.longitude')
  @DocsEditable()
  @Experimental() // untriaged
  num get longitude => _blink.BlinkCircularGeofencingRegion.instance.longitude_Getter_(this);
  
  @DomName('CircularGeofencingRegion.radius')
  @DocsEditable()
  @Experimental() // untriaged
  num get radius => _blink.BlinkCircularGeofencingRegion.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('Client')
@Experimental() // untriaged
class Client extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory Client._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Client.internal_() { }

  @DomName('Client.frameType')
  @DocsEditable()
  @Experimental() // untriaged
  String get frameType => _blink.BlinkClient.instance.frameType_Getter_(this);
  
  @DomName('Client.id')
  @DocsEditable()
  @Experimental() // untriaged
  String get id => _blink.BlinkClient.instance.id_Getter_(this);
  
  @DomName('Client.url')
  @DocsEditable()
  @Experimental() // untriaged
  String get url => _blink.BlinkClient.instance.url_Getter_(this);
  
  void postMessage(/*SerializedScriptValue*/ message, [List<MessagePort> transfer]) {
    if (transfer != null) {
      _blink.BlinkClient.instance.postMessage_Callback_2_(this, convertDartToNative_SerializedScriptValue(message), transfer);
      return;
    }
    _blink.BlinkClient.instance.postMessage_Callback_1_(this, convertDartToNative_SerializedScriptValue(message));
    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('Clients')
@Experimental() // untriaged
class Clients extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory Clients._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Clients.internal_() { }

  @DomName('Clients.claim')
  @DocsEditable()
  @Experimental() // untriaged
  Future claim() => convertNativePromiseToDartFuture(_blink.BlinkClients.instance.claim_Callback_0_(this));
  
  Future matchAll([Map options]) {
    if (options != null) {
      return _blink.BlinkClients.instance.matchAll_Callback_1_(this, convertDartToNative_Dictionary(options));
    }
    return _blink.BlinkClients.instance.matchAll_Callback_0_(this);
  }

  @DomName('Clients.openWindow')
  @DocsEditable()
  @Experimental() // untriaged
  Future openWindow(String url) => convertNativePromiseToDartFuture(_blink.BlinkClients.instance.openWindow_Callback_1_(this, 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('ClipboardEvent')
@Experimental() // untriaged
class ClipboardEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory ClipboardEvent._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ClipboardEvent.internal_() : super.internal_();


  @DomName('ClipboardEvent.clipboardData')
  @DocsEditable()
  @Experimental() // untriaged
  DataTransfer get clipboardData => _blink.BlinkClipboardEvent.instance.clipboardData_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.CloseEvent')
  @DocsEditable()
  factory CloseEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkCloseEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkCloseEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CloseEvent.internal_() : super.internal_();


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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Comment.internal_() : super.internal_();

}
// 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, String locale}) {
    if (view == null) {
      view = window;
    }
    CompositionEvent e = document._createEvent("CompositionEvent");

      e._initCompositionEvent(type, canBubble, cancelable, view, data);

    return e;
  }


  @DomName('CompositionEvent.CompositionEvent')
  @DocsEditable()
  factory CompositionEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkCompositionEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkCompositionEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CompositionEvent.internal_() : super.internal_();


  @DomName('CompositionEvent.data')
  @DocsEditable()
  String get data => _blink.BlinkCompositionEvent.instance.data_Getter_(this);
  
  @DomName('CompositionEvent.initCompositionEvent')
  @DocsEditable()
  void _initCompositionEvent(String type, bool bubbles, bool cancelable, Window view, String data) => _blink.BlinkCompositionEvent.instance.initCompositionEvent_Callback_5_(this, type, bubbles, cancelable, view, 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('CompositorProxy')
@Experimental() // untriaged
class CompositorProxy extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory CompositorProxy._() { throw new UnsupportedError("Not supported"); }

  @DomName('CompositorProxy.CompositorProxy')
  @DocsEditable()
  factory CompositorProxy(Element element, List<String> attributeArray) {
    return _blink.BlinkCompositorProxy.instance.constructorCallback_2_(element, attributeArray);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CompositorProxy.internal_() { }

  @DomName('CompositorProxy.opacity')
  @DocsEditable()
  @Experimental() // untriaged
  num get opacity => _blink.BlinkCompositorProxy.instance.opacity_Getter_(this);
  
  @DomName('CompositorProxy.opacity')
  @DocsEditable()
  @Experimental() // untriaged
  set opacity(num value) => _blink.BlinkCompositorProxy.instance.opacity_Setter_(this, value);
  
  @DomName('CompositorProxy.scrollLeft')
  @DocsEditable()
  @Experimental() // untriaged
  num get scrollLeft => _blink.BlinkCompositorProxy.instance.scrollLeft_Getter_(this);
  
  @DomName('CompositorProxy.scrollLeft')
  @DocsEditable()
  @Experimental() // untriaged
  set scrollLeft(num value) => _blink.BlinkCompositorProxy.instance.scrollLeft_Setter_(this, value);
  
  @DomName('CompositorProxy.scrollTop')
  @DocsEditable()
  @Experimental() // untriaged
  num get scrollTop => _blink.BlinkCompositorProxy.instance.scrollTop_Getter_(this);
  
  @DomName('CompositorProxy.scrollTop')
  @DocsEditable()
  @Experimental() // untriaged
  set scrollTop(num value) => _blink.BlinkCompositorProxy.instance.scrollTop_Setter_(this, value);
  
  @DomName('CompositorProxy.transform')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix get transform => _blink.BlinkCompositorProxy.instance.transform_Getter_(this);
  
  @DomName('CompositorProxy.transform')
  @DocsEditable()
  @Experimental() // untriaged
  set transform(DomMatrix value) => _blink.BlinkCompositorProxy.instance.transform_Setter_(this, value);
  
  @DomName('CompositorProxy.disconnect')
  @DocsEditable()
  @Experimental() // untriaged
  void disconnect() => _blink.BlinkCompositorProxy.instance.disconnect_Callback_0_(this);
  
  @DomName('CompositorProxy.supports')
  @DocsEditable()
  @Experimental() // untriaged
  bool supports(String attribute) => _blink.BlinkCompositorProxy.instance.supports_Callback_1_(this, attribute);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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

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

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

  @DomName('CompositorWorker.CompositorWorker')
  @DocsEditable()
  factory CompositorWorker(String scriptUrl) {
    return _blink.BlinkCompositorWorker.instance.constructorCallback_1_(scriptUrl);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CompositorWorker.internal_() : super.internal_();


  void postMessage(/*SerializedScriptValue*/ message, [List<MessagePort> transfer]) {
    if (transfer != null) {
      _blink.BlinkCompositorWorker.instance.postMessage_Callback_2_(this, convertDartToNative_SerializedScriptValue(message), transfer);
      return;
    }
    _blink.BlinkCompositorWorker.instance.postMessage_Callback_1_(this, convertDartToNative_SerializedScriptValue(message));
    return;
  }

  @DomName('CompositorWorker.terminate')
  @DocsEditable()
  @Experimental() // untriaged
  void terminate() => _blink.BlinkCompositorWorker.instance.terminate_Callback_0_(this);
  
  @DomName('CompositorWorker.onerror')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onError => errorEvent.forTarget(this);

  @DomName('CompositorWorker.onmessage')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

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

// WARNING: Do not edit - generated code.


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

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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CompositorWorkerGlobalScope.internal_() : super.internal_();


  @DomName('CompositorWorkerGlobalScope.cancelAnimationFrame')
  @DocsEditable()
  @Experimental() // untriaged
  void cancelAnimationFrame(int handle) => _blink.BlinkCompositorWorkerGlobalScope.instance.cancelAnimationFrame_Callback_1_(this, handle);
  
  void postMessage(Object message, [List<MessagePort> transfer]) {
    if (transfer != null) {
      _blink.BlinkCompositorWorkerGlobalScope.instance.postMessage_Callback_2_(this, convertDartToNative_SerializedScriptValue(message), transfer);
      return;
    }
    _blink.BlinkCompositorWorkerGlobalScope.instance.postMessage_Callback_1_(this, convertDartToNative_SerializedScriptValue(message));
    return;
  }

  @DomName('CompositorWorkerGlobalScope.requestAnimationFrame')
  @DocsEditable()
  @Experimental() // untriaged
  int requestAnimationFrame(FrameRequestCallback callback) => _blink.BlinkCompositorWorkerGlobalScope.instance.requestAnimationFrame_Callback_1_(this, callback);
  
  @DomName('CompositorWorkerGlobalScope.onmessage')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

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

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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Console.internal_() : super.internal_();


  @DomName('Console.memory')
  @DocsEditable()
  @Experimental()
  MemoryInfo get memory => _blink.BlinkConsole.instance.memory_Getter_(this);
  
  @DomName('Console.memory')
  @DocsEditable()
  @Experimental()
  set memory(MemoryInfo value) => _blink.BlinkConsole.instance.memory_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('ConsoleBase')
@Experimental() // untriaged
class ConsoleBase extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory ConsoleBase._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ConsoleBase.internal_() { }

  @DomName('ConsoleBase.assert')
  @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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ContentElement.internal_() : super.internal_();

  /**
   * 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()
  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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory Coordinates._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Coordinates.internal_() { }

  @DomName('Coordinates.accuracy')
  @DocsEditable()
  num get accuracy => _blink.BlinkCoordinates.instance.accuracy_Getter_(this);
  
  @DomName('Coordinates.altitude')
  @DocsEditable()
  num get altitude => _blink.BlinkCoordinates.instance.altitude_Getter_(this);
  
  @DomName('Coordinates.altitudeAccuracy')
  @DocsEditable()
  num get altitudeAccuracy => _blink.BlinkCoordinates.instance.altitudeAccuracy_Getter_(this);
  
  @DomName('Coordinates.heading')
  @DocsEditable()
  num get heading => _blink.BlinkCoordinates.instance.heading_Getter_(this);
  
  @DomName('Coordinates.latitude')
  @DocsEditable()
  num get latitude => _blink.BlinkCoordinates.instance.latitude_Getter_(this);
  
  @DomName('Coordinates.longitude')
  @DocsEditable()
  num get longitude => _blink.BlinkCoordinates.instance.longitude_Getter_(this);
  
  @DomName('Coordinates.speed')
  @DocsEditable()
  num 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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory Credential._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Credential.internal_() { }

  @DomName('Credential.iconURL')
  @DocsEditable()
  @Experimental() // untriaged
  String get iconUrl => _blink.BlinkCredential.instance.iconURL_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);
  
  @DomName('Credential.type')
  @DocsEditable()
  @Experimental() // untriaged
  String get type => _blink.BlinkCredential.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('CredentialsContainer')
@Experimental() // untriaged
class CredentialsContainer extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory CredentialsContainer._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CredentialsContainer.internal_() { }

  @DomName('CredentialsContainer.notifySignedIn')
  @DocsEditable()
  @Experimental() // untriaged
  Future notifySignedIn(Credential credential) => convertNativePromiseToDartFuture(_blink.BlinkCredentialsContainer.instance.notifySignedIn_Callback_1_(this, credential));
  
  Future request([Map options]) {
    if (options != null) {
      return _blink.BlinkCredentialsContainer.instance.request_Callback_1_(this, convertDartToNative_Dictionary(options));
    }
    return _blink.BlinkCredentialsContainer.instance.request_Callback_0_(this);
  }

  @DomName('CredentialsContainer.requireUserMediation')
  @DocsEditable()
  @Experimental() // untriaged
  Future requireUserMediation() => convertNativePromiseToDartFuture(_blink.BlinkCredentialsContainer.instance.requireUserMediation_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('CrossOriginConnectEvent')
@Experimental() // untriaged
class CrossOriginConnectEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory CrossOriginConnectEvent._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CrossOriginConnectEvent.internal_() : super.internal_();


  @DomName('CrossOriginConnectEvent.client')
  @DocsEditable()
  @Experimental() // untriaged
  CrossOriginServiceWorkerClient get client => _blink.BlinkCrossOriginConnectEvent.instance.client_Getter_(this);
  
  @DomName('CrossOriginConnectEvent.acceptConnection')
  @DocsEditable()
  @Experimental() // untriaged
  void acceptConnection(Future shouldAccept) => _blink.BlinkCrossOriginConnectEvent.instance.acceptConnection_Callback_1_(this, shouldAccept);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CrossOriginServiceWorkerClient.internal_() : super.internal_();


  @DomName('CrossOriginServiceWorkerClient.origin')
  @DocsEditable()
  @Experimental() // untriaged
  String get origin => _blink.BlinkCrossOriginServiceWorkerClient.instance.origin_Getter_(this);
  
  @DomName('CrossOriginServiceWorkerClient.targetUrl')
  @DocsEditable()
  @Experimental() // untriaged
  String get targetUrl => _blink.BlinkCrossOriginServiceWorkerClient.instance.targetUrl_Getter_(this);
  
  void postMessage(/*SerializedScriptValue*/ message, [List<MessagePort> transfer]) {
    if (transfer != null) {
      _blink.BlinkCrossOriginServiceWorkerClient.instance.postMessage_Callback_2_(this, convertDartToNative_SerializedScriptValue(message), transfer);
      return;
    }
    _blink.BlinkCrossOriginServiceWorkerClient.instance.postMessage_Callback_1_(this, convertDartToNative_SerializedScriptValue(message));
    return;
  }

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


@DomName('Crypto')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
// http://www.w3.org/TR/WebCryptoAPI/
class Crypto extends DartHtmlDomObject {

  TypedData getRandomValues(TypedData array) {
    var random = _getRandomValues(array);
    // The semantics of the operation are that it modifies the argument, but we
    // have no way of making a Dart typed data created initially in Dart reference
    // externalized storage. So we copy the values back from the returned copy.
    // TODO(alanknight): Make this less ridiculously slow.
    for (var i = 0; i < random.length; i++) {
      array[i] = random[i];
    }
    return array;
  }

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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Crypto.internal_() { }

  /// 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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory CryptoKey._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CryptoKey.internal_() { }

  @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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory Css._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Css.internal_() { }

  @DomName('CSS.supports')
  @DocsEditable()
  static bool supports(String property, String value) => _blink.BlinkCSS.instance.supports_Callback_2_(property, value);
  
  @DomName('CSS.supportsCondition')
  @DocsEditable()
  static bool supportsCondition(String conditionText) => _blink.BlinkCSS.instance.supports_Callback_1_(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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CssCharsetRule.internal_() : super.internal_();


  @DomName('CSSCharsetRule.encoding')
  @DocsEditable()
  String get encoding => _blink.BlinkCSSCharsetRule.instance.encoding_Getter_(this);
  
  @DomName('CSSCharsetRule.encoding')
  @DocsEditable()
  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('CSSFontFaceRule')
class CssFontFaceRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssFontFaceRule._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CssFontFaceRule.internal_() : super.internal_();


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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CssGroupingRule.internal_() : super.internal_();


  @DomName('CSSGroupingRule.cssRules')
  @DocsEditable()
  @Experimental() // untriaged
  List<CssRule> get cssRules => _blink.BlinkCSSGroupingRule.instance.cssRules_Getter_(this);
  
  @DomName('CSSGroupingRule.deleteRule')
  @DocsEditable()
  @Experimental() // untriaged
  void deleteRule(int index) => _blink.BlinkCSSGroupingRule.instance.deleteRule_Callback_1_(this, index);
  
  @DomName('CSSGroupingRule.insertRule')
  @DocsEditable()
  @Experimental() // untriaged
  int insertRule(String rule, int index) => _blink.BlinkCSSGroupingRule.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('CSSImportRule')
class CssImportRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssImportRule._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CssImportRule.internal_() : super.internal_();


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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CssKeyframeRule.internal_() : super.internal_();


  @DomName('CSSKeyframeRule.keyText')
  @DocsEditable()
  @Experimental() // untriaged
  String get keyText => _blink.BlinkCSSKeyframeRule.instance.keyText_Getter_(this);
  
  @DomName('CSSKeyframeRule.keyText')
  @DocsEditable()
  @Experimental() // untriaged
  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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CssKeyframesRule.internal_() : super.internal_();


  @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
  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.appendRule')
  @DocsEditable()
  @Experimental() // untriaged
  void appendRule(String rule) => _blink.BlinkCSSKeyframesRule.instance.appendRule_Callback_1_(this, rule);
  
  @DomName('CSSKeyframesRule.deleteRule')
  @DocsEditable()
  @Experimental() // untriaged
  void deleteRule(String select) => _blink.BlinkCSSKeyframesRule.instance.deleteRule_Callback_1_(this, select);
  
  @DomName('CSSKeyframesRule.findRule')
  @DocsEditable()
  @Experimental() // untriaged
  CssKeyframeRule findRule(String select) => _blink.BlinkCSSKeyframesRule.instance.findRule_Callback_1_(this, select);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 CssGroupingRule {
  // To suppress missing implicit constructor warnings.
  factory CssMediaRule._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CssMediaRule.internal_() : super.internal_();


  @DomName('CSSMediaRule.media')
  @DocsEditable()
  MediaList get media => _blink.BlinkCSSMediaRule.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('CSSPageRule')
class CssPageRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory CssPageRule._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CssPageRule.internal_() : super.internal_();


  @DomName('CSSPageRule.selectorText')
  @DocsEditable()
  String get selectorText => _blink.BlinkCSSPageRule.instance.selectorText_Getter_(this);
  
  @DomName('CSSPageRule.selectorText')
  @DocsEditable()
  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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory CssRule._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CssRule.internal_() { }

  @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_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()
  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 DartHtmlDomObject 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.instance.$__propertyQuery___Callback_1_(this, propertyName);

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

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

  static String _readCache(String key) => null;
  static void _writeCache(String key, value) {}

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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CssStyleDeclaration.internal_() { }

  @DomName('CSSStyleDeclaration.cssText')
  @DocsEditable()
  String get cssText => _blink.BlinkCSSStyleDeclaration.instance.cssText_Getter_(this);
  
  @DomName('CSSStyleDeclaration.cssText')
  @DocsEditable()
  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.__propertyQuery__')
  @DocsEditable()
  @Experimental() // untriaged
  bool __propertyQuery__(String name) => _blink.BlinkCSSStyleDeclaration.instance.$__propertyQuery___Callback_1_(this, name);
  
  @DomName('CSSStyleDeclaration.getPropertyPriority')
  @DocsEditable()
  String getPropertyPriority(String property) => _blink.BlinkCSSStyleDeclaration.instance.getPropertyPriority_Callback_1_(this, property);
  
  @DomName('CSSStyleDeclaration.getPropertyValue')
  @DocsEditable()
  String _getPropertyValue(String property) => _blink.BlinkCSSStyleDeclaration.instance.getPropertyValue_Callback_1_(this, property);
  
  @DomName('CSSStyleDeclaration.item')
  @DocsEditable()
  String item(int index) => _blink.BlinkCSSStyleDeclaration.instance.item_Callback_1_(this, index);
  
  @DomName('CSSStyleDeclaration.removeProperty')
  @DocsEditable()
  String removeProperty(String property) => _blink.BlinkCSSStyleDeclaration.instance.removeProperty_Callback_1_(this, property);
  
  @DomName('CSSStyleDeclaration.setProperty')
  @DocsEditable()
  void _setProperty(String property, String value, String priority) => _blink.BlinkCSSStyleDeclaration.instance.setProperty_Callback_3_(this, property, 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.
}

class CssStyleDeclarationBase {
  String getPropertyValue(String propertyName) =>
    throw new StateError('getProperty not overridden in dart:html');
  void setProperty(String propertyName, String value, [String priority]) =>
    throw new StateError('setProperty not overridden in dart:html');

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  /** Sets the value of "text-overline-mode" */
  set textOverlineMode(String value) {
    setProperty('text-overline-mode', value, '');
  }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  /** Gets the value of "transition" */@SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  String get transition =>
    getPropertyValue('transition');

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

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

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

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

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

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

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

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

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

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

  /** Sets the value of "unicode-bidi" */
  set unicodeBidi(String value) {
    setProperty('unicode-bidi', value, '');
  }

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

  /** Sets the value of "unicode-range" */
  set unicodeRange(String value) {
    setProperty('unicode-range', value, '');
  }

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

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

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

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

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

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

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

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

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

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

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

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

  /** Gets the value of "white-space" */
  String get whiteSpace =>
    getPropertyValue('white-space');

  /** Sets the value of "white-space" */
  set whiteSpace(String value) {
    setProperty('white-space', value, '');
  }

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

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

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

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

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

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

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

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

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

  /** Sets the value of "word-spacing" */
  set wordSpacing(String value) {
    setProperty('word-spacing', value, '');
  }

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

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

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

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

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

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

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

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

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

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

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

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

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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CssStyleRule.internal_() : super.internal_();


  @DomName('CSSStyleRule.selectorText')
  @DocsEditable()
  String get selectorText => _blink.BlinkCSSStyleRule.instance.selectorText_Getter_(this);
  
  @DomName('CSSStyleRule.selectorText')
  @DocsEditable()
  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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CssStyleSheet.internal_() : super.internal_();


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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CssSupportsRule.internal_() : super.internal_();


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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CssViewportRule.internal_() : super.internal_();


  @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 {
        detail = convertDartToNative_SerializedScriptValue(detail);
        e._initCustomEvent(type, canBubble, cancelable, detail);
      } catch(_) {
        e._initCustomEvent(type, canBubble, cancelable, null);
      }
    } else {
      e._initCustomEvent(type, canBubble, cancelable, null);
    }

    return e;
  }

  @DomName('CustomEvent.detail')
  get detail {
    if (_dartDetail != null) {
      return _dartDetail;
    }
    return _detail;
  }

  @DomName('CustomEvent.CustomEvent')
  @DocsEditable()
  factory CustomEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkCustomEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkCustomEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  CustomEvent.internal_() : super.internal_();


  @DomName('CustomEvent.detail')
  @DocsEditable()
  Object get _detail => convertNativeToDart_SerializedScriptValue(_blink.BlinkCustomEvent.instance.detail_Getter_(this));
  
  @DomName('CustomEvent.initCustomEvent')
  @DocsEditable()
  void _initCustomEvent(String type, bool bubbles, bool cancelable, Object detail) => _blink.BlinkCustomEvent.instance.initCustomEvent_Callback_4_(this, type, bubbles, cancelable, detail);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DListElement.internal_() : super.internal_();

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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DataListElement.internal_() : super.internal_();

  /**
   * 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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory DataTransfer._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DataTransfer.internal_() { }

  @DomName('DataTransfer.dropEffect')
  @DocsEditable()
  @Experimental() // untriaged
  String get dropEffect => _blink.BlinkDataTransfer.instance.dropEffect_Getter_(this);
  
  @DomName('DataTransfer.dropEffect')
  @DocsEditable()
  @Experimental() // untriaged
  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
  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 format]) {
    if (format != null) {
      _blink.BlinkDataTransfer.instance.clearData_Callback_1_(this, format);
      return;
    }
    _blink.BlinkDataTransfer.instance.clearData_Callback_0_(this);
    return;
  }

  @DomName('DataTransfer.getData')
  @DocsEditable()
  @Experimental() // untriaged
  String getData(String format) => _blink.BlinkDataTransfer.instance.getData_Callback_1_(this, format);
  
  @DomName('DataTransfer.setData')
  @DocsEditable()
  @Experimental() // untriaged
  void setData(String format, String data) => _blink.BlinkDataTransfer.instance.setData_Callback_2_(this, format, 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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory DataTransferItem._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DataTransferItem.internal_() { }

  @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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory DataTransferItemList._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DataTransferItemList.internal_() { }

  @DomName('DataTransferItemList.length')
  @DocsEditable()
  int get length => _blink.BlinkDataTransferItemList.instance.length_Getter_(this);
  
  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.item')
  @DocsEditable()
  DataTransferItem item(int index) => _blink.BlinkDataTransferItemList.instance.item_Callback_1_(this, index);
  
  @DomName('DataTransferItemList.remove')
  @DocsEditable()
  @Experimental() // untriaged
  void remove(int index) => _blink.BlinkDataTransferItemList.instance.remove_Callback_1_(this, index);
  

  DataTransferItem operator[] (int index) {
    // TODO(alanknight): I think that all the __getter__ generators should just
    // do property access, but that's major surgery. This one is a problem, so
    // just hard-code it for now.
    return _blink.Blink_JsNative_DomException.getProperty(this, index);
  }

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

// WARNING: Do not edit - generated code.


@DomName('DatabaseCallback')
// http://www.w3.org/TR/webdatabase/#databasecallback
@Experimental() // deprecated
typedef void DatabaseCallback(SqlDatabase database);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DedicatedWorkerGlobalScope.internal_() : super.internal_();


  void postMessage(Object message, [List<MessagePort> transfer]) {
    if (transfer != null) {
      _blink.BlinkDedicatedWorkerGlobalScope.instance.postMessage_Callback_2_(this, convertDartToNative_SerializedScriptValue(message), transfer);
      return;
    }
    _blink.BlinkDedicatedWorkerGlobalScope.instance.postMessage_Callback_1_(this, convertDartToNative_SerializedScriptValue(message));
    return;
  }

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

  @DomName('DefaultSessionStartEvent.DefaultSessionStartEvent')
  @DocsEditable()
  factory DefaultSessionStartEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkDefaultSessionStartEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkDefaultSessionStartEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DefaultSessionStartEvent.internal_() : super.internal_();


  @DomName('DefaultSessionStartEvent.session')
  @DocsEditable()
  @Experimental() // untriaged
  PresentationSession get session => _blink.BlinkDefaultSessionStartEvent.instance.session_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('DeprecatedStorageInfo')
@Experimental() // untriaged
class DeprecatedStorageInfo extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory DeprecatedStorageInfo._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DeprecatedStorageInfo.internal_() { }

  @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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory DeprecatedStorageQuota._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DeprecatedStorageQuota.internal_() { }

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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DetailsElement.internal_() : super.internal_();

  /**
   * 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()
  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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory DeviceAcceleration._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DeviceAcceleration.internal_() { }

  @DomName('DeviceAcceleration.x')
  @DocsEditable()
  num get x => _blink.BlinkDeviceAcceleration.instance.x_Getter_(this);
  
  @DomName('DeviceAcceleration.y')
  @DocsEditable()
  num get y => _blink.BlinkDeviceAcceleration.instance.y_Getter_(this);
  
  @DomName('DeviceAcceleration.z')
  @DocsEditable()
  num 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.DeviceLightEvent')
  @DocsEditable()
  factory DeviceLightEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkDeviceLightEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkDeviceLightEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DeviceLightEvent.internal_() : super.internal_();


  @DomName('DeviceLightEvent.value')
  @DocsEditable()
  @Experimental() // untriaged
  num 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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DeviceMotionEvent.internal_() : super.internal_();


  @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()
  num 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}) {
    DeviceOrientationEvent e = document._createEvent("DeviceOrientationEvent");
    e._initDeviceOrientationEvent(type, canBubble, cancelable, alpha, beta,
        gamma, absolute);
    return e;
  }
  // To suppress missing implicit constructor warnings.
  factory DeviceOrientationEvent._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DeviceOrientationEvent.internal_() : super.internal_();


  @DomName('DeviceOrientationEvent.absolute')
  @DocsEditable()
  bool get absolute => _blink.BlinkDeviceOrientationEvent.instance.absolute_Getter_(this);
  
  @DomName('DeviceOrientationEvent.alpha')
  @DocsEditable()
  num get alpha => _blink.BlinkDeviceOrientationEvent.instance.alpha_Getter_(this);
  
  @DomName('DeviceOrientationEvent.beta')
  @DocsEditable()
  num get beta => _blink.BlinkDeviceOrientationEvent.instance.beta_Getter_(this);
  
  @DomName('DeviceOrientationEvent.gamma')
  @DocsEditable()
  num 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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory DeviceRotationRate._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DeviceRotationRate.internal_() { }

  @DomName('DeviceRotationRate.alpha')
  @DocsEditable()
  num get alpha => _blink.BlinkDeviceRotationRate.instance.alpha_Getter_(this);
  
  @DomName('DeviceRotationRate.beta')
  @DocsEditable()
  num get beta => _blink.BlinkDeviceRotationRate.instance.beta_Getter_(this);
  
  @DomName('DeviceRotationRate.gamma')
  @DocsEditable()
  num 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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DialogElement.internal_() : super.internal_();

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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DirectoryEntry.internal_() : super.internal_();


  @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, convertDartToNative_Dictionary(options), successCallback, errorCallback);
      return;
    }
    if (successCallback != null) {
      _blink.BlinkDirectoryEntry.instance.getDirectory_Callback_3_(this, path, convertDartToNative_Dictionary(options), successCallback);
      return;
    }
    if (options != null) {
      _blink.BlinkDirectoryEntry.instance.getDirectory_Callback_2_(this, path, convertDartToNative_Dictionary(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, convertDartToNative_Dictionary(options), successCallback, errorCallback);
      return;
    }
    if (successCallback != null) {
      _blink.BlinkDirectoryEntry.instance.getFile_Callback_3_(this, path, convertDartToNative_Dictionary(options), successCallback);
      return;
    }
    if (options != null) {
      _blink.BlinkDirectoryEntry.instance.getFile_Callback_2_(this, path, convertDartToNative_Dictionary(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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory DirectoryReader._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DirectoryReader.internal_() { }

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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DivElement.internal_() : super.internal_();

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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Document.internal_() : super.internal_();


  @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()
  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()
  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 => _convertNativeToDart_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.origin')
  @DocsEditable()
  @Experimental() // untriaged
  String get origin => _blink.BlinkDocument.instance.origin_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.scrollingElement')
  @DocsEditable()
  @Experimental() // untriaged
  Element get scrollingElement => _blink.BlinkDocument.instance.scrollingElement_Getter_(this);
  
  @DomName('Document.selectedStylesheetSet')
  @DocsEditable()
  String get _selectedStylesheetSet => _blink.BlinkDocument.instance.selectedStylesheetSet_Getter_(this);
  
  @DomName('Document.selectedStylesheetSet')
  @DocsEditable()
  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()
  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 radiusX, num radiusY, num rotationAngle, num force) => _blink.BlinkDocument.instance.createTouch_Callback_11_(this, window, _convertDartToNative_EventTarget(target), identifier, pageX, pageY, screenX, screenY, radiusX, radiusY, rotationAngle, force);
  
  @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.elementsFromPoint')
  @DocsEditable()
  @Experimental() // untriaged
  List<Element> elementsFromPoint(int x, int y) => (_blink.BlinkDocument.instance.elementsFromPoint_Callback_2_(this, x, y));
  
  bool execCommand(String commandId, [bool showUI, String value]) {
    if (value != null) {
      return _blink.BlinkDocument.instance.execCommand_Callback_3_(this, commandId, showUI, value);
    }
    if (showUI != null) {
      return _blink.BlinkDocument.instance.execCommand_Callback_2_(this, commandId, showUI);
    }
    return _blink.BlinkDocument.instance.execCommand_Callback_1_(this, commandId);
  }

  @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.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 commandId) => _blink.BlinkDocument.instance.queryCommandEnabled_Callback_1_(this, commandId);
  
  @DomName('Document.queryCommandIndeterm')
  @DocsEditable()
  bool queryCommandIndeterm(String commandId) => _blink.BlinkDocument.instance.queryCommandIndeterm_Callback_1_(this, commandId);
  
  @DomName('Document.queryCommandState')
  @DocsEditable()
  bool queryCommandState(String commandId) => _blink.BlinkDocument.instance.queryCommandState_Callback_1_(this, commandId);
  
  @DomName('Document.queryCommandSupported')
  @DocsEditable()
  bool queryCommandSupported(String commandId) => _blink.BlinkDocument.instance.queryCommandSupported_Callback_1_(this, commandId);
  
  @DomName('Document.queryCommandValue')
  @DocsEditable()
  String queryCommandValue(String commandId) => _blink.BlinkDocument.instance.queryCommandValue_Callback_1_(this, commandId);
  
  @DomName('Document.transformDocumentToTreeView')
  @DocsEditable()
  @Experimental() // untriaged
  void transformDocumentToTreeView(String noStyleMessage) => _blink.BlinkDocument.instance.transformDocumentToTreeView_Callback_1_(this, noStyleMessage);
  
  @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.getElementById')
  @DocsEditable()
  Element getElementById(String elementId) => _blink.BlinkDocument.instance.getElementById_Callback_1_(this, elementId);
  
  @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<ClipboardEvent> get onCopy => Element.copyEvent.forTarget(this);

  /// Stream of `cut` events handled by this [Document].
  @DomName('Document.oncut')
  @DocsEditable()
  Stream<ClipboardEvent> get onCut => Element.cutEvent.forTarget(this);

  /// Stream of `doubleclick` events handled by this [Document].
  @DomName('Document.ondblclick')
  @DocsEditable()
  Stream<Event> get onDoubleClick => Element.doubleClickEvent.forTarget(this);

  /// Stream of `drag` events handled by this [Document].
  @DomName('Document.ondrag')
  @DocsEditable()
  Stream<MouseEvent> get onDrag => Element.dragEvent.forTarget(this);

  /// Stream of `dragend` events handled by this [Document].
  @DomName('Document.ondragend')
  @DocsEditable()
  Stream<MouseEvent> get onDragEnd => Element.dragEndEvent.forTarget(this);

  /// Stream of `dragenter` events handled by this [Document].
  @DomName('Document.ondragenter')
  @DocsEditable()
  Stream<MouseEvent> get onDragEnter => Element.dragEnterEvent.forTarget(this);

  /// Stream of `dragleave` events handled by this [Document].
  @DomName('Document.ondragleave')
  @DocsEditable()
  Stream<MouseEvent> get onDragLeave => Element.dragLeaveEvent.forTarget(this);

  /// Stream of `dragover` events handled by this [Document].
  @DomName('Document.ondragover')
  @DocsEditable()
  Stream<MouseEvent> get onDragOver => Element.dragOverEvent.forTarget(this);

  /// Stream of `dragstart` events handled by this [Document].
  @DomName('Document.ondragstart')
  @DocsEditable()
  Stream<MouseEvent> get onDragStart => Element.dragStartEvent.forTarget(this);

  /// Stream of `drop` events handled by this [Document].
  @DomName('Document.ondrop')
  @DocsEditable()
  Stream<MouseEvent> get onDrop => Element.dropEvent.forTarget(this);

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

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

  @DomName('Document.onended')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onEnded => Element.endedEvent.forTarget(this);

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

  /// Stream of `focus` events handled by this [Document].
  @DomName('Document.onfocus')
  @DocsEditable()
  Stream<Event> get onFocus => Element.focusEvent.forTarget(this);

  /// Stream of `input` events handled by this [Document].
  @DomName('Document.oninput')
  @DocsEditable()
  Stream<Event> get onInput => Element.inputEvent.forTarget(this);

  /// Stream of `invalid` events handled by this [Document].
  @DomName('Document.oninvalid')
  @DocsEditable()
  Stream<Event> get onInvalid => Element.invalidEvent.forTarget(this);

  /// Stream of `keydown` events handled by this [Document].
  @DomName('Document.onkeydown')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyDown => Element.keyDownEvent.forTarget(this);

  /// Stream of `keypress` events handled by this [Document].
  @DomName('Document.onkeypress')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyPress => Element.keyPressEvent.forTarget(this);

  /// Stream of `keyup` events handled by this [Document].
  @DomName('Document.onkeyup')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyUp => Element.keyUpEvent.forTarget(this);

  /// Stream of `load` events handled by this [Document].
  @DomName('Document.onload')
  @DocsEditable()
  Stream<Event> get onLoad => Element.loadEvent.forTarget(this);

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

  @DomName('Document.onloadedmetadata')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onLoadedMetadata => Element.loadedMetadataEvent.forTarget(this);

  /// Stream of `mousedown` events handled by this [Document].
  @DomName('Document.onmousedown')
  @DocsEditable()
  Stream<MouseEvent> get onMouseDown => Element.mouseDownEvent.forTarget(this);

  /// Stream of `mouseenter` events handled by this [Document].
  @DomName('Document.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseEnter => Element.mouseEnterEvent.forTarget(this);

  /// Stream of `mouseleave` events handled by this [Document].
  @DomName('Document.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseLeave => Element.mouseLeaveEvent.forTarget(this);

  /// Stream of `mousemove` events handled by this [Document].
  @DomName('Document.onmousemove')
  @DocsEditable()
  Stream<MouseEvent> get onMouseMove => Element.mouseMoveEvent.forTarget(this);

  /// Stream of `mouseout` events handled by this [Document].
  @DomName('Document.onmouseout')
  @DocsEditable()
  Stream<MouseEvent> get onMouseOut => Element.mouseOutEvent.forTarget(this);

  /// Stream of `mouseover` events handled by this [Document].
  @DomName('Document.onmouseover')
  @DocsEditable()
  Stream<MouseEvent> get onMouseOver => Element.mouseOverEvent.forTarget(this);

  /// Stream of `mouseup` events handled by this [Document].
  @DomName('Document.onmouseup')
  @DocsEditable()
  Stream<MouseEvent> get onMouseUp => Element.mouseUpEvent.forTarget(this);

  /// Stream of `mousewheel` events handled by this [Document].
  @DomName('Document.onmousewheel')
  @DocsEditable()
  Stream<WheelEvent> get onMouseWheel => Element.mouseWheelEvent.forTarget(this);

  /// Stream of `paste` events handled by this [Document].
  @DomName('Document.onpaste')
  @DocsEditable()
  Stream<ClipboardEvent> get onPaste => Element.pasteEvent.forTarget(this);

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

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

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

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

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

  @DomName('Document.onratechange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onRateChange => Element.rateChangeEvent.forTarget(this);

  /// Stream of `readystatechange` events handled by this [Document].
  @DomName('Document.onreadystatechange')
  @DocsEditable()
  Stream<Event> get onReadyStateChange => readyStateChangeEvent.forTarget(this);

  /// Stream of `reset` events handled by this [Document].
  @DomName('Document.onreset')
  @DocsEditable()
  Stream<Event> get onReset => Element.resetEvent.forTarget(this);

  @DomName('Document.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onResize => Element.resizeEvent.forTarget(this);

  /// Stream of `scroll` events handled by this [Document].
  @DomName('Document.onscroll')
  @DocsEditable()
  Stream<Event> get onScroll => Element.scrollEvent.forTarget(this);

  /// Stream of `search` events handled by this [Document].
  @DomName('Document.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  Stream<Event> get onSearch => Element.searchEvent.forTarget(this);

  /// Stream of `securitypolicyviolation` events handled by this [Document].
  @DomName('Document.onsecuritypolicyviolation')
  @DocsEditable()
  // https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#widl-Document-onsecuritypolicyviolation
  @Experimental()
  Stream<SecurityPolicyViolationEvent> get onSecurityPolicyViolation => securityPolicyViolationEvent.forTarget(this);

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

  @DomName('Document.onseeking')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSeeking => Element.seekingEvent.forTarget(this);

  /// Stream of `select` events handled by this [Document].
  @DomName('Document.onselect')
  @DocsEditable()
  Stream<Event> get onSelect => Element.selectEvent.forTarget(this);

  /// Stream of `selectionchange` events handled by this [Document].
  @DomName('Document.onselectionchange')
  @DocsEditable()
  Stream<Event> get onSelectionChange => selectionChangeEvent.forTarget(this);

  /// Stream of `selectstart` events handled by this [Document].
  @DomName('Document.onselectstart')
  @DocsEditable()
  Stream<Event> get onSelectStart => Element.selectStartEvent.forTarget(this);

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

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

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

  @DomName('Document.ontimeupdate')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onTimeUpdate => Element.timeUpdateEvent.forTarget(this);

  /// Stream of `touchcancel` events handled by this [Document].
  @DomName('Document.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchCancel => Element.touchCancelEvent.forTarget(this);

  /// Stream of `touchend` events handled by this [Document].
  @DomName('Document.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchEnd => Element.touchEndEvent.forTarget(this);

  /// Stream of `touchmove` events handled by this [Document].
  @DomName('Document.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchMove => Element.touchMoveEvent.forTarget(this);

  /// Stream of `touchstart` events handled by this [Document].
  @DomName('Document.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchStart => Element.touchStartEvent.forTarget(this);

  @DomName('Document.onvolumechange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onVolumeChange => Element.volumeChangeEvent.forTarget(this);

  @DomName('Document.onwaiting')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onWaiting => Element.waitingEvent.forTarget(this);

  /// Stream of `fullscreenchange` events handled by this [Document].
  @DomName('Document.onwebkitfullscreenchange')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  Stream<Event> get onFullscreenChange => Element.fullscreenChangeEvent.forTarget(this);

  /// Stream of `fullscreenerror` events handled by this [Document].
  @DomName('Document.onwebkitfullscreenerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  Stream<Event> get onFullscreenError => Element.fullscreenErrorEvent.forTarget(this);

  /**
   * Finds all descendant elements of this document that match the specified
   * group of selectors.
   *
   * Unless your webpage contains multiple documents, the top-level
   * [querySelectorAll]
   * method behaves the same as this method, so you should use it instead to
   * save typing a few characters.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var items = document.querySelectorAll('.itemClassName');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  ElementList<Element /*=T*/> querySelectorAll/*<T extends Element>*/(String selectors) =>
    new _FrozenElementList/*<T>*/._wrap(_querySelectorAll(selectors));

  /**
   * Alias for [querySelector]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @Experimental()
  @DomName('Document.querySelector')
  Element query(String relativeSelectors) => querySelector(relativeSelectors);

  /**
   * Alias for [querySelectorAll]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @Experimental()
  @DomName('Document.querySelectorAll')
  ElementList<Element /*=T*/> queryAll/*<T extends Element>*/(String relativeSelectors) =>
      querySelectorAll(relativeSelectors);

  /// Checks if [registerElement] is supported on the current platform.
  bool get supportsRegisterElement {
    return true;
  }

  /// *Deprecated*: use [supportsRegisterElement] instead.
  @deprecated
  bool get supportsRegister => supportsRegisterElement;

  @DomName('Document.createElement')
  Element createElement(String tagName, [String typeExtension]) {
    return (typeExtension == null) ?
      _blink.BlinkDocument.instance.createElement_Callback_1_(this, tagName) :
      _blink.BlinkDocument.instance.createElement_Callback_2_(this, tagName, typeExtension);
  }

  @DomName('Document.createElementNS')
  @DocsEditable()
  Element createElementNS(String namespaceURI, String qualifiedName, [String typeExtension]) {
    return (typeExtension == null) ?
      _blink.BlinkDocument.instance.createElementNS_Callback_2_(this, namespaceURI, qualifiedName) :
      _blink.BlinkDocument.instance.createElementNS_Callback_3_(this, namespaceURI, qualifiedName, typeExtension);    
  }


  @DomName('Document.visibilityState')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @Experimental()
  String get visibilityState => _visibilityState;
}
// 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 NonElementParentNode, ParentNode {
  factory DocumentFragment() => document.createDocumentFragment();

  factory DocumentFragment.html(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {

    return document.body.createFragment(html,
      validator: validator, treeSanitizer: treeSanitizer);
  }

  factory DocumentFragment.svg(String svgContent,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {

    return new svg.SvgSvgElement().createFragment(svgContent,
        validator: validator, treeSanitizer: treeSanitizer);
  }

  HtmlCollection get _children => throw new UnimplementedError(
      'Use _docChildren instead');

  List<Element> _docChildren;

  List<Element> get children {
    if (_docChildren == null) {
      _docChildren = new FilteredElementList(this);
    }
    return _docChildren;
  }

  set children(List<Element> value) {
    // Copy list first since we don't want liveness during iteration.
    var copy = value.toList();
    var children = this.children;
    children.clear();
    children.addAll(copy);
  }

  /**
   * Finds all descendant elements of this document fragment that match the
   * specified group of selectors.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var items = document.querySelectorAll('.itemClassName');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  ElementList<Element /*=T*/> querySelectorAll/*<T extends Element>*/(String selectors) =>
    new _FrozenElementList/*<T>*/._wrap(_querySelectorAll(selectors));


  String get innerHtml {
    final e = new Element.tag("div");
    e.append(this.clone(true));
    return e.innerHtml;
  }

  set innerHtml(String value) {
    this.setInnerHtml(value);
  }

  void setInnerHtml(String html,
    {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {

    this.nodes.clear();
    append(document.body.createFragment(
        html, validator: validator, treeSanitizer: treeSanitizer));
  }

  /**
   * Adds the specified text as a text node after the last child of this
   * document fragment.
   */
  void appendText(String text) {
    this.append(new Text(text));
  }


  /**
   * Parses the specified text as HTML and adds the resulting node after the
   * last child of this document fragment.
   */
  void appendHtml(String text, {NodeValidator validator,
      NodeTreeSanitizer, treeSanitizer}) {
    this.append(new DocumentFragment.html(text, validator: validator,
        treeSanitizer: treeSanitizer));
  }

  /** 
   * Alias for [querySelector]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @Experimental()
  @DomName('DocumentFragment.querySelector')
  Element query(String relativeSelectors) {
    return querySelector(relativeSelectors);
  }

  /** 
   * Alias for [querySelectorAll]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @Experimental()
  @DomName('DocumentFragment.querySelectorAll')
  ElementList<Element /*=T*/> queryAll/*<T extends Element>*/(String relativeSelectors) =>
    querySelectorAll(relativeSelectors);
  // To suppress missing implicit constructor warnings.
  factory DocumentFragment._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DocumentFragment.internal_() : super.internal_();


  @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 DartHtmlDomObject {
  // 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);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DomError.internal_() { }

  @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 DartHtmlDomObject {

  static const String INDEX_SIZE = 'IndexSizeError';
  static const String HIERARCHY_REQUEST = 'HierarchyRequestError';
  static const String WRONG_DOCUMENT = 'WrongDocumentError';
  static const String INVALID_CHARACTER = 'InvalidCharacterError';
  static const String NO_MODIFICATION_ALLOWED = 'NoModificationAllowedError';
  static const String NOT_FOUND = 'NotFoundError';
  static const String NOT_SUPPORTED = 'NotSupportedError';
  static const String INVALID_STATE = 'InvalidStateError';
  static const String SYNTAX = 'SyntaxError';
  static const String INVALID_MODIFICATION = 'InvalidModificationError';
  static const String NAMESPACE = 'NamespaceError';
  static const String INVALID_ACCESS = 'InvalidAccessError';
  static const String TYPE_MISMATCH = 'TypeMismatchError';
  static const String SECURITY = 'SecurityError';
  static const String NETWORK = 'NetworkError';
  static const String ABORT = 'AbortError';
  static const String URL_MISMATCH = 'URLMismatchError';
  static const String QUOTA_EXCEEDED = 'QuotaExceededError';
  static const String TIMEOUT = 'TimeoutError';
  static const String INVALID_NODE_TYPE = 'InvalidNodeTypeError';
  static const String DATA_CLONE = 'DataCloneError';

  String _name;
  String _message;

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

  @Deprecated("Internal Use Only")
  static DomException internalCreateDomException() {
    return new DomException._internalWrap();
  }

  external factory DomException._internalWrap();

  @Deprecated("Internal Use Only")
  DomException.internal_() { }

  @Deprecated("Internal Use Only")
  DomException.jsInterop(String m) {
    var name_index = m.indexOf(': ');
    if (name_index < 0) {
      _name = "";
      _message = m;
    } else {
      _name = m.substring(0, name_index);
      _message = m.substring(name_index + 1).trim();
    }
  }

  @DomName('DOMException.message')
  @DocsEditable()
  String get message => _message;

  @DomName('DOMException.name')
  @DocsEditable()
  String get name => _name;

  @DomName('DOMException.toString')
  @DocsEditable()
  String toString() => "${_name}: $_message";

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

// WARNING: Do not edit - generated code.


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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DomImplementation.internal_() { }

  @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() => _blink.BlinkDOMImplementation.instance.hasFeature_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('Iterator')
@Experimental() // untriaged
class DomIterator extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory DomIterator._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DomIterator.internal_() { }

  Object next([Object value]) {
    if (value != null) {
      return _blink.BlinkIterator.instance.next_Callback_1_(this, value);
    }
    return _blink.BlinkIterator.instance.next_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('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");
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DomMatrix.internal_() : super.internal_();


  @DomName('DOMMatrix.a')
  @DocsEditable()
  @Experimental() // untriaged
  num get a => _blink.BlinkDOMMatrix.instance.a_Getter_(this);
  
  @DomName('DOMMatrix.a')
  @DocsEditable()
  @Experimental() // untriaged
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  set m44(num value) => _blink.BlinkDOMMatrix.instance.m44_Setter_(this, value);
  
  @DomName('DOMMatrix.multiplySelf')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix multiplySelf(DomMatrix other) => _blink.BlinkDOMMatrix.instance.multiplySelf_Callback_1_(this, other);
  
  @DomName('DOMMatrix.preMultiplySelf')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix preMultiplySelf(DomMatrix other) => _blink.BlinkDOMMatrix.instance.preMultiplySelf_Callback_1_(this, other);
  
  DomMatrix scale3dSelf(num scale, [num originX, num originY, num originZ]) {
    if (originZ != null) {
      return _blink.BlinkDOMMatrix.instance.scale3dSelf_Callback_4_(this, scale, originX, originY, originZ);
    }
    if (originY != null) {
      return _blink.BlinkDOMMatrix.instance.scale3dSelf_Callback_3_(this, scale, originX, originY);
    }
    if (originX != null) {
      return _blink.BlinkDOMMatrix.instance.scale3dSelf_Callback_2_(this, scale, originX);
    }
    return _blink.BlinkDOMMatrix.instance.scale3dSelf_Callback_1_(this, scale);
  }

  DomMatrix scaleNonUniformSelf(num scaleX, [num scaleY, num scaleZ, num originX, num originY, num originZ]) {
    if (originZ != null) {
      return _blink.BlinkDOMMatrix.instance.scaleNonUniformSelf_Callback_6_(this, scaleX, scaleY, scaleZ, originX, originY, originZ);
    }
    if (originY != null) {
      return _blink.BlinkDOMMatrix.instance.scaleNonUniformSelf_Callback_5_(this, scaleX, scaleY, scaleZ, originX, originY);
    }
    if (originX != null) {
      return _blink.BlinkDOMMatrix.instance.scaleNonUniformSelf_Callback_4_(this, scaleX, scaleY, scaleZ, originX);
    }
    if (scaleZ != null) {
      return _blink.BlinkDOMMatrix.instance.scaleNonUniformSelf_Callback_3_(this, scaleX, scaleY, scaleZ);
    }
    if (scaleY != null) {
      return _blink.BlinkDOMMatrix.instance.scaleNonUniformSelf_Callback_2_(this, scaleX, scaleY);
    }
    return _blink.BlinkDOMMatrix.instance.scaleNonUniformSelf_Callback_1_(this, scaleX);
  }

  DomMatrix scaleSelf(num scale, [num originX, num originY]) {
    if (originY != null) {
      return _blink.BlinkDOMMatrix.instance.scaleSelf_Callback_3_(this, scale, originX, originY);
    }
    if (originX != null) {
      return _blink.BlinkDOMMatrix.instance.scaleSelf_Callback_2_(this, scale, originX);
    }
    return _blink.BlinkDOMMatrix.instance.scaleSelf_Callback_1_(this, scale);
  }

  DomMatrix translateSelf(num tx, num ty, [num tz]) {
    if (tz != null) {
      return _blink.BlinkDOMMatrix.instance.translateSelf_Callback_3_(this, tx, ty, tz);
    }
    return _blink.BlinkDOMMatrix.instance.translateSelf_Callback_2_(this, tx, ty);
  }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory DomMatrixReadOnly._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DomMatrixReadOnly.internal_() { }

  @DomName('DOMMatrixReadOnly.a')
  @DocsEditable()
  @Experimental() // untriaged
  num get a => _blink.BlinkDOMMatrixReadOnly.instance.a_Getter_(this);
  
  @DomName('DOMMatrixReadOnly.b')
  @DocsEditable()
  @Experimental() // untriaged
  num get b => _blink.BlinkDOMMatrixReadOnly.instance.b_Getter_(this);
  
  @DomName('DOMMatrixReadOnly.c')
  @DocsEditable()
  @Experimental() // untriaged
  num get c => _blink.BlinkDOMMatrixReadOnly.instance.c_Getter_(this);
  
  @DomName('DOMMatrixReadOnly.d')
  @DocsEditable()
  @Experimental() // untriaged
  num get d => _blink.BlinkDOMMatrixReadOnly.instance.d_Getter_(this);
  
  @DomName('DOMMatrixReadOnly.e')
  @DocsEditable()
  @Experimental() // untriaged
  num get e => _blink.BlinkDOMMatrixReadOnly.instance.e_Getter_(this);
  
  @DomName('DOMMatrixReadOnly.f')
  @DocsEditable()
  @Experimental() // untriaged
  num 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
  num get m11 => _blink.BlinkDOMMatrixReadOnly.instance.m11_Getter_(this);
  
  @DomName('DOMMatrixReadOnly.m12')
  @DocsEditable()
  @Experimental() // untriaged
  num get m12 => _blink.BlinkDOMMatrixReadOnly.instance.m12_Getter_(this);
  
  @DomName('DOMMatrixReadOnly.m13')
  @DocsEditable()
  @Experimental() // untriaged
  num get m13 => _blink.BlinkDOMMatrixReadOnly.instance.m13_Getter_(this);
  
  @DomName('DOMMatrixReadOnly.m14')
  @DocsEditable()
  @Experimental() // untriaged
  num get m14 => _blink.BlinkDOMMatrixReadOnly.instance.m14_Getter_(this);
  
  @DomName('DOMMatrixReadOnly.m21')
  @DocsEditable()
  @Experimental() // untriaged
  num get m21 => _blink.BlinkDOMMatrixReadOnly.instance.m21_Getter_(this);
  
  @DomName('DOMMatrixReadOnly.m22')
  @DocsEditable()
  @Experimental() // untriaged
  num get m22 => _blink.BlinkDOMMatrixReadOnly.instance.m22_Getter_(this);
  
  @DomName('DOMMatrixReadOnly.m23')
  @DocsEditable()
  @Experimental() // untriaged
  num get m23 => _blink.BlinkDOMMatrixReadOnly.instance.m23_Getter_(this);
  
  @DomName('DOMMatrixReadOnly.m24')
  @DocsEditable()
  @Experimental() // untriaged
  num get m24 => _blink.BlinkDOMMatrixReadOnly.instance.m24_Getter_(this);
  
  @DomName('DOMMatrixReadOnly.m31')
  @DocsEditable()
  @Experimental() // untriaged
  num get m31 => _blink.BlinkDOMMatrixReadOnly.instance.m31_Getter_(this);
  
  @DomName('DOMMatrixReadOnly.m32')
  @DocsEditable()
  @Experimental() // untriaged
  num get m32 => _blink.BlinkDOMMatrixReadOnly.instance.m32_Getter_(this);
  
  @DomName('DOMMatrixReadOnly.m33')
  @DocsEditable()
  @Experimental() // untriaged
  num get m33 => _blink.BlinkDOMMatrixReadOnly.instance.m33_Getter_(this);
  
  @DomName('DOMMatrixReadOnly.m34')
  @DocsEditable()
  @Experimental() // untriaged
  num get m34 => _blink.BlinkDOMMatrixReadOnly.instance.m34_Getter_(this);
  
  @DomName('DOMMatrixReadOnly.m41')
  @DocsEditable()
  @Experimental() // untriaged
  num get m41 => _blink.BlinkDOMMatrixReadOnly.instance.m41_Getter_(this);
  
  @DomName('DOMMatrixReadOnly.m42')
  @DocsEditable()
  @Experimental() // untriaged
  num get m42 => _blink.BlinkDOMMatrixReadOnly.instance.m42_Getter_(this);
  
  @DomName('DOMMatrixReadOnly.m43')
  @DocsEditable()
  @Experimental() // untriaged
  num get m43 => _blink.BlinkDOMMatrixReadOnly.instance.m43_Getter_(this);
  
  @DomName('DOMMatrixReadOnly.m44')
  @DocsEditable()
  @Experimental() // untriaged
  num get m44 => _blink.BlinkDOMMatrixReadOnly.instance.m44_Getter_(this);
  
  @DomName('DOMMatrixReadOnly.multiply')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix multiply(DomMatrix other) => _blink.BlinkDOMMatrixReadOnly.instance.multiply_Callback_1_(this, other);
  
  DomMatrix scale(num scale, [num originX, num originY]) {
    if (originY != null) {
      return _blink.BlinkDOMMatrixReadOnly.instance.scale_Callback_3_(this, scale, originX, originY);
    }
    if (originX != null) {
      return _blink.BlinkDOMMatrixReadOnly.instance.scale_Callback_2_(this, scale, originX);
    }
    return _blink.BlinkDOMMatrixReadOnly.instance.scale_Callback_1_(this, scale);
  }

  DomMatrix scale3d(num scale, [num originX, num originY, num originZ]) {
    if (originZ != null) {
      return _blink.BlinkDOMMatrixReadOnly.instance.scale3d_Callback_4_(this, scale, originX, originY, originZ);
    }
    if (originY != null) {
      return _blink.BlinkDOMMatrixReadOnly.instance.scale3d_Callback_3_(this, scale, originX, originY);
    }
    if (originX != null) {
      return _blink.BlinkDOMMatrixReadOnly.instance.scale3d_Callback_2_(this, scale, originX);
    }
    return _blink.BlinkDOMMatrixReadOnly.instance.scale3d_Callback_1_(this, scale);
  }

  DomMatrix scaleNonUniform(num scaleX, [num scaleY, num scaleZn, num originX, num originY, num originZ]) {
    if (originZ != null) {
      return _blink.BlinkDOMMatrixReadOnly.instance.scaleNonUniform_Callback_6_(this, scaleX, scaleY, scaleZn, originX, originY, originZ);
    }
    if (originY != null) {
      return _blink.BlinkDOMMatrixReadOnly.instance.scaleNonUniform_Callback_5_(this, scaleX, scaleY, scaleZn, originX, originY);
    }
    if (originX != null) {
      return _blink.BlinkDOMMatrixReadOnly.instance.scaleNonUniform_Callback_4_(this, scaleX, scaleY, scaleZn, originX);
    }
    if (scaleZn != null) {
      return _blink.BlinkDOMMatrixReadOnly.instance.scaleNonUniform_Callback_3_(this, scaleX, scaleY, scaleZn);
    }
    if (scaleY != null) {
      return _blink.BlinkDOMMatrixReadOnly.instance.scaleNonUniform_Callback_2_(this, scaleX, scaleY);
    }
    return _blink.BlinkDOMMatrixReadOnly.instance.scaleNonUniform_Callback_1_(this, scaleX);
  }

  @DomName('DOMMatrixReadOnly.toFloat32Array')
  @DocsEditable()
  @Experimental() // untriaged
  Float32List toFloat32Array() => _blink.BlinkDOMMatrixReadOnly.instance.toFloat32Array_Callback_0_(this);
  
  @DomName('DOMMatrixReadOnly.toFloat64Array')
  @DocsEditable()
  @Experimental() // untriaged
  Float64List toFloat64Array() => _blink.BlinkDOMMatrixReadOnly.instance.toFloat64Array_Callback_0_(this);
  
  DomMatrix translate(num tx, num ty, [num tz]) {
    if (tz != null) {
      return _blink.BlinkDOMMatrixReadOnly.instance.translate_Callback_3_(this, tx, ty, tz);
    }
    return _blink.BlinkDOMMatrixReadOnly.instance.translate_Callback_2_(this, tx, ty);
  }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 DartHtmlDomObject {
  // 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_();
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DomParser.internal_() { }

  @DomName('DOMParser.parseFromString')
  @DocsEditable()
  Document parseFromString(String str, String type) => _blink.BlinkDOMParser.instance.parseFromString_Callback_2_(this, str, type);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// 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 is Map || point_OR_x == null) && y == null && z == null && w == null) {
      var point_1 = convertDartToNative_Dictionary(point_OR_x);
      return _blink.BlinkDOMPoint.instance.constructorCallback_1_(point_1);
    }
    if (point_OR_x == null && y == null && z == null && w == null) {
      return _blink.BlinkDOMPoint.instance.constructorCallback_0_();
    }
    if ((point_OR_x is num || 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");
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DomPoint.internal_() : super.internal_();


  /// Checks if this type is supported on the current platform.
  static bool get supported => true;

  @DomName('DOMPoint.w')
  @DocsEditable()
  @Experimental() // untriaged
  num get w => _blink.BlinkDOMPoint.instance.w_Getter_(this);
  
  @DomName('DOMPoint.w')
  @DocsEditable()
  @Experimental() // untriaged
  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
  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
  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
  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 DartHtmlDomObject {
  // 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);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DomPointReadOnly.internal_() { }

  @DomName('DOMPointReadOnly.w')
  @DocsEditable()
  @Experimental() // untriaged
  num get w => _blink.BlinkDOMPointReadOnly.instance.w_Getter_(this);
  
  @DomName('DOMPointReadOnly.x')
  @DocsEditable()
  @Experimental() // untriaged
  num get x => _blink.BlinkDOMPointReadOnly.instance.x_Getter_(this);
  
  @DomName('DOMPointReadOnly.y')
  @DocsEditable()
  @Experimental() // untriaged
  num get y => _blink.BlinkDOMPointReadOnly.instance.y_Getter_(this);
  
  @DomName('DOMPointReadOnly.z')
  @DocsEditable()
  @Experimental() // untriaged
  num 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 DartHtmlDomObject 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);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DomRectReadOnly.internal_() { }

  @DomName('DOMRectReadOnly.bottom')
  @DocsEditable()
  @Experimental() // untriaged
  num get bottom => _blink.BlinkDOMRectReadOnly.instance.bottom_Getter_(this);
  
  @DomName('DOMRectReadOnly.height')
  @DocsEditable()
  @Experimental() // untriaged
  num get height => _blink.BlinkDOMRectReadOnly.instance.height_Getter_(this);
  
  @DomName('DOMRectReadOnly.left')
  @DocsEditable()
  @Experimental() // untriaged
  num get left => _blink.BlinkDOMRectReadOnly.instance.left_Getter_(this);
  
  @DomName('DOMRectReadOnly.right')
  @DocsEditable()
  @Experimental() // untriaged
  num get right => _blink.BlinkDOMRectReadOnly.instance.right_Getter_(this);
  
  @DomName('DOMRectReadOnly.top')
  @DocsEditable()
  @Experimental() // untriaged
  num get top => _blink.BlinkDOMRectReadOnly.instance.top_Getter_(this);
  
  @DomName('DOMRectReadOnly.width')
  @DocsEditable()
  @Experimental() // untriaged
  num get width => _blink.BlinkDOMRectReadOnly.instance.width_Getter_(this);
  
  @DomName('DOMRectReadOnly.x')
  @DocsEditable()
  @Experimental() // untriaged
  num get x => _blink.BlinkDOMRectReadOnly.instance.x_Getter_(this);
  
  @DomName('DOMRectReadOnly.y')
  @DocsEditable()
  @Experimental() // untriaged
  num 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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DomSettableTokenList.internal_() : super.internal_();


  @DomName('DOMSettableTokenList.value')
  @DocsEditable()
  String get value => _blink.BlinkDOMSettableTokenList.instance.value_Getter_(this);
  
  @DomName('DOMSettableTokenList.value')
  @DocsEditable()
  set value(String value) => _blink.BlinkDOMSettableTokenList.instance.value_Setter_(this, value);
  
  @DomName('DOMSettableTokenList.item')
  @DocsEditable()
  @Experimental() // untriaged
  String item(int index) => _blink.BlinkDOMSettableTokenList.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('DOMStringList')
class DomStringList extends DartHtmlDomObject with ListMixin<String>, ImmutableListMixin<String> implements List<String> {
  // To suppress missing implicit constructor warnings.
  factory DomStringList._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DomStringList.internal_() { }

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


  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.__getter__')
  @DocsEditable()
  @Experimental() // untriaged
  String __getter__(int index) => _blink.BlinkDOMStringList.instance.$__getter___Callback_1_(this, index);
  
  @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')
class DomStringMap extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory DomStringMap._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DomStringMap.internal_() { }

  void __delete__(index_OR_name) {
    if ((index_OR_name is String || index_OR_name == null)) {
      _blink.BlinkDOMStringMap.instance.$__delete___Callback_1_(this, index_OR_name);
      return;
    }
    if ((index_OR_name is int || index_OR_name == null)) {
      _blink.BlinkDOMStringMap.instance.$__delete___Callback_1_(this, index_OR_name);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('DOMStringMap.__getter__')
  @DocsEditable()
  String __getter__(int index) => _blink.BlinkDOMStringMap.instance.$__getter___Callback_1_(this, index);
  
  void __setter__(index_OR_name, String value) {
    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;
    }
    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;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('DOMStringMap.item')
  @DocsEditable()
  @Experimental() // untriaged
  String item(String name) => _blink.BlinkDOMStringMap.instance.item_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('DOMTokenList')
class DomTokenList extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory DomTokenList._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  DomTokenList.internal_() { }

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

// WARNING: Do not edit - generated code.


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


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  EffectModel.internal_() { }

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


class _ChildrenElementList extends ListBase<Element>
    implements NodeListWrapper {
  // Raw Element.
  final Element _element;
  final HtmlCollection _childElements;

  _ChildrenElementList._wrap(Element element)
    : _childElements = element._children,
      _element = element;

  bool contains(Object element) => _childElements.contains(element);


  bool get isEmpty {
    return _element._firstElementChild == null;
  }

  int get length {
    return _childElements.length;
  }

  Element operator [](int index) {
    return _childElements[index];
  }

  void operator []=(int index, Element value) {
    _element._replaceChild(value, _childElements[index]);
  }

  set length(int newLength) {
    // TODO(jacobr): remove children when length is reduced.
    throw new UnsupportedError('Cannot resize element lists');
  }

  Element add(Element value) {
    _element.append(value);
    return value;
  }

  Iterator<Element> get iterator => toList().iterator;

  void addAll(Iterable<Element> iterable) {
    if (iterable is _ChildNodeListLazy) {
      iterable = new List.from(iterable);
    }

    for (Element element in iterable) {
      _element.append(element);
    }
  }

  void sort([int compare(Element a, Element b)]) {
    throw new UnsupportedError('Cannot sort element lists');
  }

  void shuffle([Random random]) {
    throw new UnsupportedError('Cannot shuffle element lists');
  }

  void removeWhere(bool test(Element element)) {
    _filter(test, false);
  }

  void retainWhere(bool test(Element element)) {
    _filter(test, true);
  }

  void _filter(bool test(Element element), bool retainMatching) {
    var removed;
    if (retainMatching) {
      removed = _element.children.where((e) => !test(e));
    } else {
      removed = _element.children.where(test);
    }
    for (var e in removed) e.remove();
  }

  void 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;
      // We aren't preserving identity of nodes in JSINTEROP mode
      if (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<ClipboardEvent> get onCopy;

  /// Stream of `cut` events handled by this [Element].
  @DomName('Element.oncut')
  @DocsEditable()
  ElementStream<ClipboardEvent> get onCut;

  /// Stream of `doubleclick` events handled by this [Element].
  @DomName('Element.ondblclick')
  @DocsEditable()
  ElementStream<Event> get onDoubleClick;

  /**
   * A stream of `drag` events fired when this element currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.ondrag')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrag;

  /**
   * A stream of `dragend` events fired when this element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.ondragend')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnd;

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.ondragenter')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnter;

  /**
   * A stream of `dragleave` events fired when an object being dragged over this
   * element leaves this element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.ondragleave')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragLeave;

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.ondragover')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragOver;

  /**
   * A stream of `dragstart` events fired when this element starts being
   * dragged.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.ondragstart')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragStart;

  /**
   * A stream of `drop` events fired when a dragged object is dropped on this
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.ondrop')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrop;

  @DomName('Element.ondurationchange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onDurationChange;

  @DomName('Element.onemptied')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEmptied;

  @DomName('Element.onended')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEnded;

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

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

  /// Stream of `input` events handled by this [Element].
  @DomName('Element.oninput')
  @DocsEditable()
  ElementStream<Event> get onInput;

  /// Stream of `invalid` events handled by this [Element].
  @DomName('Element.oninvalid')
  @DocsEditable()
  ElementStream<Event> get onInvalid;

  /// Stream of `keydown` events handled by this [Element].
  @DomName('Element.onkeydown')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyDown;

  /// Stream of `keypress` events handled by this [Element].
  @DomName('Element.onkeypress')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyPress;

  /// Stream of `keyup` events handled by this [Element].
  @DomName('Element.onkeyup')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyUp;

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

  @DomName('Element.onloadeddata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedData;

  @DomName('Element.onloadedmetadata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedMetadata;

  /// Stream of `mousedown` events handled by this [Element].
  @DomName('Element.onmousedown')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseDown;

  /// Stream of `mouseenter` events handled by this [Element].
  @DomName('Element.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseEnter;

  /// Stream of `mouseleave` events handled by this [Element].
  @DomName('Element.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseLeave;

  /// Stream of `mousemove` events handled by this [Element].
  @DomName('Element.onmousemove')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseMove;

  /// Stream of `mouseout` events handled by this [Element].
  @DomName('Element.onmouseout')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOut;

  /// Stream of `mouseover` events handled by this [Element].
  @DomName('Element.onmouseover')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOver;

  /// Stream of `mouseup` events handled by this [Element].
  @DomName('Element.onmouseup')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseUp;

  /// Stream of `mousewheel` events handled by this [Element].
  @DomName('Element.onmousewheel')
  @DocsEditable()
  // http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents
  @Experimental() // non-standard
  ElementStream<WheelEvent> get onMouseWheel;

  /// Stream of `paste` events handled by this [Element].
  @DomName('Element.onpaste')
  @DocsEditable()
  ElementStream<ClipboardEvent> get onPaste;

  @DomName('Element.onpause')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPause;

  @DomName('Element.onplay')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPlay;

  @DomName('Element.onplaying')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPlaying;

  @DomName('Element.onratechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onRateChange;

  /// Stream of `reset` events handled by this [Element].
  @DomName('Element.onreset')
  @DocsEditable()
  ElementStream<Event> get onReset;

  @DomName('Element.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onResize;

  /// Stream of `scroll` events handled by this [Element].
  @DomName('Element.onscroll')
  @DocsEditable()
  ElementStream<Event> get onScroll;

  /// Stream of `search` events handled by this [Element].
  @DomName('Element.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  ElementStream<Event> get onSearch;

  @DomName('Element.onseeked')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeked;

  @DomName('Element.onseeking')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeking;

  /// Stream of `select` events handled by this [Element].
  @DomName('Element.onselect')
  @DocsEditable()
  ElementStream<Event> get onSelect;

  /// Stream of `selectstart` events handled by this [Element].
  @DomName('Element.onselectstart')
  @DocsEditable()
  @Experimental() // nonstandard
  ElementStream<Event> get onSelectStart;

  @DomName('Element.onstalled')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onStalled;

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

  @DomName('Element.onsuspend')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSuspend;

  @DomName('Element.ontimeupdate')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onTimeUpdate;

  /// Stream of `touchcancel` events handled by this [Element].
  @DomName('Element.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchCancel;

  /// Stream of `touchend` events handled by this [Element].
  @DomName('Element.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnd;

  /// Stream of `touchenter` events handled by this [Element].
  @DomName('Element.ontouchenter')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnter;

  /// Stream of `touchleave` events handled by this [Element].
  @DomName('Element.ontouchleave')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchLeave;

  /// Stream of `touchmove` events handled by this [Element].
  @DomName('Element.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchMove;

  /// Stream of `touchstart` events handled by this [Element].
  @DomName('Element.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchStart;

  /// Stream of `transitionend` events handled by this [Element].
  @DomName('Element.ontransitionend')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  ElementStream<TransitionEvent> get onTransitionEnd;

  @DomName('Element.onvolumechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onVolumeChange;

  @DomName('Element.onwaiting')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onWaiting;

  /// Stream of `fullscreenchange` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenchange')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenChange;

  /// Stream of `fullscreenerror` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenError;

}

// Wrapper over an immutable NodeList to make it implement ElementList.
//
// Clients are {`Document`, `DocumentFragment`}.`querySelectorAll` which are
// declared to return `ElementList`.  This provides all the static analysis
// benefit so there is no need for this class have a constrained type parameter.
//
class _FrozenElementList<E extends Element> extends ListBase<E>
    implements ElementList<E>, NodeListWrapper {
  final List<Node> _nodeList;

  var dartClass_instance;

  _FrozenElementList._wrap(this._nodeList) {
      this.dartClass_instance = this._nodeList;
  }

  int get length => _nodeList.length;

  E operator [](int index) => _downcast/*<Node, E>*/(_nodeList[index]);

  void operator []=(int index, E value) {
    throw new UnsupportedError('Cannot modify list');
  }

  set length(int newLength) {
    throw new UnsupportedError('Cannot modify list');
  }

  void sort([Comparator<E> compare]) {
    throw new UnsupportedError('Cannot sort list');
  }

  void shuffle([Random random]) {
    throw new UnsupportedError('Cannot shuffle list');
  }

  E get first => _downcast/*<Node, E>*/(_nodeList.first);

  E get last => _downcast/*<Node, E>*/(_nodeList.last);

  E get single => _downcast/*<Node, E>*/(_nodeList.single);

  CssClassSet get classes => new _MultiElementCssClassSet(this);

  CssStyleDeclarationBase get style =>
      new _CssStyleDeclarationSet(this);

  set classes(Iterable<String> value) {
    // TODO(sra): This might be faster for Sets:
    //
    //     new _MultiElementCssClassSet(this).writeClasses(value)
    //
    // as the code below converts the Iterable[value] to a string multiple
    // times.  Maybe compute the string and set className here.
    forEach((e) => e.classes = value);
  }

  CssRect get contentEdge => new _ContentCssListRect(this);

  CssRect get paddingEdge => this.first.paddingEdge;

  CssRect get borderEdge => this.first.borderEdge;

  CssRect get marginEdge => this.first.marginEdge;

  List<Node> get rawList => _nodeList;


  /// Stream of `abort` events handled by this [Element].
  @DomName('Element.onabort')
  @DocsEditable()
  ElementStream<Event> get onAbort => Element.abortEvent._forElementList(this);

  /// Stream of `beforecopy` events handled by this [Element].
  @DomName('Element.onbeforecopy')
  @DocsEditable()
  ElementStream<Event> get onBeforeCopy => Element.beforeCopyEvent._forElementList(this);

  /// Stream of `beforecut` events handled by this [Element].
  @DomName('Element.onbeforecut')
  @DocsEditable()
  ElementStream<Event> get onBeforeCut => Element.beforeCutEvent._forElementList(this);

  /// Stream of `beforepaste` events handled by this [Element].
  @DomName('Element.onbeforepaste')
  @DocsEditable()
  ElementStream<Event> get onBeforePaste => Element.beforePasteEvent._forElementList(this);

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

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

  @DomName('Element.oncanplaythrough')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onCanPlayThrough => Element.canPlayThroughEvent._forElementList(this);

  /// Stream of `change` events handled by this [Element].
  @DomName('Element.onchange')
  @DocsEditable()
  ElementStream<Event> get onChange => Element.changeEvent._forElementList(this);

  /// Stream of `click` events handled by this [Element].
  @DomName('Element.onclick')
  @DocsEditable()
  ElementStream<MouseEvent> get onClick => Element.clickEvent._forElementList(this);

  /// Stream of `contextmenu` events handled by this [Element].
  @DomName('Element.oncontextmenu')
  @DocsEditable()
  ElementStream<MouseEvent> get onContextMenu => Element.contextMenuEvent._forElementList(this);

  /// Stream of `copy` events handled by this [Element].
  @DomName('Element.oncopy')
  @DocsEditable()
  ElementStream<ClipboardEvent> get onCopy => Element.copyEvent._forElementList(this);

  /// Stream of `cut` events handled by this [Element].
  @DomName('Element.oncut')
  @DocsEditable()
  ElementStream<ClipboardEvent> get onCut => Element.cutEvent._forElementList(this);

  /// Stream of `doubleclick` events handled by this [Element].
  @DomName('Element.ondblclick')
  @DocsEditable()
  ElementStream<Event> get onDoubleClick => Element.doubleClickEvent._forElementList(this);

  /**
   * A stream of `drag` events fired when this element currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.ondrag')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrag => Element.dragEvent._forElementList(this);

  /**
   * A stream of `dragend` events fired when this element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.ondragend')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnd => Element.dragEndEvent._forElementList(this);

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.ondragenter')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnter => Element.dragEnterEvent._forElementList(this);

  /**
   * A stream of `dragleave` events fired when an object being dragged over this
   * element leaves this element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.ondragleave')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragLeave => Element.dragLeaveEvent._forElementList(this);

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.ondragover')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragOver => Element.dragOverEvent._forElementList(this);

  /**
   * A stream of `dragstart` events fired when this element starts being
   * dragged.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.ondragstart')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragStart => Element.dragStartEvent._forElementList(this);

  /**
   * A stream of `drop` events fired when a dragged object is dropped on this
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.ondrop')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrop => Element.dropEvent._forElementList(this);

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

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

  @DomName('Element.onended')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEnded => Element.endedEvent._forElementList(this);

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

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

  /// Stream of `input` events handled by this [Element].
  @DomName('Element.oninput')
  @DocsEditable()
  ElementStream<Event> get onInput => Element.inputEvent._forElementList(this);

  /// Stream of `invalid` events handled by this [Element].
  @DomName('Element.oninvalid')
  @DocsEditable()
  ElementStream<Event> get onInvalid => Element.invalidEvent._forElementList(this);

  /// Stream of `keydown` events handled by this [Element].
  @DomName('Element.onkeydown')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyDown => Element.keyDownEvent._forElementList(this);

  /// Stream of `keypress` events handled by this [Element].
  @DomName('Element.onkeypress')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyPress => Element.keyPressEvent._forElementList(this);

  /// Stream of `keyup` events handled by this [Element].
  @DomName('Element.onkeyup')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyUp => Element.keyUpEvent._forElementList(this);

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

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

  @DomName('Element.onloadedmetadata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedMetadata => Element.loadedMetadataEvent._forElementList(this);

  /// Stream of `mousedown` events handled by this [Element].
  @DomName('Element.onmousedown')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseDown => Element.mouseDownEvent._forElementList(this);

  /// Stream of `mouseenter` events handled by this [Element].
  @DomName('Element.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseEnter => Element.mouseEnterEvent._forElementList(this);

  /// Stream of `mouseleave` events handled by this [Element].
  @DomName('Element.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseLeave => Element.mouseLeaveEvent._forElementList(this);

  /// Stream of `mousemove` events handled by this [Element].
  @DomName('Element.onmousemove')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseMove => Element.mouseMoveEvent._forElementList(this);

  /// Stream of `mouseout` events handled by this [Element].
  @DomName('Element.onmouseout')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOut => Element.mouseOutEvent._forElementList(this);

  /// Stream of `mouseover` events handled by this [Element].
  @DomName('Element.onmouseover')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOver => Element.mouseOverEvent._forElementList(this);

  /// Stream of `mouseup` events handled by this [Element].
  @DomName('Element.onmouseup')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseUp => Element.mouseUpEvent._forElementList(this);

  /// Stream of `mousewheel` events handled by this [Element].
  @DomName('Element.onmousewheel')
  @DocsEditable()
  // http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents
  @Experimental() // non-standard
  ElementStream<WheelEvent> get onMouseWheel => Element.mouseWheelEvent._forElementList(this);

  /// Stream of `paste` events handled by this [Element].
  @DomName('Element.onpaste')
  @DocsEditable()
  ElementStream<ClipboardEvent> get onPaste => Element.pasteEvent._forElementList(this);

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

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

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

  @DomName('Element.onratechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onRateChange => Element.rateChangeEvent._forElementList(this);

  /// Stream of `reset` events handled by this [Element].
  @DomName('Element.onreset')
  @DocsEditable()
  ElementStream<Event> get onReset => Element.resetEvent._forElementList(this);

  @DomName('Element.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onResize => Element.resizeEvent._forElementList(this);

  /// Stream of `scroll` events handled by this [Element].
  @DomName('Element.onscroll')
  @DocsEditable()
  ElementStream<Event> get onScroll => Element.scrollEvent._forElementList(this);

  /// Stream of `search` events handled by this [Element].
  @DomName('Element.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  ElementStream<Event> get onSearch => Element.searchEvent._forElementList(this);

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

  @DomName('Element.onseeking')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeking => Element.seekingEvent._forElementList(this);

  /// Stream of `select` events handled by this [Element].
  @DomName('Element.onselect')
  @DocsEditable()
  ElementStream<Event> get onSelect => Element.selectEvent._forElementList(this);

  /// Stream of `selectstart` events handled by this [Element].
  @DomName('Element.onselectstart')
  @DocsEditable()
  @Experimental() // nonstandard
  ElementStream<Event> get onSelectStart => Element.selectStartEvent._forElementList(this);

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

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

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

  @DomName('Element.ontimeupdate')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onTimeUpdate => Element.timeUpdateEvent._forElementList(this);

  /// Stream of `touchcancel` events handled by this [Element].
  @DomName('Element.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchCancel => Element.touchCancelEvent._forElementList(this);

  /// Stream of `touchend` events handled by this [Element].
  @DomName('Element.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnd => Element.touchEndEvent._forElementList(this);

  /// Stream of `touchenter` events handled by this [Element].
  @DomName('Element.ontouchenter')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnter => Element.touchEnterEvent._forElementList(this);

  /// Stream of `touchleave` events handled by this [Element].
  @DomName('Element.ontouchleave')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchLeave => Element.touchLeaveEvent._forElementList(this);

  /// Stream of `touchmove` events handled by this [Element].
  @DomName('Element.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchMove => Element.touchMoveEvent._forElementList(this);

  /// Stream of `touchstart` events handled by this [Element].
  @DomName('Element.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchStart => Element.touchStartEvent._forElementList(this);

  /// Stream of `transitionend` events handled by this [Element].
  @DomName('Element.ontransitionend')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  ElementStream<TransitionEvent> get onTransitionEnd => Element.transitionEndEvent._forElementList(this);

  @DomName('Element.onvolumechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onVolumeChange => Element.volumeChangeEvent._forElementList(this);

  @DomName('Element.onwaiting')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onWaiting => Element.waitingEvent._forElementList(this);

  /// Stream of `fullscreenchange` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenchange')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenChange => Element.fullscreenChangeEvent._forElementList(this);

  /// Stream of `fullscreenerror` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenError => Element.fullscreenErrorEvent._forElementList(this);

}

@DocsEditable()
/**
 * An abstract class, which all HTML elements extend.
 */
@DomName('Element')
class Element extends Node implements NonDocumentTypeChildNode, GlobalEventHandlers, ParentNode, ChildNode {

  /**
   * Creates an HTML element from a valid fragment of HTML.
   *
   *     var element = new Element.html('<div class="foo">content</div>');
   *
   * The HTML fragment should contain only one single root element, any
   * leading or trailing text nodes will be removed.
   *
   * The HTML fragment is parsed as if it occurred within the context of a
   * `<body>` tag, this means that special elements such as `<caption>` which
   * must be parsed within the scope of a `<table>` element will be dropped. Use
   * [createFragment] to parse contextual HTML fragments.
   *
   * Unless a validator is provided this will perform the default validation
   * and remove all scriptable elements and attributes.
   *
   * See also:
   *
   * * [NodeValidator]
   *
   */
  factory Element.html(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    var fragment = document.body.createFragment(html, validator: validator,
        treeSanitizer: treeSanitizer);

    return fragment.nodes.where((e) => e is Element).single;
  }

  /**
   * Custom element creation constructor.
   *
   * This constructor is used by the DOM when a custom element has been
   * created. It can only be invoked by subclasses of Element from
   * that classes created constructor.
   *
   *     class CustomElement extends Element {
   *       factory CustomElement() => new Element.tag('x-custom');
   *
   *       CustomElement.created() : super.created() {
   *          // Perform any element initialization.
   *       }
   *     }
   *     document.registerElement('x-custom', CustomElement);
   */
  Element.created() : super._created() {
    // Validate that this is a custom element & possibly perform additional
    // initialization.
    _blink.Blink_Utils.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);

  set attributes(Map<String, String> value) {
    Map<String, String> attributes = this.attributes;
    attributes.clear();
    for (String key in value.keys) {
      attributes[key] = value[key];
    }
  }

  /**
   * List of the direct children of this element.
   *
   * This collection can be used to add and remove elements from the document.
   *
   *     var item = new DivElement();
   *     item.text = 'Something';
   *     document.body.children.add(item) // Item is now displayed on the page.
   *     for (var element in document.body.children) {
   *       element.style.background = 'red'; // Turns every child of body red.
   *     }
   */
  List<Element> get children => new _ChildrenElementList._wrap(this);

  set children(List<Element> value) {
    // Copy list first since we don't want liveness during iteration.
    var copy = value.toList();
    var children = this.children;
    children.clear();
    children.addAll(copy);
  }

  /**
   * Finds all descendent elements of this element that match the specified
   * group of selectors.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var items = element.querySelectorAll('.itemClassName');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  @DomName('Element.querySelectorAll')
  ElementList<Element /*=T*/> querySelectorAll/*<T extends Element>*/(String selectors) =>
    new _FrozenElementList/*<T>*/._wrap(_querySelectorAll(selectors));

  /**
   * Alias for [querySelector]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @DomName('Element.querySelector')
  @Experimental()
  Element query(String relativeSelectors) => querySelector(relativeSelectors);

  /**
   * Alias for [querySelectorAll]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @DomName('Element.querySelectorAll')
  @Experimental()
  ElementList<Element /*=T*/> queryAll/*<T extends Element>*/(String relativeSelectors) =>
      querySelectorAll(relativeSelectors);

  /**
   * The set of CSS classes applied to this element.
   *
   * This set makes it easy to add, remove or toggle the classes applied to
   * this element.
   *
   *     element.classes.add('selected');
   *     element.classes.toggle('isOnline');
   *     element.classes.remove('selected');
   */
  CssClassSet get classes => new _ElementCssClassSet(this);

  set classes(Iterable<String> value) {
    // TODO(sra): Do this without reading the classes in clear() and addAll(),
    // or writing the classes in clear().
    CssClassSet classSet = classes;
    classSet.clear();
    classSet.addAll(value);
  }

  /**
   * Allows access to all custom data attributes (data-*) set on this element.
   *
   * The keys for the map must follow these rules:
   *
   * * The name must not begin with 'xml'.
   * * The name cannot contain a semi-colon (';').
   * * The name cannot contain any capital letters.
   *
   * Any keys from markup will be converted to camel-cased keys in the map.
   *
   * For example, HTML specified as:
   *
   *     <div data-my-random-value='value'></div>
   *
   * Would be accessed in Dart as:
   *
   *     var value = element.dataset['myRandomValue'];
   *
   * See also:
   *
   * * [Custom data
   *   attributes](http://dev.w3.org/html5/spec-preview/global-attributes.html#custom-data-attribute)
   */
  Map<String, String> get dataset =>
    new _DataAttributeMap(attributes);

  set dataset(Map<String, String> value) {
    final data = this.dataset;
    data.clear();
    for (String key in value.keys) {
      data[key] = value[key];
    }
  }

  /**
   * Gets a map for manipulating the attributes of a particular namespace.
   *
   * This is primarily useful for SVG attributes such as xref:link.
   */
  Map<String, String> getNamespacedAttributes(String namespace) {
    return new _NamespacedAttributeMap(this, namespace);
  }

  /**
   * The set of all CSS values applied to this element, including inherited
   * and default values.
   *
   * The computedStyle contains values that are inherited from other
   * sources, such as parent elements or stylesheets. This differs from the
   * [style] property, which contains only the values specified directly on this
   * element.
   *
   * PseudoElement can be values such as `::after`, `::before`, `::marker`,
   * `::line-marker`.
   *
   * See also:
   *
   * * [CSS Inheritance and Cascade](http://docs.webplatform.org/wiki/tutorials/inheritance_and_cascade)
   * * [Pseudo-elements](http://docs.webplatform.org/wiki/css/selectors/pseudo-elements)
   */
  CssStyleDeclaration getComputedStyle([String pseudoElement]) {
    if (pseudoElement == null) {
      pseudoElement = '';
    }
    // TODO(jacobr): last param should be null, see b/5045788
    return window._getComputedStyle(this, pseudoElement);
  }

  /**
   * Gets the position of this element relative to the client area of the page.
   */
  Rectangle get client => new Rectangle(clientLeft, clientTop, clientWidth,
      clientHeight);

  /**
   * Gets the offset of this element relative to its offsetParent.
   */
  Rectangle get offset => new Rectangle(offsetLeft, offsetTop, offsetWidth,
      offsetHeight);

  /**
   * Adds the specified text after the last child of this element.
   */
  void appendText(String text) {
    this.append(new Text(text));
  }

  /**
   * Parses the specified text as HTML and adds the resulting node after the
   * last child of this element.
   */
  void appendHtml(String text, {NodeValidator validator,
      NodeTreeSanitizer treeSanitizer}) {
    this.insertAdjacentHtml('beforeend', text, validator: validator,
        treeSanitizer: treeSanitizer);
  }

  /**
   * Checks to see if the tag name is supported by the current platform.
   *
   * The tag should be a valid HTML tag name.
   */
  static bool isTagSupported(String tag) {
    var e = _ElementFactoryProvider.createElement_tag(tag, null);
    return e is Element && !(e is UnknownElement);
  }

  /**
   * Called by the DOM when this element has been inserted into the live
   * document.
   *
   * More information can be found in the
   * [Custom Elements](http://w3c.github.io/webcomponents/spec/custom/#dfn-attached-callback)
   * draft specification.
   */
  @Experimental()
  void attached() {
    // For the deprecation period, call the old callback.
    enteredView();
  }

  /**
   * Called by the DOM when this element has been removed from the live
   * document.
   *
   * More information can be found in the
   * [Custom Elements](http://w3c.github.io/webcomponents/spec/custom/#dfn-detached-callback)
   * draft specification.
   */
  @Experimental()
  void detached() {
    // For the deprecation period, call the old callback.
    leftView();
  }

  /** *Deprecated*: override [attached] instead. */
  @Experimental()
  @deprecated
  void enteredView() {}

  /** *Deprecated*: override [detached] instead. */
  @Experimental()
  @deprecated
  void leftView() {}

  /**
   * Creates a new AnimationEffect object whose target element is the object
   * on which the method is called, and calls the play() method of the
   * AnimationTimeline object of the document timeline of the node document
   * of the element, passing the newly created AnimationEffect as the argument
   * to the method. Returns an Animation for the effect.
   *
   * Examples
   *
   *     var animation = elem.animate([{"opacity": 75}, {"opacity": 0}], 200);
   *
   *     var animation = elem.animate([
   *       {"transform": "translate(100px, -100%)"},
   *       {"transform" : "translate(400px, 500px)"}
   *     ], 1500);
   *
   * The [frames] parameter is an Iterable<Map>, where the
   * map entries specify CSS animation effects. The
   * [timing] paramter can be a double, representing the number of milliseconds
   * for the transition, or a Map with fields corresponding to those
   * of the [Timing] object.
  **/
  @Experimental()
  @SupportedBrowser(SupportedBrowser.CHROME, '36')
  Animation animate(Iterable<Map<String, dynamic>> frames, [timing]) {
    if (frames is! Iterable || !(frames.every((x) => x is Map))) {
      throw new ArgumentError("The frames parameter should be a List of Maps "
          "with frame information");
    }
    var convertedFrames;
    if (frames is Iterable) {
      convertedFrames = convertDartToNative_List(
          frames.map(convertDartToNative_Dictionary).toList());
    } else {
      convertedFrames = frames;
    }
    var convertedTiming = timing is Map ? convertDartToNative_Dictionary(timing) : timing;
    return convertedTiming == null
      ? _animate(convertedFrames)
      : _animate(convertedFrames, convertedTiming);
  }

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

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


  /**
   * Parses text as an HTML fragment and inserts it into the DOM at the
   * specified location.
   *
   * The [where] parameter indicates where to insert the HTML fragment:
   *
   * * 'beforeBegin': Immediately before this element.
   * * 'afterBegin': As the first child of this element.
   * * 'beforeEnd': As the last child of this element.
   * * 'afterEnd': Immediately after this element.
   *
   *     var html = '<div class="something">content</div>';
   *     // Inserts as the first child
   *     document.body.insertAdjacentHtml('afterBegin', html);
   *     var createdElement = document.body.children[0];
   *     print(createdElement.classes[0]); // Prints 'something'
   *
   * See also:
   *
   * * [insertAdjacentText]
   * * [insertAdjacentElement]
   */
  void insertAdjacentHtml(String where, String html, {NodeValidator validator,
      NodeTreeSanitizer treeSanitizer}) {
      if (treeSanitizer is _TrustedHtmlTreeSanitizer) {
        _insertAdjacentHtml(where, html);
      } else {
        _insertAdjacentNode(where, createFragment(html,
            validator: validator, treeSanitizer: treeSanitizer));
      }
  }


  void _insertAdjacentNode(String where, Node node) {
    switch (where.toLowerCase()) {
      case 'beforebegin':
        this.parentNode.insertBefore(node, this);
        break;
      case 'afterbegin':
        var first = this.nodes.length > 0 ? this.nodes[0] : null;
        this.insertBefore(node, first);
        break;
      case 'beforeend':
        this.append(node);
        break;
      case 'afterend':
        this.parentNode.insertBefore(node, this.nextNode);
        break;
      default:
        throw new ArgumentError("Invalid position ${where}");
    }
  }


  /** Checks if this element 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 sameAsParent = current == parent;
    bool foundAsParent = sameAsParent || parent.tagName == 'HTML';
    if (current == null || sameAsParent) {
      if (foundAsParent) return new Point(0, 0);
      throw new ArgumentError("Specified element is not a transitive offset "
          "parent of this element.");
    }
    Element parentOffset = current.offsetParent;
    Point p = Element._offsetToHelper(parentOffset, parent);
    return new Point(p.x + current.offsetLeft, p.y + current.offsetTop);
  }

  static HtmlDocument _parseDocument;
  static Range _parseRange;
  static NodeValidatorBuilder _defaultValidator;
  static _ValidatingTreeSanitizer _defaultSanitizer;

  /**
   * Create a DocumentFragment from the HTML fragment and ensure that it follows
   * the sanitization rules specified by the validator or treeSanitizer.
   *
   * If the default validation behavior is too restrictive then a new
   * NodeValidator should be created, either extending or wrapping a default
   * validator and overriding the validation APIs.
   *
   * The treeSanitizer is used to walk the generated node tree and sanitize it.
   * A custom treeSanitizer can also be provided to perform special validation
   * rules but since the API is more complex to implement this is discouraged.
   *
   * The returned tree is guaranteed to only contain nodes and attributes which
   * are allowed by the provided validator.
   *
   * See also:
   *
   * * [NodeValidator]
   * * [NodeTreeSanitizer]
   */
  DocumentFragment createFragment(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    if (treeSanitizer == null) {
      if (validator == null) {
        if (_defaultValidator == null) {
          _defaultValidator = new NodeValidatorBuilder.common();
        }
        validator = _defaultValidator;
      }
      if (_defaultSanitizer == null) {
        _defaultSanitizer = new _ValidatingTreeSanitizer(validator);
      } else {
        _defaultSanitizer.validator = validator;
      }
      treeSanitizer = _defaultSanitizer;
    } else if (validator != null) {
      throw new ArgumentError(
          'validator can only be passed if treeSanitizer is null');
    }

    if (_parseDocument == null) {
      _parseDocument = document.implementation.createHtmlDocument('');
      _parseRange = _parseDocument.createRange();

      // Workaround for Safari bug. Was also previously Chrome bug 229142
      // - URIs are not resolved in new doc.
      BaseElement base = _parseDocument.createElement('base');
      base.href = document.baseUri;
      _parseDocument.head.append(base);
    }
    var contextElement;
    if (this is BodyElement) {
      contextElement = _parseDocument.body;
    } else {
      contextElement = _parseDocument.createElement(tagName);
      _parseDocument.body.append(contextElement);
    }
    var fragment;
    if (Range.supportsCreateContextualFragment &&
        _canBeUsedToCreateContextualFragment) {
      _parseRange.selectNodeContents(contextElement);
      fragment = _parseRange.createContextualFragment(html);
    } else {
      contextElement._innerHtml = html;

      fragment = _parseDocument.createDocumentFragment();
      while (contextElement.firstChild != null) {
        fragment.append(contextElement.firstChild);
      }
    }
    if (contextElement != _parseDocument.body) {
      contextElement.remove();
    }

    treeSanitizer.sanitizeTree(fragment);
    // Copy the fragment over to the main document (fix for 14184)
    document.adoptNode(fragment);

    return fragment;
  }

  /** Test if createContextualFragment is supported for this element type */
  bool get _canBeUsedToCreateContextualFragment =>
      !_cannotBeUsedToCreateContextualFragment;

  /** Test if createContextualFragment is NOT supported for this element type */
  bool get _cannotBeUsedToCreateContextualFragment =>
      _tagsForWhichCreateContextualFragmentIsNotSupported.contains(tagName);

  /**
   * A hard-coded list of the tag names for which createContextualFragment
   * isn't supported.
   */
  static const _tagsForWhichCreateContextualFragmentIsNotSupported =
      const ['HEAD', 'AREA',
      'BASE', 'BASEFONT', 'BR', 'COL', 'COLGROUP', 'EMBED', 'FRAME', 'FRAMESET',
      'HR', 'IMAGE', 'IMG', 'INPUT', 'ISINDEX', 'LINK', 'META', 'PARAM',
      'SOURCE', 'STYLE', 'TITLE', 'WBR'];

  /**
   * Parses the HTML fragment and sets it as the contents of this element.
   *
   * This uses the default sanitization behavior to sanitize the HTML fragment,
   * use [setInnerHtml] to override the default behavior.
   */
  set innerHtml(String html) {
    this.setInnerHtml(html);
  }

  /**
   * Parses the HTML fragment and sets it as the contents of this element.
   * This ensures that the generated content follows the sanitization rules
   * specified by the validator or treeSanitizer.
   *
   * If the default validation behavior is too restrictive then a new
   * NodeValidator should be created, either extending or wrapping a default
   * validator and overriding the validation APIs.
   *
   * The treeSanitizer is used to walk the generated node tree and sanitize it.
   * A custom treeSanitizer can also be provided to perform special validation
   * rules but since the API is more complex to implement this is discouraged.
   *
   * The resulting tree is guaranteed to only contain nodes and attributes which
   * are allowed by the provided validator.
   *
   * See also:
   *
   * * [NodeValidator]
   * * [NodeTreeSanitizer]
   */
  void setInnerHtml(String html,
    {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    text = null;
    if (treeSanitizer is _TrustedHtmlTreeSanitizer) {
      _innerHtml = html;
    } else {
      append(createFragment(
          html, validator: validator, treeSanitizer: treeSanitizer));
    }
  }
  String get innerHtml => _innerHtml;

  /**
   * This is an ease-of-use accessor for event streams which should only be
   * used when an explicit accessor is not available.
   */
  ElementEvents get on => new ElementEvents(this);

  /**
   * Verify if any of the attributes that we use in the sanitizer look unexpected,
   * possibly indicating DOM clobbering attacks.
   *
   * Those attributes are: attributes, lastChild, children, previousNode and tagName.
   */

  static var _namedNodeMap = js.context["NamedNodeMap"];
  static var _htmlCollection = js.context["HTMLCollection"];
  static var _nodeList = js.context["NodeList"];

  static const _evilAttributeNames =
      const ['attributes', 'lastChild', 'children', 'childNodes'];

  static bool _hasCorruptedAttributes(Element element) {
    // We have trusted access to children and to attributes of objects,
    // so we can inspect directly for attempts at DOM clobbering.
    var child = element.firstChild;
    while( child != null)  {
      if (child is Element) {
      for (var attributeName in ["id", "name"]) {
        var childAttribute = child.getAttribute(attributeName);
        if (_evilAttributeNames.contains(childAttribute)) return true;
      }}
      child = child.nextNode;
    }
    return false;
  }

  /// A secondary check for corruption, needed on IE
  static bool _hasCorruptedAttributesAdditionalCheck(Element element) => false;

  static String _safeTagName(element) {
    try {
      // Safe as we plumb directly to a C++ native method.
      return element.tagName;
    } catch (e) {}
    return 'element tag unavailable';
  }

  // Need to explicitly delegate because Element is no longer abstract for Dartium.
  bool get isContentEditable => _blink.BlinkHTMLElement.instance.isContentEditable_Getter_(this);
  void click() => _blink.BlinkHTMLElement.instance.click_Callback_0_(this);

  @DomName('Element.offsetParent')
  @DocsEditable()
  Element get offsetParent => _blink.BlinkElement.instance.offsetParent_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.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.scrollHeight')
  @DocsEditable()
  int get scrollHeight => _blink.BlinkElement.instance.scrollHeight_Getter_(this).round();

  @DomName('Element.scrollLeft')
  @DocsEditable()
  int get scrollLeft => _blink.BlinkElement.instance.scrollLeft_Getter_(this).round();

  @DomName('Element.scrollLeft')
  @DocsEditable()
  set scrollLeft(int value) => _blink.BlinkElement.instance.scrollLeft_Setter_(this, value.round());

  @DomName('Element.scrollTop')
  @DocsEditable()
  int get scrollTop => _blink.BlinkElement.instance.scrollTop_Getter_(this).round();

  @DomName('Element.scrollTop')
  @DocsEditable()
  set scrollTop(int value) => _blink.BlinkElement.instance.scrollTop_Setter_(this, value.round());

  @DomName('Element.scrollWidth')
  @DocsEditable()
  int get scrollWidth => _blink.BlinkElement.instance.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<ClipboardEvent> copyEvent = const EventStreamProvider<ClipboardEvent>('copy');

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

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

  /**
   * A stream of `drag` events fired when an element is currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.dragEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragEvent = const EventStreamProvider<MouseEvent>('drag');

  /**
   * A stream of `dragend` events fired when an element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.dragendEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragEndEvent = const EventStreamProvider<MouseEvent>('dragend');

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over an element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.dragenterEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragEnterEvent = const EventStreamProvider<MouseEvent>('dragenter');

  /**
   * A stream of `dragleave` events fired when an object being dragged over an
   * element leaves the element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.dragleaveEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragLeaveEvent = const EventStreamProvider<MouseEvent>('dragleave');

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over an element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.dragoverEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragOverEvent = const EventStreamProvider<MouseEvent>('dragover');

  /**
   * A stream of `dragstart` events for a dragged element whose drag has begun.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.dragstartEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragStartEvent = const EventStreamProvider<MouseEvent>('dragstart');

  /**
   * A stream of `drop` events fired when a dragged object is dropped on an
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.dropEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dropEvent = const EventStreamProvider<MouseEvent>('drop');

  @DomName('Element.durationchangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> durationChangeEvent = const EventStreamProvider<Event>('durationchange');

  @DomName('Element.emptiedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> emptiedEvent = const EventStreamProvider<Event>('emptied');

  @DomName('Element.endedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');

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

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

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

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

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

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

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

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

  @DomName('Element.loadeddataEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadedDataEvent = const EventStreamProvider<Event>('loadeddata');

  @DomName('Element.loadedmetadataEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadedMetadataEvent = const EventStreamProvider<Event>('loadedmetadata');

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

  /**
   * Static factory designed to expose `mouseenter` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mouseenterEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseEnterEvent = const EventStreamProvider<MouseEvent>('mouseenter');

  /**
   * Static factory designed to expose `mouseleave` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mouseleaveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseLeaveEvent = const EventStreamProvider<MouseEvent>('mouseleave');

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

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

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

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

  @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<ClipboardEvent> pasteEvent = const EventStreamProvider<ClipboardEvent>('paste');

  @DomName('Element.pauseEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> pauseEvent = const EventStreamProvider<Event>('pause');

  @DomName('Element.playEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> playEvent = const EventStreamProvider<Event>('play');

  @DomName('Element.playingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> playingEvent = const EventStreamProvider<Event>('playing');

  @DomName('Element.ratechangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> rateChangeEvent = const EventStreamProvider<Event>('ratechange');

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

  @DomName('Element.resizeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> resizeEvent = const EventStreamProvider<Event>('resize');

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

  /**
   * Static factory designed to expose `search` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.searchEvent')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  static const EventStreamProvider<Event> searchEvent = const EventStreamProvider<Event>('search');

  @DomName('Element.seekedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> seekedEvent = const EventStreamProvider<Event>('seeked');

  @DomName('Element.seekingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> seekingEvent = const EventStreamProvider<Event>('seeking');

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

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

  @DomName('Element.stalledEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> stalledEvent = const EventStreamProvider<Event>('stalled');

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

  @DomName('Element.suspendEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> suspendEvent = const EventStreamProvider<Event>('suspend');

  @DomName('Element.timeupdateEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> timeUpdateEvent = const EventStreamProvider<Event>('timeupdate');

  /**
   * Static factory designed to expose `touchcancel` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchcancelEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchCancelEvent = const EventStreamProvider<TouchEvent>('touchcancel');

  /**
   * Static factory designed to expose `touchend` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchendEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchEndEvent = const EventStreamProvider<TouchEvent>('touchend');

  /**
   * Static factory designed to expose `touchenter` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchenterEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchEnterEvent = const EventStreamProvider<TouchEvent>('touchenter');

  /**
   * Static factory designed to expose `touchleave` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchleaveEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchLeaveEvent = const EventStreamProvider<TouchEvent>('touchleave');

  /**
   * Static factory designed to expose `touchmove` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchmoveEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchMoveEvent = const EventStreamProvider<TouchEvent>('touchmove');

  /**
   * Static factory designed to expose `touchstart` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchstartEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchStartEvent = const EventStreamProvider<TouchEvent>('touchstart');

  @DomName('Element.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');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Element.internal_() : super.internal_();


  String contentEditable;

  MenuElement contextMenu;

  String dir;

  bool draggable;

  bool hidden;

  String lang;

  bool spellcheck;

  CssStyleDeclaration get style;

  int tabIndex;

  String title;

  bool translate;

  String dropzone;

  void blur();

  void focus();

  @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()
  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.computedName')
  @DocsEditable()
  @Experimental() // untriaged
  String get computedName => _blink.BlinkElement.instance.computedName_Getter_(this);
  
  @DomName('Element.computedRole')
  @DocsEditable()
  @Experimental() // untriaged
  String get computedRole => _blink.BlinkElement.instance.computedRole_Getter_(this);
  
  @DomName('Element.id')
  @DocsEditable()
  String get id => _blink.BlinkElement.instance.id_Getter_(this);
  
  @DomName('Element.id')
  @DocsEditable()
  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()
  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.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()
  num get _scrollLeft => _blink.BlinkElement.instance.scrollLeft_Getter_(this);
  
  @DomName('Element.scrollLeft')
  @DocsEditable()
  set _scrollLeft(num value) => _blink.BlinkElement.instance.scrollLeft_Setter_(this, value);
  
  @DomName('Element.scrollTop')
  @DocsEditable()
  num get _scrollTop => _blink.BlinkElement.instance.scrollTop_Getter_(this);
  
  @DomName('Element.scrollTop')
  @DocsEditable()
  set _scrollTop(num 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.tagName')
  @DocsEditable()
  String get tagName => _blink.BlinkElement.instance.tagName_Getter_(this);
  
  Animation _animate(Object effect, [timing]) {
    if (effect != null && timing == null) {
      return _blink.BlinkElement.instance.animate_Callback_1_(this, effect);
    }
    if ((timing is num) && effect != null) {
      return _blink.BlinkElement.instance.animate_Callback_2_(this, effect, timing);
    }
    if (timing != null && effect != null) {
      return _blink.BlinkElement.instance.animate_Callback_2_(this, effect, timing);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('Element.closest')
  @DocsEditable()
  @Experimental() // untriaged
  Element closest(String selectors) => _blink.BlinkElement.instance.closest_Callback_1_(this, selectors);
  
  ShadowRoot createShadowRoot([Map shadowRootInitDict]) {
    if (shadowRootInitDict == null) {
      return _blink.BlinkElement.instance.createShadowRoot_Callback_0_(this);
    }
    if ((shadowRootInitDict is Map)) {
      return _blink.BlinkElement.instance.createShadowRoot_Callback_1_(this, convertDartToNative_Dictionary(shadowRootInitDict));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('Element.getAnimations')
  @DocsEditable()
  @Experimental() // untriaged
  List<Animation> getAnimations() => (_blink.BlinkElement.instance.getAnimations_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() => make_dart_rectangle(_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 localName) => (_blink.BlinkElement.instance.getElementsByTagName_Callback_1_(this, localName));
  
  @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 position, String text) => _blink.BlinkElement.instance.insertAdjacentHTML_Callback_2_(this, position, text);
  
  @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 scroll([options_OR_x, num y]) {
    if (options_OR_x == null && y == null) {
      _blink.BlinkElement.instance.scroll_Callback_0_(this);
      return;
    }
    if ((options_OR_x is Map) && y == null) {
      _blink.BlinkElement.instance.scroll_Callback_1_(this, options_OR_x);
      return;
    }
    if ((y is num) && (options_OR_x is num)) {
      _blink.BlinkElement.instance.scroll_Callback_2_(this, options_OR_x, y);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  void scrollBy([options_OR_x, num y]) {
    if (options_OR_x == null && y == null) {
      _blink.BlinkElement.instance.scrollBy_Callback_0_(this);
      return;
    }
    if ((options_OR_x is Map) && y == null) {
      _blink.BlinkElement.instance.scrollBy_Callback_1_(this, options_OR_x);
      return;
    }
    if ((y is num) && (options_OR_x is num)) {
      _blink.BlinkElement.instance.scrollBy_Callback_2_(this, options_OR_x, y);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

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

  void scrollTo([options_OR_x, num y]) {
    if (options_OR_x == null && y == null) {
      _blink.BlinkElement.instance.scrollTo_Callback_0_(this);
      return;
    }
    if ((options_OR_x is Map) && y == null) {
      _blink.BlinkElement.instance.scrollTo_Callback_1_(this, options_OR_x);
      return;
    }
    if ((y is num) && (options_OR_x is num)) {
      _blink.BlinkElement.instance.scrollTo_Callback_2_(this, options_OR_x, y);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @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 name, String value) => _blink.BlinkElement.instance.setAttributeNS_Callback_3_(this, namespaceURI, name, value);
  
  @DomName('Element.after')
  @DocsEditable()
  @Experimental() // untriaged
  void after(Object nodes) => _blink.BlinkElement.instance.after_Callback_1_(this, nodes);
  
  @DomName('Element.before')
  @DocsEditable()
  @Experimental() // untriaged
  void before(Object nodes) => _blink.BlinkElement.instance.before_Callback_1_(this, nodes);
  
  @DomName('Element.remove')
  @DocsEditable()
  void remove() => _blink.BlinkElement.instance.remove_Callback_0_(this);
  
  @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.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<ClipboardEvent> get onCopy => copyEvent.forElement(this);

  /// Stream of `cut` events handled by this [Element].
  @DomName('Element.oncut')
  @DocsEditable()
  ElementStream<ClipboardEvent> get onCut => cutEvent.forElement(this);

  /// Stream of `doubleclick` events handled by this [Element].
  @DomName('Element.ondblclick')
  @DocsEditable()
  ElementStream<Event> get onDoubleClick => doubleClickEvent.forElement(this);

  /**
   * A stream of `drag` events fired when this element currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.ondrag')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrag => dragEvent.forElement(this);

  /**
   * A stream of `dragend` events fired when this element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.ondragend')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnd => dragEndEvent.forElement(this);

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.ondragenter')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnter => dragEnterEvent.forElement(this);

  /**
   * A stream of `dragleave` events fired when an object being dragged over this
   * element leaves this element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.ondragleave')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragLeave => dragLeaveEvent.forElement(this);

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.ondragover')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragOver => dragOverEvent.forElement(this);

  /**
   * A stream of `dragstart` events fired when this element starts being
   * dragged.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.ondragstart')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragStart => dragStartEvent.forElement(this);

  /**
   * A stream of `drop` events fired when a dragged object is dropped on this
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop
   *   sample](https://github.com/dart-lang/dart-samples/tree/master/html5/web/dnd/basics)
   *   based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   *   from HTML5Rocks.
   * * [Drag and drop
   *   specification](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
   *   from WHATWG.
   */
  @DomName('Element.ondrop')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrop => dropEvent.forElement(this);

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

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

  @DomName('Element.onended')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEnded => endedEvent.forElement(this);

  /// Stream of `error` events handled by this [Element].
  @DomName('Element.onerror')
  @DocsEditable()
  ElementStream<Event> get onError => errorEvent.forElement(this);

  /// Stream of `focus` events handled by this [Element].
  @DomName('Element.onfocus')
  @DocsEditable()
  ElementStream<Event> get onFocus => focusEvent.forElement(this);

  /// Stream of `input` events handled by this [Element].
  @DomName('Element.oninput')
  @DocsEditable()
  ElementStream<Event> get onInput => inputEvent.forElement(this);

  /// Stream of `invalid` events handled by this [Element].
  @DomName('Element.oninvalid')
  @DocsEditable()
  ElementStream<Event> get onInvalid => invalidEvent.forElement(this);

  /// Stream of `keydown` events handled by this [Element].
  @DomName('Element.onkeydown')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyDown => keyDownEvent.forElement(this);

  /// Stream of `keypress` events handled by this [Element].
  @DomName('Element.onkeypress')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyPress => keyPressEvent.forElement(this);

  /// Stream of `keyup` events handled by this [Element].
  @DomName('Element.onkeyup')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyUp => keyUpEvent.forElement(this);

  /// Stream of `load` events handled by this [Element].
  @DomName('Element.onload')
  @DocsEditable()
  ElementStream<Event> get onLoad => loadEvent.forElement(this);

  @DomName('Element.onloadeddata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedData => loadedDataEvent.forElement(this);

  @DomName('Element.onloadedmetadata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedMetadata => loadedMetadataEvent.forElement(this);

  /// Stream of `mousedown` events handled by this [Element].
  @DomName('Element.onmousedown')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseDown => mouseDownEvent.forElement(this);

  /// Stream of `mouseenter` events handled by this [Element].
  @DomName('Element.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseEnter => mouseEnterEvent.forElement(this);

  /// Stream of `mouseleave` events handled by this [Element].
  @DomName('Element.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseLeave => mouseLeaveEvent.forElement(this);

  /// Stream of `mousemove` events handled by this [Element].
  @DomName('Element.onmousemove')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseMove => mouseMoveEvent.forElement(this);

  /// Stream of `mouseout` events handled by this [Element].
  @DomName('Element.onmouseout')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOut => mouseOutEvent.forElement(this);

  /// Stream of `mouseover` events handled by this [Element].
  @DomName('Element.onmouseover')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOver => mouseOverEvent.forElement(this);

  /// Stream of `mouseup` events handled by this [Element].
  @DomName('Element.onmouseup')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseUp => mouseUpEvent.forElement(this);

  /// Stream of `mousewheel` events handled by this [Element].
  @DomName('Element.onmousewheel')
  @DocsEditable()
  // http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents
  @Experimental() // non-standard
  ElementStream<WheelEvent> get onMouseWheel => mouseWheelEvent.forElement(this);

  /// Stream of `paste` events handled by this [Element].
  @DomName('Element.onpaste')
  @DocsEditable()
  ElementStream<ClipboardEvent> get onPaste => pasteEvent.forElement(this);

  @DomName('Element.onpause')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPause => pauseEvent.forElement(this);

  @DomName('Element.onplay')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPlay => playEvent.forElement(this);

  @DomName('Element.onplaying')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPlaying => playingEvent.forElement(this);

  @DomName('Element.onratechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onRateChange => rateChangeEvent.forElement(this);

  /// Stream of `reset` events handled by this [Element].
  @DomName('Element.onreset')
  @DocsEditable()
  ElementStream<Event> get onReset => resetEvent.forElement(this);

  @DomName('Element.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onResize => resizeEvent.forElement(this);

  /// Stream of `scroll` events handled by this [Element].
  @DomName('Element.onscroll')
  @DocsEditable()
  ElementStream<Event> get onScroll => scrollEvent.forElement(this);

  /// Stream of `search` events handled by this [Element].
  @DomName('Element.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  ElementStream<Event> get onSearch => searchEvent.forElement(this);

  @DomName('Element.onseeked')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeked => seekedEvent.forElement(this);

  @DomName('Element.onseeking')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeking => seekingEvent.forElement(this);

  /// Stream of `select` events handled by this [Element].
  @DomName('Element.onselect')
  @DocsEditable()
  ElementStream<Event> get onSelect => selectEvent.forElement(this);

  /// Stream of `selectstart` events handled by this [Element].
  @DomName('Element.onselectstart')
  @DocsEditable()
  @Experimental() // nonstandard
  ElementStream<Event> get onSelectStart => selectStartEvent.forElement(this);

  @DomName('Element.onstalled')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onStalled => stalledEvent.forElement(this);

  /// Stream of `submit` events handled by this [Element].
  @DomName('Element.onsubmit')
  @DocsEditable()
  ElementStream<Event> get onSubmit => submitEvent.forElement(this);

  @DomName('Element.onsuspend')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSuspend => suspendEvent.forElement(this);

  @DomName('Element.ontimeupdate')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onTimeUpdate => timeUpdateEvent.forElement(this);

  /// Stream of `touchcancel` events handled by this [Element].
  @DomName('Element.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchCancel => touchCancelEvent.forElement(this);

  /// Stream of `touchend` events handled by this [Element].
  @DomName('Element.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnd => touchEndEvent.forElement(this);

  /// Stream of `touchenter` events handled by this [Element].
  @DomName('Element.ontouchenter')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnter => touchEnterEvent.forElement(this);

  /// Stream of `touchleave` events handled by this [Element].
  @DomName('Element.ontouchleave')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchLeave => touchLeaveEvent.forElement(this);

  /// Stream of `touchmove` events handled by this [Element].
  @DomName('Element.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchMove => touchMoveEvent.forElement(this);

  /// Stream of `touchstart` events handled by this [Element].
  @DomName('Element.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchStart => touchStartEvent.forElement(this);

  /// Stream of `transitionend` events handled by this [Element].
  @DomName('Element.ontransitionend')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  ElementStream<TransitionEvent> get onTransitionEnd => transitionEndEvent.forElement(this);

  @DomName('Element.onvolumechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onVolumeChange => volumeChangeEvent.forElement(this);

  @DomName('Element.onwaiting')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onWaiting => waitingEvent.forElement(this);

  /// Stream of `fullscreenchange` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenchange')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenChange => fullscreenChangeEvent.forElement(this);

  /// Stream of `fullscreenerror` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenError => fullscreenErrorEvent.forElement(this);

}


class _ElementFactoryProvider {

  @DomName('Document.createElement')
  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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  EmbedElement.internal_() : super.internal_();

  /**
   * 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()
  set height(String value) => _blink.BlinkHTMLEmbedElement.instance.height_Setter_(this, value);
  
  @DomName('HTMLEmbedElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLEmbedElement.instance.name_Getter_(this);
  
  @DomName('HTMLEmbedElement.name')
  @DocsEditable()
  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()
  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()
  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()
  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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory Entry._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Entry.internal_() { }

  @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.ErrorEvent')
  @DocsEditable()
  factory ErrorEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkErrorEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkErrorEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ErrorEvent.internal_() : super.internal_();


  @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 DartHtmlDomObject {
  // In JS, canBubble and cancelable are technically required parameters to
  // init*Event. In practice, though, if they aren't provided they simply
  // default to false (since that's Boolean(undefined)).
  //
  // Contrary to JS, we default canBubble and cancelable to true, since that's
  // what people want most of the time anyway.
  factory Event(String type,
      {bool canBubble: true, bool cancelable: true}) {
    return new Event.eventType('Event', type, canBubble: canBubble,
        cancelable: cancelable);
  }

  /**
   * Creates a new Event object of the specified type.
   *
   * This is analogous to document.createEvent.
   * Normally events should be created via their constructors, if available.
   *
   *     var e = new Event.type('MouseEvent', 'mousedown', true, true);
   */
  factory Event.eventType(String type, String name, {bool canBubble: true,
      bool cancelable: true}) {
    final Event e = document._createEvent(type);
    e._initEvent(name, canBubble, cancelable);
    return e;
  }

  /** The CSS selector involved with event delegation. */
  String _selector;

  /**
   * A pointer to the element whose CSS selector matched within which an event
   * was fired. If this Event was not associated with any Event delegation,
   * accessing this value will throw an [UnsupportedError].
   */
  Element get matchingTarget {
    if (_selector == null) {
      throw new UnsupportedError('Cannot call matchingTarget if this Event did'
          ' not arise as a result of event delegation.');
    }
    Element currentTarget = this.currentTarget;
    Element target = this.target;
    var matchedTarget;
    do {
      if (target.matches(_selector)) return target;
      target = target.parent;
    } while (target != null && target != currentTarget.parent);
    throw new StateError('No selector matched for populating matchedTarget.');
  }

  @DomName('Event.Event')
  @DocsEditable()
  factory Event._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Event.internal_() { }

  /**
   * 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);
  
  @DomName('Event.currentTarget')
  @DocsEditable()
  EventTarget get currentTarget => _convertNativeToDart_EventTarget(_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<EventTarget> get path => (_blink.BlinkEvent.instance.path_Getter_(this));
  
  @DomName('Event.target')
  @DocsEditable()
  EventTarget get target => _convertNativeToDart_EventTarget(_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 type, bool bubbles, bool cancelable) => _blink.BlinkEvent.instance.initEvent_Callback_3_(this, type, bubbles, cancelable);
  
  @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 url, {withCredentials: false}) {
    var parsedOptions = {
      'withCredentials': withCredentials,
    };
    return EventSource._factoryEventSource(url, parsedOptions);
  }
  // To suppress missing implicit constructor warnings.
  factory EventSource._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [EventSource].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('EventSource.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `message` events to event
   * handlers that are not necessarily instances of [EventSource].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('EventSource.messageEvent')
  @DocsEditable()
  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');

  /**
   * Static factory designed to expose `open` events to event
   * handlers that are not necessarily instances of [EventSource].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('EventSource.openEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> openEvent = const EventStreamProvider<Event>('open');

  @DomName('EventSource.EventSource')
  @DocsEditable()
  static EventSource _factoryEventSource(String url, [Map eventSourceInitDict]) {
    if (eventSourceInitDict != null) {
      var eventSourceInitDict_1 = convertDartToNative_Dictionary(eventSourceInitDict);
      return _blink.BlinkEventSource.instance.constructorCallback_2_(url, eventSourceInitDict_1);
    }
    return _blink.BlinkEventSource.instance.constructorCallback_1_(url);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  EventSource.internal_() : super.internal_();


  @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 {
  static final webkitEvents = {
    'animationend' : 'webkitAnimationEnd',
    'animationiteration' : 'webkitAnimationIteration',
    'animationstart' : 'webkitAnimationStart',
    'fullscreenchange' : 'webkitfullscreenchange',
    'fullscreenerror' : 'webkitfullscreenerror',
    'keyadded' : 'webkitkeyadded',
    'keyerror' : 'webkitkeyerror',
    'keymessage' : 'webkitkeymessage',
    'needkey' : 'webkitneedkey',
    'pointerlockchange' : 'webkitpointerlockchange',
    'pointerlockerror' : 'webkitpointerlockerror',
    'resourcetimingbufferfull' : 'webkitresourcetimingbufferfull',
    'transitionend': 'webkitTransitionEnd',
    'speechchange' : 'webkitSpeechChange'
  };

  ElementEvents(Element ptr) : super(ptr);

  Stream 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 DartHtmlDomObject {

  // Default constructor to allow other classes e.g. GlobalEventHandlers to be
  // constructed using _internalWrap when mapping Blink object to Dart class.
  EventTarget();

  // Custom element created callback.
  EventTarget._created();

  /**
   * This is an ease-of-use accessor for event streams which should only be
   * used when an explicit accessor is not available.
   */
  Events get on => new Events(this);

  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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  EventTarget.internal_() { }

  @DomName('EventTarget.addEventListener')
  @DocsEditable()
  void _addEventListener(String type, EventListener listener, [bool capture]) => _blink.BlinkEventTarget.instance.addEventListener_Callback_3_(this, type, listener, capture);
  
  @DomName('EventTarget.dispatchEvent')
  @DocsEditable()
  bool dispatchEvent(Event event) => _blink.BlinkEventTarget.instance.dispatchEvent_Callback_1_(this, event);
  
  @DomName('EventTarget.removeEventListener')
  @DocsEditable()
  void _removeEventListener(String type, EventListener listener, [bool capture]) => _blink.BlinkEventTarget.instance.removeEventListener_Callback_3_(this, type, listener, capture);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('ExtendableEvent')
@Experimental() // untriaged
class ExtendableEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory ExtendableEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('ExtendableEvent.ExtendableEvent')
  @DocsEditable()
  factory ExtendableEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkExtendableEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkExtendableEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ExtendableEvent.internal_() : super.internal_();


  @DomName('ExtendableEvent.waitUntil')
  @DocsEditable()
  @Experimental() // untriaged
  void waitUntil(Object value) => _blink.BlinkExtendableEvent.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.

// 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(Map data) {
    var data_1 = convertDartToNative_Dictionary(data);
    return _blink.BlinkFederatedCredential.instance.constructorCallback_1_(data_1);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  FederatedCredential.internal_() : super.internal_();


  @DomName('FederatedCredential.protocol')
  @DocsEditable()
  @Experimental() // untriaged
  String get protocol => _blink.BlinkFederatedCredential.instance.protocol_Getter_(this);
  
  @DomName('FederatedCredential.provider')
  @DocsEditable()
  @Experimental() // untriaged
  String get provider => _blink.BlinkFederatedCredential.instance.provider_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('FetchEvent')
@Experimental() // untriaged
class FetchEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory FetchEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('FetchEvent.FetchEvent')
  @DocsEditable()
  factory FetchEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkFetchEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkFetchEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  FetchEvent.internal_() : super.internal_();


  @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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  FieldSetElement.internal_() : super.internal_();

  /**
   * 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()
  set disabled(bool value) => _blink.BlinkHTMLFieldSetElement.instance.disabled_Setter_(this, value);
  
  @DomName('HTMLFieldSetElement.elements')
  @DocsEditable()
  HtmlFormControlsCollection 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()
  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.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() => _blink.BlinkHTMLFieldSetElement.instance.reportValidity_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.File')
  @DocsEditable()
  factory File(List<Object> fileBits, String fileName, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _blink.BlinkFile.instance.constructorCallback_3_(fileBits, fileName, options_1);
    }
    return _blink.BlinkFile.instance.constructorCallback_2_(fileBits, fileName);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  File.internal_() : super.internal_();


  @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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  FileEntry.internal_() : super.internal_();


  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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  FileError.internal_() : super.internal_();


  @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 DartHtmlDomObject with ListMixin<File>, ImmutableListMixin<File> implements List<File> {
  // To suppress missing implicit constructor warnings.
  factory FileList._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  FileList.internal_() { }

  @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 _nativeIndexedGetter(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.


  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.instance.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_();
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  FileReader.internal_() : super.internal_();


  @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 label]) {
    if (label != null) {
      _blink.BlinkFileReader.instance.readAsText_Callback_2_(this, blob, label);
      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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory FileStream._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  FileStream.internal_() { }

  @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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory FileSystem._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  FileSystem.internal_() { }

  /// 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');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  FileWriter.internal_() : super.internal_();


  @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.FocusEvent')
  @DocsEditable()
  factory FocusEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkFocusEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkFocusEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  FocusEvent.internal_() : super.internal_();


  @DomName('FocusEvent.relatedTarget')
  @DocsEditable()
  EventTarget get relatedTarget => _convertNativeToDart_EventTarget(_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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory FontFace._() { throw new UnsupportedError("Not supported"); }

  @DomName('FontFace.FontFace')
  @DocsEditable()
  factory FontFace(String family, Object source, [Map descriptors]) {
    if (descriptors != null) {
      var descriptors_1 = convertDartToNative_Dictionary(descriptors);
      return _blink.BlinkFontFace.instance.constructorCallback_3_(family, source, descriptors_1);
    }
    return _blink.BlinkFontFace.instance.constructorCallback_2_(family, source);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  FontFace.internal_() { }

  @DomName('FontFace.family')
  @DocsEditable()
  @Experimental() // untriaged
  String get family => _blink.BlinkFontFace.instance.family_Getter_(this);
  
  @DomName('FontFace.family')
  @DocsEditable()
  @Experimental() // untriaged
  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
  set featureSettings(String value) => _blink.BlinkFontFace.instance.featureSettings_Setter_(this, value);
  
  @DomName('FontFace.loaded')
  @DocsEditable()
  @Experimental() // untriaged
  Future get loaded => convertNativePromiseToDartFuture(_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
  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
  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
  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
  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
  set weight(String value) => _blink.BlinkFontFace.instance.weight_Setter_(this, value);
  
  @DomName('FontFace.load')
  @DocsEditable()
  @Experimental() // untriaged
  Future load() => convertNativePromiseToDartFuture(_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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  FontFaceSet.internal_() : super.internal_();


  @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);
  
  bool check(String font, [String text]) {
    if (text != null) {
      return _blink.BlinkFontFaceSet.instance.check_Callback_2_(this, font, text);
    }
    return _blink.BlinkFontFaceSet.instance.check_Callback_1_(this, font);
  }

  @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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  FontFaceSetLoadEvent.internal_() : super.internal_();


  @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 DartHtmlDomObject {
  // 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);


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  FormData.internal_() { }

  /// 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);
  
  @DomName('FormData.delete')
  @DocsEditable()
  @Experimental() // untriaged
  void delete(String name) => _blink.BlinkFormData.instance.delete_Callback_1_(this, name);
  
  @DomName('FormData.get')
  @DocsEditable()
  @Experimental() // untriaged
  Object get(String name) => (_blink.BlinkFormData.instance.get_Callback_1_(this, name));
  
  @DomName('FormData.getAll')
  @DocsEditable()
  @Experimental() // untriaged
  List<Object> getAll(String name) => _blink.BlinkFormData.instance.getAll_Callback_1_(this, name);
  
  @DomName('FormData.has')
  @DocsEditable()
  @Experimental() // untriaged
  bool has(String name) => _blink.BlinkFormData.instance.has_Callback_1_(this, name);
  
  void set(String name, value, [String filename]) {
    if ((value is Blob || value == null) && (name is String || name == null) && filename == null) {
      _blink.BlinkFormData.instance.set_Callback_2_(this, name, value);
      return;
    }
    if ((filename is String || filename == null) && (value is Blob || value == null) && (name is String || name == null)) {
      _blink.BlinkFormData.instance.set_Callback_3_(this, name, value, filename);
      return;
    }
    if ((value is String || value == null) && (name is String || name == null) && filename == null) {
      _blink.BlinkFormData.instance.set_Callback_2_(this, 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('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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  FormElement.internal_() : super.internal_();

  /**
   * 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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  set target(String value) => _blink.BlinkHTMLFormElement.instance.target_Setter_(this, value);
  
  @DomName('HTMLFormElement.__getter__')
  @DocsEditable()
  Object __getter__(String name) => (_blink.BlinkHTMLFormElement.instance.$__getter___Callback_1_(this, name));
  
  @DomName('HTMLFormElement.checkValidity')
  @DocsEditable()
  bool checkValidity() => _blink.BlinkHTMLFormElement.instance.checkValidity_Callback_0_(this);
  
  @DomName('HTMLFormElement.item')
  @DocsEditable()
  @Experimental() // untriaged
  Element item(int index) => _blink.BlinkHTMLFormElement.instance.item_Callback_1_(this, index);
  
  @DomName('HTMLFormElement.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() => _blink.BlinkHTMLFormElement.instance.reportValidity_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, convertDartToNative_Dictionary(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.


@DomName('FrameRequestCallback')
@Experimental() // untriaged
typedef void FrameRequestCallback(num highResTime);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// 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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory Gamepad._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Gamepad.internal_() { }

  @DomName('Gamepad.axes')
  @DocsEditable()
  List<num> get axes => _blink.BlinkGamepad.instance.axes_Getter_(this);
  
  @DomName('Gamepad.buttons')
  @DocsEditable()
  List<GamepadButton> get buttons => (_blink.BlinkGamepad.instance.buttons_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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory GamepadButton._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  GamepadButton.internal_() { }

  @DomName('GamepadButton.pressed')
  @DocsEditable()
  @Experimental() // untriaged
  bool get pressed => _blink.BlinkGamepadButton.instance.pressed_Getter_(this);
  
  @DomName('GamepadButton.value')
  @DocsEditable()
  @Experimental() // untriaged
  num 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.GamepadEvent')
  @DocsEditable()
  factory GamepadEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkGamepadEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkGamepadEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  GamepadEvent.internal_() : super.internal_();


  @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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory Geofencing._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Geofencing.internal_() { }

  @DomName('Geofencing.getRegisteredRegions')
  @DocsEditable()
  @Experimental() // untriaged
  Future getRegisteredRegions() => convertNativePromiseToDartFuture(_blink.BlinkGeofencing.instance.getRegisteredRegions_Callback_0_(this));
  
  @DomName('Geofencing.registerRegion')
  @DocsEditable()
  @Experimental() // untriaged
  Future registerRegion(GeofencingRegion region) => convertNativePromiseToDartFuture(_blink.BlinkGeofencing.instance.registerRegion_Callback_1_(this, region));
  
  @DomName('Geofencing.unregisterRegion')
  @DocsEditable()
  @Experimental() // untriaged
  Future unregisterRegion(String regionId) => convertNativePromiseToDartFuture(_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('GeofencingEvent')
@Experimental() // untriaged
class GeofencingEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory GeofencingEvent._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  GeofencingEvent.internal_() : super.internal_();


  @DomName('GeofencingEvent.id')
  @DocsEditable()
  @Experimental() // untriaged
  String get id => _blink.BlinkGeofencingEvent.instance.id_Getter_(this);
  
  @DomName('GeofencingEvent.region')
  @DocsEditable()
  @Experimental() // untriaged
  GeofencingRegion get region => _blink.BlinkGeofencingEvent.instance.region_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('GeofencingRegion')
@Experimental() // untriaged
class GeofencingRegion extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory GeofencingRegion._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  GeofencingRegion.internal_() { }

  @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 DartHtmlDomObject {

  @DomName('Geolocation.getCurrentPosition')
  Future<Geoposition> getCurrentPosition({bool enableHighAccuracy,
      Duration timeout, Duration maximumAge}) {
    var options = {};
    if (enableHighAccuracy != null) {
      options['enableHighAccuracy'] = enableHighAccuracy;
    }
    if (timeout != null) {
      options['timeout'] = timeout.inMilliseconds;
    }
    if (maximumAge != null) {
      options['maximumAge'] = maximumAge.inMilliseconds;
    }
    var completer = new Completer<Geoposition>();
    try {
      _getCurrentPosition(
          (position) {
            completer.complete(_ensurePosition(position));
          },
          (error) {
            completer.completeError(error);
          },
          options);
    } catch (e, stacktrace) {
      completer.completeError(e, stacktrace);
    }
    return completer.future;
  }

  @DomName('Geolocation.watchPosition')
  Stream<Geoposition> watchPosition({bool enableHighAccuracy,
      Duration timeout, Duration maximumAge}) {

    var options = {};
    if (enableHighAccuracy != null) {
      options['enableHighAccuracy'] = enableHighAccuracy;
    }
    if (timeout != null) {
      options['timeout'] = timeout.inMilliseconds;
    }
    if (maximumAge != null) {
      options['maximumAge'] = maximumAge.inMilliseconds;
    }

    int watchId;
    // TODO(jacobr): it seems like a bug that we have to specifiy the static
    // type here for controller.stream to have the right type.
    // dartbug.com/26278
    StreamController<Geoposition> controller;
    controller = new StreamController<Geoposition>(sync: true,
      onListen: () {
        assert(watchId == null);
        watchId = _watchPosition(
            (position) {
              controller.add(_ensurePosition(position));
            },
            (error) {
              controller.addError(error);
            },
            options);
      },
      onCancel: () {
        assert(watchId != null);
        _clearWatch(watchId);
      });

    return controller.stream;
  }

  Geoposition _ensurePosition(domPosition) {
    return domPosition;
  }

  // To suppress missing implicit constructor warnings.
  factory Geolocation._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Geolocation.internal_() { }

  @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, convertDartToNative_Dictionary(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, convertDartToNative_Dictionary(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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory Geoposition._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Geoposition.internal_() { }

  @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.


// We implement EventTarget and have stubs for its methods because it's tricky to
// convince the scripts to make our instance methods abstract, and the bodies that
// get generated require `this` to be an EventTarget.
@DocsEditable()
@DomName('GlobalEventHandlers')
@Experimental() // untriaged
abstract class GlobalEventHandlers implements EventTarget {

  void addEventListener(String type, dynamic listener(Event event), [bool useCapture]);
  bool dispatchEvent(Event event);
  void removeEventListener(String type, dynamic listener(Event event), [bool useCapture]);
  Events get on;

  // To suppress missing implicit constructor warnings.
  factory GlobalEventHandlers._() { throw new UnsupportedError("Not supported"); }

  @DomName('GlobalEventHandlers.abortEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> abortEvent = const EventStreamProvider<Event>('abort');

  @DomName('GlobalEventHandlers.blurEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> blurEvent = const EventStreamProvider<Event>('blur');

  @DomName('GlobalEventHandlers.canplayEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> canPlayEvent = const EventStreamProvider<Event>('canplay');

  @DomName('GlobalEventHandlers.canplaythroughEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> canPlayThroughEvent = const EventStreamProvider<Event>('canplaythrough');

  @DomName('GlobalEventHandlers.changeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> changeEvent = const EventStreamProvider<Event>('change');

  @DomName('GlobalEventHandlers.clickEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> clickEvent = const EventStreamProvider<MouseEvent>('click');

  @DomName('GlobalEventHandlers.contextmenuEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> contextMenuEvent = const EventStreamProvider<MouseEvent>('contextmenu');

  @DomName('GlobalEventHandlers.dblclickEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> doubleClickEvent = const EventStreamProvider<Event>('dblclick');

  @DomName('GlobalEventHandlers.dragEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragEvent = const EventStreamProvider<MouseEvent>('drag');

  @DomName('GlobalEventHandlers.dragendEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragEndEvent = const EventStreamProvider<MouseEvent>('dragend');

  @DomName('GlobalEventHandlers.dragenterEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragEnterEvent = const EventStreamProvider<MouseEvent>('dragenter');

  @DomName('GlobalEventHandlers.dragleaveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragLeaveEvent = const EventStreamProvider<MouseEvent>('dragleave');

  @DomName('GlobalEventHandlers.dragoverEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragOverEvent = const EventStreamProvider<MouseEvent>('dragover');

  @DomName('GlobalEventHandlers.dragstartEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragStartEvent = const EventStreamProvider<MouseEvent>('dragstart');

  @DomName('GlobalEventHandlers.dropEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dropEvent = const EventStreamProvider<MouseEvent>('drop');

  @DomName('GlobalEventHandlers.durationchangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> durationChangeEvent = const EventStreamProvider<Event>('durationchange');

  @DomName('GlobalEventHandlers.emptiedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> emptiedEvent = const EventStreamProvider<Event>('emptied');

  @DomName('GlobalEventHandlers.endedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');

  @DomName('GlobalEventHandlers.errorEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  @DomName('GlobalEventHandlers.focusEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> focusEvent = const EventStreamProvider<Event>('focus');

  @DomName('GlobalEventHandlers.inputEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> inputEvent = const EventStreamProvider<Event>('input');

  @DomName('GlobalEventHandlers.invalidEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> invalidEvent = const EventStreamProvider<Event>('invalid');

  @DomName('GlobalEventHandlers.keydownEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<KeyboardEvent> keyDownEvent = const EventStreamProvider<KeyboardEvent>('keydown');

  @DomName('GlobalEventHandlers.keypressEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<KeyboardEvent> keyPressEvent = const EventStreamProvider<KeyboardEvent>('keypress');

  @DomName('GlobalEventHandlers.keyupEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<KeyboardEvent> keyUpEvent = const EventStreamProvider<KeyboardEvent>('keyup');

  @DomName('GlobalEventHandlers.loadEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadEvent = const EventStreamProvider<Event>('load');

  @DomName('GlobalEventHandlers.loadeddataEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadedDataEvent = const EventStreamProvider<Event>('loadeddata');

  @DomName('GlobalEventHandlers.loadedmetadataEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadedMetadataEvent = const EventStreamProvider<Event>('loadedmetadata');

  @DomName('GlobalEventHandlers.mousedownEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseDownEvent = const EventStreamProvider<MouseEvent>('mousedown');

  @DomName('GlobalEventHandlers.mouseenterEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseEnterEvent = const EventStreamProvider<MouseEvent>('mouseenter');

  @DomName('GlobalEventHandlers.mouseleaveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseLeaveEvent = const EventStreamProvider<MouseEvent>('mouseleave');

  @DomName('GlobalEventHandlers.mousemoveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseMoveEvent = const EventStreamProvider<MouseEvent>('mousemove');

  @DomName('GlobalEventHandlers.mouseoutEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseOutEvent = const EventStreamProvider<MouseEvent>('mouseout');

  @DomName('GlobalEventHandlers.mouseoverEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseOverEvent = const EventStreamProvider<MouseEvent>('mouseover');

  @DomName('GlobalEventHandlers.mouseupEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseUpEvent = const EventStreamProvider<MouseEvent>('mouseup');

  @DomName('GlobalEventHandlers.mousewheelEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<WheelEvent> mouseWheelEvent = const EventStreamProvider<WheelEvent>('mousewheel');

  @DomName('GlobalEventHandlers.pauseEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> pauseEvent = const EventStreamProvider<Event>('pause');

  @DomName('GlobalEventHandlers.playEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> playEvent = const EventStreamProvider<Event>('play');

  @DomName('GlobalEventHandlers.playingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> playingEvent = const EventStreamProvider<Event>('playing');

  @DomName('GlobalEventHandlers.ratechangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> rateChangeEvent = const EventStreamProvider<Event>('ratechange');

  @DomName('GlobalEventHandlers.resetEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> resetEvent = const EventStreamProvider<Event>('reset');

  @DomName('GlobalEventHandlers.resizeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> resizeEvent = const EventStreamProvider<Event>('resize');

  @DomName('GlobalEventHandlers.scrollEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> scrollEvent = const EventStreamProvider<Event>('scroll');

  @DomName('GlobalEventHandlers.seekedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> seekedEvent = const EventStreamProvider<Event>('seeked');

  @DomName('GlobalEventHandlers.seekingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> seekingEvent = const EventStreamProvider<Event>('seeking');

  @DomName('GlobalEventHandlers.selectEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> selectEvent = const EventStreamProvider<Event>('select');

  @DomName('GlobalEventHandlers.stalledEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> stalledEvent = const EventStreamProvider<Event>('stalled');

  @DomName('GlobalEventHandlers.submitEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> submitEvent = const EventStreamProvider<Event>('submit');

  @DomName('GlobalEventHandlers.suspendEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> suspendEvent = const EventStreamProvider<Event>('suspend');

  @DomName('GlobalEventHandlers.timeupdateEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> timeUpdateEvent = const EventStreamProvider<Event>('timeupdate');

  @DomName('GlobalEventHandlers.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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  HRElement.internal_() : super.internal_();

  /**
   * 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
  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}) {

    // TODO(alanknight): This is required while we're on Dartium 39, but will need
    // to look like dart2js with later versions when initHashChange is removed.
    var event = document._createEvent("HashChangeEvent");
    event._initHashChangeEvent(type, canBubble, cancelable, oldUrl, newUrl);
    return event;
  }


  @DomName('HashChangeEvent.HashChangeEvent')
  @DocsEditable()
  factory HashChangeEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkHashChangeEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkHashChangeEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  HashChangeEvent.internal_() : super.internal_();


  /// 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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  HeadElement.internal_() : super.internal_();

  /**
   * 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 DartHtmlDomObject {
  // 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)) {
      return _blink.BlinkHeaders.instance.constructorCallback_1_(input);
    }
    if ((input is Map)) {
      var input_1 = convertDartToNative_Dictionary(input);
      return _blink.BlinkHeaders.instance.constructorCallback_1_(input_1);
    }
    if ((input is List<Object>)) {
      return _blink.BlinkHeaders.instance.constructorCallback_1_(input);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Headers.internal_() { }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  HeadingElement.internal_() : super.internal_();

  /**
   * 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 DartHtmlDomObject 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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  History.internal_() { }

  @DomName('History.length')
  @DocsEditable()
  int get length => _blink.BlinkHistory.instance.length_Getter_(this);
  
  @DomName('History.options')
  @DocsEditable()
  @Experimental() // untriaged
   get options => convertNativeDictionaryToDartDictionary((_blink.BlinkHistory.instance.options_Getter_(this)));
  
  @DomName('History.state')
  @DocsEditable()
  dynamic get state => convertNativeToDart_SerializedScriptValue(_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);
  
  void go([int delta]) {
    if (delta != null) {
      _blink.BlinkHistory.instance.go_Callback_1_(this, delta);
      return;
    }
    _blink.BlinkHistory.instance.go_Callback_0_(this);
    return;
  }

  void pushState(/*SerializedScriptValue*/ data, String title, String url, [Map options]) {
    if (options != null) {
      _blink.BlinkHistory.instance.pushState_Callback_4_(this, convertDartToNative_SerializedScriptValue(data), title, url, convertDartToNative_Dictionary(options));
      return;
    }
    _blink.BlinkHistory.instance.pushState_Callback_3_(this, convertDartToNative_SerializedScriptValue(data), title, url);
    return;
  }

  void replaceState(/*SerializedScriptValue*/ data, String title, String url, [Map options]) {
    if (options != null) {
      _blink.BlinkHistory.instance.replaceState_Callback_4_(this, convertDartToNative_SerializedScriptValue(data), title, url, convertDartToNative_Dictionary(options));
      return;
    }
    _blink.BlinkHistory.instance.replaceState_Callback_3_(this, convertDartToNative_SerializedScriptValue(data), title, url);
    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('HMDVRDevice')
@Experimental() // untriaged
class HmdvrDevice extends VRDevice {
  // To suppress missing implicit constructor warnings.
  factory HmdvrDevice._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  HmdvrDevice.internal_() : super.internal_();


  @DomName('HMDVRDevice.getEyeParameters')
  @DocsEditable()
  @Experimental() // untriaged
  VREyeParameters getEyeParameters(String whichEye) => _blink.BlinkHMDVRDevice.instance.getEyeParameters_Callback_1_(this, whichEye);
  
  void setFieldOfView([VRFieldOfView leftFov, VRFieldOfView rightFov]) {
    if (rightFov != null) {
      _blink.BlinkHMDVRDevice.instance.setFieldOfView_Callback_2_(this, leftFov, rightFov);
      return;
    }
    if (leftFov != null) {
      _blink.BlinkHMDVRDevice.instance.setFieldOfView_Callback_1_(this, leftFov);
      return;
    }
    _blink.BlinkHMDVRDevice.instance.setFieldOfView_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('HTMLCollection')
class HtmlCollection extends DartHtmlDomObject with ListMixin<Node>, ImmutableListMixin<Node> implements List<Node> {
  // To suppress missing implicit constructor warnings.
  factory HtmlCollection._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  HtmlCollection.internal_() { }

  @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 _nativeIndexedGetter(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.


  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()
  Node item(int index) => _blink.BlinkHTMLCollection.instance.item_Callback_1_(this, index);
  
  @DomName('HTMLCollection.namedItem')
  @DocsEditable()
  Object 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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  HtmlDocument.internal_() : super.internal_();



  @DomName('Document.body')
  BodyElement get body => _body;

  @DomName('Document.body')
  set body(BodyElement value) {
    _body = value;
  }

  /// UNSTABLE: Chrome-only - create a Range from the given point.
  @DomName('Document.caretRangeFromPoint')
  @Unstable()
  Range caretRangeFromPoint(int x, int y) {
    return _caretRangeFromPoint(x, y);
  }

  @DomName('Document.elementFromPoint')
  Element elementFromPoint(int x, int y) {
    return _elementFromPoint(x, y);
  }

  /**
   * Checks if the getCssCanvasContext API is supported on the current platform.
   *
   * See also:
   *
   * * [getCssCanvasContext]
   */
  static bool get supportsCssCanvasContext => 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;
  set selectedStylesheetSet(String value) {
    _selectedStylesheetSet = value;
  }

  @DomName('Document.styleSheets')
  List<StyleSheet> get styleSheets => _styleSheets;

  @DomName('Document.title')
  String get title => _title;

  @DomName('Document.title')
  set title(String value) {
    _title = value;
  }

  /**
   * Returns page to standard layout.
   *
   * Has no effect if the page is not in fullscreen mode.
   *
   * ## Other resources
   *
   * * [Using the fullscreen
   *   API](http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)
   *   from WebPlatform.org.
   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
   */
  @DomName('Document.webkitExitFullscreen')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  void exitFullscreen() {
    _webkitExitFullscreen();
  }


  /**
   * Internal routine to find the DOM JS class name being extended for custom
   * elements.
   */
  String _getJSClassName(ClassMirror classMirror) {
    var jsClassName = null;
    var isElement = false;

    while (classMirror.superclass != null) {
      var fullName = classMirror.superclass.qualifiedName;
      isElement = isElement ||
          (fullName == #dart.dom.html.Element || fullName == #dart.dom.svg.Element);

      var domLibrary = MirrorSystem.getName(fullName).startsWith('dart.dom.');
      if (jsClassName == null && domLibrary) {
        // Lookup JS class name (if not found).
        var metadatas = classMirror.metadata;
        for (var metadata in metadatas) {
          var metaDataMirror = metadata.reflectee;
          var metaType = reflectClass(metaDataMirror.runtimeType);
          if (MirrorSystem.getName(metaType.simpleName) == 'DomName' &&
              (metaDataMirror.name.startsWith('HTML') || metaDataMirror.name.startsWith('SVG'))) {
            jsClassName = metadata.reflectee.name;
          }
        }
      }

      classMirror = classMirror.superclass;
    }

    // If we're an element then everything is okay.
    return isElement ? jsClassName : null;
  }

  // Get the first class that's a super of a dart.dom library.
  ClassMirror _getDartHtmlClassName(ClassMirror classMirror) {
    while (classMirror.superclass != null) {
      var fullName = classMirror.superclass.qualifiedName;
      var domLibrary = MirrorSystem.getName(fullName).startsWith('dart.dom.');
      if (domLibrary) {
        return classMirror.superclass;
      }

      classMirror = classMirror.superclass;
    }

    return null;
  }

  /**
   * Get the class that immediately derived from a class in dart:html or
   * dart:svg (has an attribute DomName of either HTML* or SVG*).
   */
  ClassMirror _getDomSuperClass(ClassMirror classMirror) {
    var isElement = false;
    var foundSuperElement = null;

    while (classMirror.superclass != null) {
      var fullName = classMirror.superclass.qualifiedName;
      isElement = isElement || (fullName == #dart.dom.html.Element || fullName == #dart.dom.svg.Element);

      var domLibrary = MirrorSystem.getName(fullName).startsWith('dart.dom.');
      if (domLibrary) {
        if (foundSuperElement == null) {
          foundSuperElement = classMirror.superclass;
        }
        // Lookup JS class (if not found).
        var metadatas = classMirror.metadata;
        for (var metadata in metadatas) {
          var metaDataMirror = metadata.reflectee;
          var metaType = reflectClass(metaDataMirror.runtimeType);
          if (MirrorSystem.getName(metaType.simpleName) == 'DomName' &&
              (metaDataMirror.name.startsWith('HTML') || metaDataMirror.name.startsWith('SVG'))) {
            if (isElement) return foundSuperElement;
          }
        }
      }

      classMirror = classMirror.superclass;
    }

    return null;
  }

  /**
   * Does this CustomElement class have:
   *
   *   - a created constructor with no arguments?
   *   - a created constructor with a super.created() initializer?
   *
   * e.g.,    MyCustomClass.created() : super.created();
   */
  bool _hasCreatedConstructor(ClassMirror classToRegister) {
    var htmlClassMirror = _getDomSuperClass(classToRegister);

    var classMirror = classToRegister;
    while (classMirror != null && classMirror != htmlClassMirror) {
      var createdParametersValid = false;
      var superCreatedCalled = false;
      var className = MirrorSystem.getName(classMirror.simpleName);
      var methodMirror = classMirror.declarations[new Symbol("$className.created")];
      if (methodMirror != null && methodMirror.isConstructor) {
        createdParametersValid = true;                // Assume no parameters.
        if (methodMirror.parameters.length != 0) {
          // If any parameters each one must be optional.
          methodMirror.parameters.forEach((parameter) {
            createdParametersValid = createdParametersValid && parameter.isOptional;
          });
        }
      }

      if (!createdParametersValid) {
        throw new DomException.jsInterop('created constructor must have no parameters');
      }

      classMirror = classMirror.superclass;
      while (classMirror != classMirror.mixin) {
        // Skip the mixins.
        classMirror = classMirror.superclass;
      }
    }

    return true;
  }

  @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}) {
    // Hack to setup an interceptor for HTMLElement so it isn't changed when a custom element is created.
    var jsHTMLElementPrototype = js.JsNative.getProperty(js.JsNative.getProperty(js.context, 'HTMLElement'),'prototype');
    _blink.Blink_Utils.defineInterceptor(jsHTMLElementPrototype, HtmlElement.instanceRuntimeType);

    // Figure out which DOM class is being extended from the user's Dart class.
    var classMirror = reflectClass(customElementClass);

    var locationUri = classMirror.location.sourceUri.toString();
    if (locationUri == 'dart:html' || locationUri == 'dart:svg') {
      throw new DomException.jsInterop("HierarchyRequestError: Cannot register an existing dart:html or dart:svg type.");
    }

    if (classMirror.isAbstract) {
      throw new DomException.jsInterop("HierarchyRequestError: Cannot register an abstract class.");
    }

    var jsClassName = _getJSClassName(classMirror);
    if (jsClassName == null) {
      // Only components derived from HTML* can be extended.
      throw new DomException.jsInterop("HierarchyRequestError: Only HTML elements can be customized.");
    }

    var customClassType = _getDartHtmlClassName(classMirror);

    if (extendsTag != null) {
      var nativeElement = document.createElement(extendsTag);

      // Trying to extend a native element is it the Dart class consistent with the
      // extendsTag?
      if (nativeElement.runtimeType != customClassType.reflectedType) {
        var nativeElementClassMirror = reflectClass(nativeElement.runtimeType);
        var customClassNativeElement = MirrorSystem.getName(customClassType.simpleName);
        var extendsNativeElement = MirrorSystem.getName(nativeElementClassMirror.simpleName);
        throw new DomException.jsInterop("HierarchyRequestError: Custom class type ($customClassNativeElement) and extendsTag class ($extendsNativeElement) don't match .");
      }
    } else if (customClassType.reflectedType != HtmlElement && customClassType.reflectedType != svg.SvgElement) {
      var customClassName = MirrorSystem.getName(classMirror.simpleName);
      var customClassElement = MirrorSystem.getName(customClassType.simpleName);
      throw new DomException.jsInterop("HierarchyRequestError: Custom element $customClassName is a native $customClassElement should be derived from HtmlElement or SvgElement.");
    }

    if (_hasCreatedConstructor(classMirror)) {
      // Start the hookup the JS way create an <x-foo> element that extends the
      // <x-base> custom element. Inherit its prototype and signal what tag is
      // inherited:
      //
      //     var myProto = Object.create(HTMLElement.prototype);
      //     var myElement = document.registerElement('x-foo', {prototype: myProto});
      var baseElement = js.JsNative.getProperty(js.context, jsClassName);
      if (baseElement == null) {
        // Couldn't find the HTML element so use a generic one.
        baseElement = js.JsNative.getProperty(js.context, 'HTMLElement');
      }
      var elemProto = js.JsNative.callMethod(js.JsNative.getProperty(js.context, 'Object'), "create", [js.JsNative.getProperty(baseElement, 'prototype')]);

      // TODO(terry): Hack to stop recursion re-creating custom element when the
      //              created() constructor of the custom element does e.g.,
      //
      //                  MyElement.created() : super.created() {
      //                    this.innerHtml = "<b>I'm an x-foo-with-markup!</b>";
      //                  }
      //
      //              sanitizing causes custom element to created recursively
      //              until stack overflow.
      //
      //              See https://github.com/dart-lang/sdk/issues/23666
      int creating = 0; // TODO(jacobr): I think I broke thise case. Will fix monday.

      // If any JS code is hooked we want to call it too.
      var oldCreatedCallback = js.JsNative.getProperty(elemProto, 'createdCallback');
      var oldAttributeChangedCallback = js.JsNative.getProperty(elemProto, 'attributeChangedCallback');
      var oldAttachedCallback = js.JsNative.getProperty(elemProto, 'attachedCallback');
      var oldDetachedCallback = js.JsNative.getProperty(elemProto, 'detachedCallback');

      js.JsNative.setProperty(elemProto, 'createdCallback', js.allowInteropCaptureThis(($this) {
        // The created callback has already been called by the very act of passing a JS
        // custom element from JS to Dart.

        //  Make element's interceptor a CustomElementClass.
        _blink.Blink_Utils.setInstanceInterceptorCustomUpgrade($this);

        if (oldCreatedCallback != null)
          oldCreatedCallback.apply([], thisArg: $this);
      }));
      js.JsNative.setProperty(elemProto, 'attributeChangedCallback', js.allowInteropCaptureThis(($this, attrName, oldVal, newVal) {
        $this.attributeChanged(attrName, oldVal, newVal);

        if (oldAttributeChangedCallback != null)
          oldAttributeChangedCallback.apply([], thisArg: $this);
      }));
      js.JsNative.setProperty(elemProto, 'attachedCallback', js.allowInteropCaptureThis(($this) {
        $this.attached();

        if (oldAttachedCallback != null)
          oldAttachedCallback.apply([], thisArg: $this);
      }));
      js.JsNative.setProperty(elemProto, 'detachedCallback', js.allowInteropCaptureThis(($this) {
        $this.detached();

        if (oldDetachedCallback != null)
          oldDetachedCallback.apply([], thisArg: $this);
      }));
      // document.registerElement('x-foo', {prototype: elemProto, extends: extendsTag});
      var jsMap = new js.JsObject.jsify({'prototype': elemProto, 'extends': extendsTag});
      _blink.Blink_Utils.defineInterceptorCustomElement(elemProto, customElementClass);
      js.JsNative.callMethod(document, 'registerElement', [tag, jsMap]);
    }
  }

  /** *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.


@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');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  HtmlElement.internal_() : super.internal_();

  /**
   * 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()
  set contentEditable(String value) => _blink.BlinkHTMLElement.instance.contentEditable_Setter_(this, value);
  
  @DomName('HTMLElement.contextMenu')
  @DocsEditable()
  @Experimental() // untriaged
  MenuElement get contextMenu => _blink.BlinkHTMLElement.instance.contextMenu_Getter_(this);
  
  @DomName('HTMLElement.contextMenu')
  @DocsEditable()
  @Experimental() // untriaged
  set contextMenu(MenuElement value) => _blink.BlinkHTMLElement.instance.contextMenu_Setter_(this, value);
  
  @DomName('HTMLElement.dir')
  @DocsEditable()
  String get dir => _blink.BlinkHTMLElement.instance.dir_Getter_(this);
  
  @DomName('HTMLElement.dir')
  @DocsEditable()
  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()
  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()
  set hidden(bool value) => _blink.BlinkHTMLElement.instance.hidden_Setter_(this, value);
  
  @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()
  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
  set spellcheck(bool value) => _blink.BlinkHTMLElement.instance.spellcheck_Setter_(this, value);
  
  @DomName('HTMLElement.style')
  @DocsEditable()
  @Experimental() // untriaged
  CssStyleDeclaration get style => _blink.BlinkHTMLElement.instance.style_Getter_(this);
  
  @DomName('HTMLElement.tabIndex')
  @DocsEditable()
  int get tabIndex => _blink.BlinkHTMLElement.instance.tabIndex_Getter_(this);
  
  @DomName('HTMLElement.tabIndex')
  @DocsEditable()
  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()
  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()
  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
  set dropzone(String value) => _blink.BlinkHTMLElement.instance.webkitdropzone_Setter_(this, value);
  
  @DomName('HTMLElement.blur')
  @DocsEditable()
  @Experimental() // untriaged
  void blur() => _blink.BlinkHTMLElement.instance.blur_Callback_0_(this);
  
  @DomName('HTMLElement.click')
  @DocsEditable()
  void click() => _blink.BlinkHTMLElement.instance.click_Callback_0_(this);
  
  @DomName('HTMLElement.focus')
  @DocsEditable()
  @Experimental() // untriaged
  void focus() => _blink.BlinkHTMLElement.instance.focus_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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  HtmlFormControlsCollection.internal_() : super.internal_();


  @DomName('HTMLFormControlsCollection.item')
  @DocsEditable()
  @Experimental() // untriaged
  Node item(int index) => _blink.BlinkHTMLFormControlsCollection.instance.item_Callback_1_(this, index);
  
  @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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  HtmlHtmlElement.internal_() : super.internal_();

  /**
   * 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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  HtmlOptionsCollection.internal_() : super.internal_();


  @DomName('HTMLOptionsCollection.item')
  @DocsEditable()
  @Experimental() // untriaged
  Node _item(int index) => _blink.BlinkHTMLOptionsCollection.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.


 /**
  * 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((HttpRequest xhr) => xhr.responseText);
  }

  /**
   * Makes a server POST request with the specified data encoded as form data.
   *
   * This is roughly the POST equivalent of getString. This method is similar
   * to sending a FormData object with broader browser support but limited to
   * String values.
   *
   * If [data] is supplied, the key/value pairs are URI encoded with
   * [Uri.encodeQueryComponent] and converted into an HTTP query string.
   *
   * Unless otherwise specified, this method appends the following header:
   *
   *     Content-Type: application/x-www-form-urlencoded; charset=UTF-8
   *
   * Here's an example of using this method:
   *
   *     var data = { 'firstName' : 'John', 'lastName' : 'Doe' };
   *     HttpRequest.postFormData('/send', data).then((HttpRequest resp) {
   *       // Do something with the response.
   *     });
   *
   * See also:
   *
   * * [request]
   */
  static Future<HttpRequest> postFormData(String url, Map<String, String> data,
      {bool withCredentials, String responseType,
      Map<String, String> requestHeaders,
      void onProgress(ProgressEvent e)}) {

    var parts = [];
    data.forEach((key, value) {
      parts.add('${Uri.encodeQueryComponent(key)}='
          '${Uri.encodeQueryComponent(value)}');
    });
    var formData = parts.join('&');

    if (requestHeaders == null) {
      requestHeaders = <String, String>{};
    }
    requestHeaders.putIfAbsent('Content-Type',
        () => 'application/x-www-form-urlencoded; charset=UTF-8');

    return request(url, method: 'POST', withCredentials: withCredentials,
        responseType: responseType,
        requestHeaders: requestHeaders, sendData: formData,
        onProgress: onProgress);
  }

  /**
   * Creates and sends a URL request for the specified [url].
   *
   * By default `request` will perform an HTTP GET request, but a different
   * method (`POST`, `PUT`, `DELETE`, etc) can be used by specifying the
   * [method] parameter. (See also [HttpRequest.postFormData] for `POST` 
   * requests only.
   *
   * The Future is completed when the response is available.
   *
   * If specified, `sendData` will send data in the form of a [ByteBuffer],
   * [Blob], [Document], [String], or [FormData] along with the HttpRequest.
   *
   * If specified, [responseType] sets the desired response format for the
   * request. By default it is [String], but can also be 'arraybuffer', 'blob', 
   * 'document', 'json', or 'text'. See also [HttpRequest.responseType] 
   * for more information.
   *
   * The [withCredentials] parameter specified that credentials such as a cookie
   * (already) set in the header or
   * [authorization headers](http://tools.ietf.org/html/rfc1945#section-10.2)
   * should be specified for the request. Details to keep in mind when using
   * credentials:
   *
   * * Using credentials is only useful for cross-origin requests.
   * * The `Access-Control-Allow-Origin` header of `url` cannot contain a wildcard (*).
   * * The `Access-Control-Allow-Credentials` header of `url` must be set to true.
   * * If `Access-Control-Expose-Headers` has not been set to true, only a subset of all the response headers will be returned when calling [getAllRequestHeaders].
   *
   * The following is equivalent to the [getString] sample above:
   *
   *     var name = Uri.encodeQueryComponent('John');
   *     var id = Uri.encodeQueryComponent('42');
   *     HttpRequest.request('users.json?name=$name&id=$id')
   *       .then((HttpRequest resp) {
   *         // Do something with the response.
   *     });
   *
   * Here's an example of submitting an entire form with [FormData].
   *
   *     var myForm = querySelector('form#myForm');
   *     var data = new FormData(myForm);
   *     HttpRequest.request('/submit', method: 'POST', sendData: data)
   *       .then((HttpRequest resp) {
   *         // Do something with the response.
   *     });
   *
   * Note that requests for file:// URIs are only supported by Chrome extensions
   * with appropriate permissions in their manifest. Requests to file:// URIs
   * will also never fail- the Future will always complete successfully, even
   * when the file cannot be found.
   *
   * See also: [authorization headers](http://en.wikipedia.org/wiki/Basic_access_authentication).
   */
  static Future<HttpRequest> request(String url,
      {String method, bool withCredentials, String responseType,
      String mimeType, Map<String, String> requestHeaders, sendData,
      void onProgress(ProgressEvent e)}) {
    var completer = new Completer<HttpRequest>();

    var xhr = new HttpRequest();
    if (method == null) {
      method = 'GET';
    }
    xhr.open(method, url, async: true);

    if (withCredentials != null) {
      xhr.withCredentials = withCredentials;
    }

    if (responseType != null) {
      xhr.responseType = responseType;
    }

    if (mimeType != null) {
      xhr.overrideMimeType(mimeType);
    }

    if (requestHeaders != null) {
      requestHeaders.forEach((header, value) {
        xhr.setRequestHeader(header, value);
      });
    }

    if (onProgress != null) {
      xhr.onProgress.listen(onProgress);
    }

    xhr.onLoad.listen((e) {
      var accepted = xhr.status >= 200 && xhr.status < 300;
      var fileUri = xhr.status == 0; // file:// URIs have status of 0.
      var notModified = xhr.status == 304;
      // Redirect status is specified up to 307, but others have been used in
      // practice. Notably Google Drive uses 308 Resume Incomplete for
      // resumable uploads, and it's also been used as a redirect. The
      // redirect case will be handled by the browser before it gets to us,
      // so if we see it we should pass it through to the user.
      var unknownRedirect = xhr.status > 307 && xhr.status < 400;
      
      if (accepted || fileUri || notModified || unknownRedirect) {
        completer.complete(xhr);
      } else {
        completer.completeError(e);
      }
    });

    xhr.onError.listen(completer.completeError);

    if (sendData != null) {
      xhr.send(sendData);
    } else {
      xhr.send();
    }

    return completer.future;
  }

  /**
   * Checks to see if the Progress event is supported on the current platform.
   */
  static bool get supportsProgressEvent {
    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;
  }

  /**
   * 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}) {
    if (async == null && user == null && password == null) {
      _blink.BlinkXMLHttpRequest.instance.open_Callback_2_(this, method, url);
    } else {
      _blink.BlinkXMLHttpRequest.instance.open_Callback_5_(this, method, url, async, user, password);
    }
  }

  // To suppress missing implicit constructor warnings.
  factory HttpRequest._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `readystatechange` events to event
   * handlers that are not necessarily instances of [HttpRequest].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequest.readystatechangeEvent')
  @DocsEditable()
  static const EventStreamProvider<ProgressEvent> readyStateChangeEvent = const EventStreamProvider<ProgressEvent>('readystatechange');

  /**
   * General constructor for any type of request (GET, POST, etc).
   *
   * This call is used in conjunction with [open]:
   *
   *     var request = new HttpRequest();
   *     request.open('GET', 'http://dartlang.org');
   *     request.onLoad.listen((event) => print(
   *         'Request complete ${event.target.reponseText}'));
   *     request.send();
   *
   * is the (more verbose) equivalent of
   *
   *     HttpRequest.getString('http://dartlang.org').then(
   *         (result) => print('Request complete: $result'));
   */
  @DomName('XMLHttpRequest.XMLHttpRequest')
  @DocsEditable()
  factory HttpRequest() {
    return _blink.BlinkXMLHttpRequest.instance.constructorCallback_0_();
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  HttpRequest.internal_() : super.internal_();


  @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 => _convertNativeToDart_XHR_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/Web/API/XMLHttpRequest#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/Web/API/XMLHttpRequest#xmlhttprequest-responsetype)
   */
  @DomName('XMLHttpRequest.responseType')
  @DocsEditable()
  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#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#xmlhttprequest-timeout)
   *   from MDN.
   * * [The timeout attribute](http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute)
   *   from W3C.
   */
  @DomName('XMLHttpRequest.timeout')
  @DocsEditable()
  @Experimental() // untriaged
  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()
  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](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields)
   * for a list of common response headers.
   */
  @DomName('XMLHttpRequest.getAllResponseHeaders')
  @DocsEditable()
  @Unstable()
  String getAllResponseHeaders() => _blink.BlinkXMLHttpRequest.instance.getAllResponseHeaders_Callback_0_(this);
  
  /**
   * Return the response header named `header`, or null if not found.
   *
   * See also [HTTP response
   * headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields)
   * for a list of common response headers.
   */
  @DomName('XMLHttpRequest.getResponseHeader')
  @DocsEditable()
  @Unstable()
  String getResponseHeader(String name) => _blink.BlinkXMLHttpRequest.instance.getResponseHeader_Callback_1_(this, name);
  
  /**
   * Specify a particular MIME type (such as `text/xml`) desired for the
   * response.
   *
   * This value must be set before the request has been sent. See also the list
   * of [IANA Official MIME types](https://www.iana.org/assignments/media-types/media-types.xhtml)
   */
  @DomName('XMLHttpRequest.overrideMimeType')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void overrideMimeType(String mime) => _blink.BlinkXMLHttpRequest.instance.overrideMimeType_Callback_1_(this, mime);
  
  void send([body_OR_data]) {
    if (body_OR_data != null) {
      _blink.BlinkXMLHttpRequest.instance.send_Callback_1_(this, body_OR_data);
      return;
    }
    if ((body_OR_data is TypedData || body_OR_data == null)) {
      _blink.BlinkXMLHttpRequest.instance.send_Callback_1_(this, body_OR_data);
      return;
    }
    if ((body_OR_data is ByteBuffer || body_OR_data == null)) {
      _blink.BlinkXMLHttpRequest.instance.send_Callback_1_(this, body_OR_data);
      return;
    }
    if ((body_OR_data is Document || body_OR_data == null)) {
      _blink.BlinkXMLHttpRequest.instance.send_Callback_1_(this, body_OR_data);
      return;
    }
    if ((body_OR_data is String || body_OR_data == null)) {
      _blink.BlinkXMLHttpRequest.instance.send_Callback_1_(this, body_OR_data);
      return;
    }
    if ((body_OR_data is FormData || body_OR_data == null)) {
      _blink.BlinkXMLHttpRequest.instance.send_Callback_1_(this, body_OR_data);
      return;
    }
    if ((body_OR_data is Blob || body_OR_data == null)) {
      _blink.BlinkXMLHttpRequest.instance.send_Callback_1_(this, body_OR_data);
      return;
    }
    if (body_OR_data == null) {
      _blink.BlinkXMLHttpRequest.instance.send_Callback_0_(this);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  /**
   * 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/Web/API/XMLHttpRequest#setRequestHeader())
   *   from MDN.
   * * [The setRequestHeader()
   *   method](http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method)
   *   from W3C.
   */
  @DomName('XMLHttpRequest.setRequestHeader')
  @DocsEditable()
  void setRequestHeader(String name, String value) => _blink.BlinkXMLHttpRequest.instance.setRequestHeader_Callback_2_(this, name, 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');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  HttpRequestEventTarget.internal_() : super.internal_();


  /// 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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  HttpRequestUpload.internal_() : super.internal_();


}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  IFrameElement.internal_() : super.internal_();

  /**
   * 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
  set allowFullscreen(bool value) => _blink.BlinkHTMLIFrameElement.instance.allowFullscreen_Setter_(this, value);
  
  @DomName('HTMLIFrameElement.contentWindow')
  @DocsEditable()
  WindowBase get contentWindow => _convertNativeToDart_Window(_blink.BlinkHTMLIFrameElement.instance.contentWindow_Getter_(this));
  
  @DomName('HTMLIFrameElement.height')
  @DocsEditable()
  String get height => _blink.BlinkHTMLIFrameElement.instance.height_Getter_(this);
  
  @DomName('HTMLIFrameElement.height')
  @DocsEditable()
  set height(String value) => _blink.BlinkHTMLIFrameElement.instance.height_Setter_(this, value);
  
  @DomName('HTMLIFrameElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLIFrameElement.instance.name_Getter_(this);
  
  @DomName('HTMLIFrameElement.name')
  @DocsEditable()
  set name(String value) => _blink.BlinkHTMLIFrameElement.instance.name_Setter_(this, value);
  
  @DomName('HTMLIFrameElement.sandbox')
  @DocsEditable()
  DomSettableTokenList get sandbox => _blink.BlinkHTMLIFrameElement.instance.sandbox_Getter_(this);
  
  @DomName('HTMLIFrameElement.src')
  @DocsEditable()
  String get src => _blink.BlinkHTMLIFrameElement.instance.src_Getter_(this);
  
  @DomName('HTMLIFrameElement.src')
  @DocsEditable()
  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()
  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()
  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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory ImageBitmap._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ImageBitmap.internal_() { }

  @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 DartHtmlDomObject {
  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_sw, int sh_OR_sw, [int sh]) {
    if ((sh_OR_sw is int) && (data_OR_sw is int) && sh == null) {
      return _blink.BlinkImageData.instance.constructorCallback_2_(data_OR_sw, sh_OR_sw);
    }
    if ((sh_OR_sw is int) && (data_OR_sw is Uint8ClampedList) && sh == null) {
      return _blink.BlinkImageData.instance.constructorCallback_2_(data_OR_sw, sh_OR_sw);
    }
    if ((sh is int) && (sh_OR_sw is int) && (data_OR_sw is Uint8ClampedList)) {
      return _blink.BlinkImageData.instance.constructorCallback_3_(data_OR_sw, sh_OR_sw, sh);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ImageData.internal_() { }

  @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}) {
    ImageElement e = document.createElement("img");
    if (src != null) e.src = src;
    if (width != null) e.width = width;
    if (height != null) e.height = height;
    return e;
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ImageElement.internal_() : super.internal_();

  /**
   * 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()
  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()
  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()
  set height(int value) => _blink.BlinkHTMLImageElement.instance.height_Setter_(this, value);
  
  @DomName('HTMLImageElement.isMap')
  @DocsEditable()
  bool get isMap => _blink.BlinkHTMLImageElement.instance.isMap_Getter_(this);
  
  @DomName('HTMLImageElement.isMap')
  @DocsEditable()
  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
  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()
  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
  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()
  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()
  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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory InjectedScriptHost._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  InjectedScriptHost.internal_() { }

  @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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('InputDevice')
@Experimental() // untriaged
class InputDevice extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory InputDevice._() { throw new UnsupportedError("Not supported"); }

  @DomName('InputDevice.InputDevice')
  @DocsEditable()
  factory InputDevice([Map deviceInitDict]) {
    if (deviceInitDict != null) {
      var deviceInitDict_1 = convertDartToNative_Dictionary(deviceInitDict);
      return _blink.BlinkInputDevice.instance.constructorCallback_1_(deviceInitDict_1);
    }
    return _blink.BlinkInputDevice.instance.constructorCallback_0_();
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  InputDevice.internal_() { }

  @DomName('InputDevice.firesTouchEvents')
  @DocsEditable()
  @Experimental() // untriaged
  bool get firesTouchEvents => _blink.BlinkInputDevice.instance.firesTouchEvents_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('HTMLInputElement')
class InputElement extends HtmlElement implements
    HiddenInputElement,
    SearchInputElement,
    TextInputElement,
    UrlInputElement,
    TelephoneInputElement,
    EmailInputElement,
    PasswordInputElement,
    DateInputElement,
    MonthInputElement,
    WeekInputElement,
    TimeInputElement,
    LocalDateTimeInputElement,
    NumberInputElement,
    RangeInputElement,
    CheckboxInputElement,
    RadioButtonInputElement,
    FileUploadInputElement,
    SubmitButtonInputElement,
    ImageButtonInputElement,
    ResetButtonInputElement,
    ButtonInputElement {

  factory InputElement({String type}) {
    InputElement e = document.createElement("input");
    if (type != null) {
      try {
        // IE throws an exception for unknown types.
        e.type = type;
      } catch(_) {}
    }
    return e;
  }

  // To suppress missing implicit constructor warnings.
  factory InputElement._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  InputElement.internal_() : super.internal_();

  /**
   * 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()
  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()
  set alt(String value) => _blink.BlinkHTMLInputElement.instance.alt_Setter_(this, value);
  
  @DomName('HTMLInputElement.autocapitalize')
  @DocsEditable()
  @Experimental() // untriaged
  String get autocapitalize => _blink.BlinkHTMLInputElement.instance.autocapitalize_Getter_(this);
  
  @DomName('HTMLInputElement.autocapitalize')
  @DocsEditable()
  @Experimental() // untriaged
  set autocapitalize(String value) => _blink.BlinkHTMLInputElement.instance.autocapitalize_Setter_(this, value);
  
  @DomName('HTMLInputElement.autocomplete')
  @DocsEditable()
  String get autocomplete => _blink.BlinkHTMLInputElement.instance.autocomplete_Getter_(this);
  
  @DomName('HTMLInputElement.autocomplete')
  @DocsEditable()
  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()
  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
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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
  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()
  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()
  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()
  set min(String value) => _blink.BlinkHTMLInputElement.instance.min_Setter_(this, value);
  
  @DomName('HTMLInputElement.minLength')
  @DocsEditable()
  @Experimental() // untriaged
  int get minLength => _blink.BlinkHTMLInputElement.instance.minLength_Getter_(this);
  
  @DomName('HTMLInputElement.minLength')
  @DocsEditable()
  @Experimental() // untriaged
  set minLength(int value) => _blink.BlinkHTMLInputElement.instance.minLength_Setter_(this, value);
  
  @DomName('HTMLInputElement.multiple')
  @DocsEditable()
  bool get multiple => _blink.BlinkHTMLInputElement.instance.multiple_Getter_(this);
  
  @DomName('HTMLInputElement.multiple')
  @DocsEditable()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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
  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()
  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.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() => _blink.BlinkHTMLInputElement.instance.reportValidity_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 ((end is int || end == null) && (start is int || start == null) && (replacement is String || replacement == null) && selectionMode == null) {
      _blink.BlinkHTMLInputElement.instance.setRangeText_Callback_3_(this, replacement, start, end);
      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.


@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;

  @DomName('KeyboardEvent.which')
  int get which => _which;

  @DomName('KeyboardEvent.KeyboardEvent')
  @DocsEditable()
  factory KeyboardEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkKeyboardEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkKeyboardEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  KeyboardEvent.internal_() : super.internal_();


  @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.code')
  @DocsEditable()
  @Experimental() // untriaged
  String get code => _blink.BlinkKeyboardEvent.instance.code_Getter_(this);
  
  @DomName('KeyboardEvent.ctrlKey')
  @DocsEditable()
  bool get ctrlKey => _blink.BlinkKeyboardEvent.instance.ctrlKey_Getter_(this);
  
  @DomName('KeyboardEvent.key')
  @DocsEditable()
  @Experimental() // untriaged
  String get key => _blink.BlinkKeyboardEvent.instance.key_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 keyArg) => _blink.BlinkKeyboardEvent.instance.getModifierState_Callback_1_(this, keyArg);
  
  @DomName('KeyboardEvent.initKeyboardEvent')
  @DocsEditable()
  void _initKeyboardEvent(String type, bool bubbles, bool cancelable, Window view, String keyIdentifier, int location, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey) => _blink.BlinkKeyboardEvent.instance.initKeyboardEvent_Callback_10_(this, type, bubbles, 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('KeyframeEffect')
@Experimental() // untriaged
class KeyframeEffect extends AnimationEffectReadOnly {
  // To suppress missing implicit constructor warnings.
  factory KeyframeEffect._() { throw new UnsupportedError("Not supported"); }

  @DomName('KeyframeEffect.KeyframeEffect')
  @DocsEditable()
  factory KeyframeEffect(Element target, List<Map> keyframes, [timing]) {
    if ((keyframes is List<Map>) && (target is Element || target == null) && timing == null) {
      return _blink.BlinkKeyframeEffect.instance.constructorCallback_2_(target, keyframes);
    }
    if ((timing is num) && (keyframes is List<Map>) && (target is Element || target == null)) {
      return _blink.BlinkKeyframeEffect.instance.constructorCallback_3_(target, keyframes, timing);
    }
    if ((timing is Map) && (keyframes is List<Map>) && (target is Element || target == null)) {
      var timing_1 = convertDartToNative_Dictionary(timing);
      return _blink.BlinkKeyframeEffect.instance.constructorCallback_3_(target, keyframes, timing_1);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  KeyframeEffect.internal_() : super.internal_();


}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  KeygenElement.internal_() : super.internal_();

  /**
   * 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()
  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()
  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()
  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()
  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()
  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.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() => _blink.BlinkHTMLKeygenElement.instance.reportValidity_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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  LIElement.internal_() : super.internal_();

  /**
   * 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()
  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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  LabelElement.internal_() : super.internal_();

  /**
   * 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()
  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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  LegendElement.internal_() : super.internal_();

  /**
   * 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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  LinkElement.internal_() : super.internal_();

  /**
   * 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
  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()
  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()
  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()
  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
  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()
  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()
  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()
  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) 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 DartHtmlDomObject implements LocationBase {
  // To suppress missing implicit constructor warnings.
  factory Location._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Location.internal_() { }

  @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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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.


@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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MapElement.internal_() : super.internal_();

  /**
   * 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()
  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_();
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MediaController.internal_() : super.internal_();


  @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()
  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()
  set defaultPlaybackRate(num value) => _blink.BlinkMediaController.instance.defaultPlaybackRate_Setter_(this, value);
  
  @DomName('MediaController.duration')
  @DocsEditable()
  num 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()
  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()
  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()
  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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory MediaDeviceInfo._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MediaDeviceInfo.internal_() { }

  @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.


@DocsEditable()
@DomName('MediaDevices')
@Experimental() // untriaged
class MediaDevices extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory MediaDevices._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MediaDevices.internal_() { }

  @DomName('MediaDevices.enumerateDevices')
  @DocsEditable()
  @Experimental() // untriaged
  Future enumerateDevices() => convertNativePromiseToDartFuture(_blink.BlinkMediaDevices.instance.enumerateDevices_Callback_0_(this));
  
  @DomName('MediaDevices.getUserMedia')
  @DocsEditable()
  @Experimental() // untriaged
  Future getUserMedia(Map options) => convertNativePromiseToDartFuture(_blink.BlinkMediaDevices.instance.getUserMedia_Callback_1_(this, convertDartToNative_Dictionary(options)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// 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');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MediaElement.internal_() : super.internal_();

  /**
   * 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()
  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()
  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()
  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
  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()
  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()
  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()
  set defaultPlaybackRate(num value) => _blink.BlinkHTMLMediaElement.instance.defaultPlaybackRate_Setter_(this, value);
  
  @DomName('HTMLMediaElement.duration')
  @DocsEditable()
  num 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.loop')
  @DocsEditable()
  bool get loop => _blink.BlinkHTMLMediaElement.instance.loop_Getter_(this);
  
  @DomName('HTMLMediaElement.loop')
  @DocsEditable()
  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()
  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()
  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()
  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()
  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.session')
  @DocsEditable()
  @Experimental() // untriaged
  MediaSession get session => _blink.BlinkHTMLMediaElement.instance.session_Getter_(this);
  
  @DomName('HTMLMediaElement.session')
  @DocsEditable()
  @Experimental() // untriaged
  set session(MediaSession value) => _blink.BlinkHTMLMediaElement.instance.session_Setter_(this, value);
  
  @DomName('HTMLMediaElement.sinkId')
  @DocsEditable()
  @Experimental() // untriaged
  String get sinkId => _blink.BlinkHTMLMediaElement.instance.sinkId_Getter_(this);
  
  @DomName('HTMLMediaElement.src')
  @DocsEditable()
  String get src => _blink.BlinkHTMLMediaElement.instance.src_Getter_(this);
  
  @DomName('HTMLMediaElement.src')
  @DocsEditable()
  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()
  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 ((type is String) && keySystem == null) {
      return _blink.BlinkHTMLMediaElement.instance.canPlayType_Callback_1_(this, type);
    }
    if ((type is String || type == null) && keySystem == null) {
      return _blink.BlinkHTMLMediaElement.instance.canPlayType_Callback_1_(this, type);
    }
    if ((keySystem is String || keySystem == null) && (type is String || type == null)) {
      return _blink.BlinkHTMLMediaElement.instance.canPlayType_Callback_2_(this, type, keySystem);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @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
  Future setMediaKeys(MediaKeys mediaKeys) => convertNativePromiseToDartFuture(_blink.BlinkHTMLMediaElement.instance.setMediaKeys_Callback_1_(this, mediaKeys));
  
  @DomName('HTMLMediaElement.setSinkId')
  @DocsEditable()
  @Experimental() // untriaged
  Future setSinkId(String sinkId) => convertNativePromiseToDartFuture(_blink.BlinkHTMLMediaElement.instance.setSinkId_Callback_1_(this, sinkId));
  
  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('MediaEncryptedEvent')
@Experimental() // untriaged
class MediaEncryptedEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MediaEncryptedEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaEncryptedEvent.MediaEncryptedEvent')
  @DocsEditable()
  factory MediaEncryptedEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkMediaEncryptedEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkMediaEncryptedEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MediaEncryptedEvent.internal_() : super.internal_();


  @DomName('MediaEncryptedEvent.initData')
  @DocsEditable()
  @Experimental() // untriaged
  ByteBuffer get initData => _blink.BlinkMediaEncryptedEvent.instance.initData_Getter_(this);
  
  @DomName('MediaEncryptedEvent.initDataType')
  @DocsEditable()
  @Experimental() // untriaged
  String get initDataType => _blink.BlinkMediaEncryptedEvent.instance.initDataType_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('MediaError')
@Unstable()
class MediaError extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory MediaError._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MediaError.internal_() { }

  @DomName('MediaError.MEDIA_ERR_ABORTED')
  @DocsEditable()
  static const int MEDIA_ERR_ABORTED = 1;

  @DomName('MediaError.MEDIA_ERR_DECODE')
  @DocsEditable()
  static const int MEDIA_ERR_DECODE = 3;

  @DomName('MediaError.MEDIA_ERR_NETWORK')
  @DocsEditable()
  static const int MEDIA_ERR_NETWORK = 2;

  @DomName('MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED')
  @DocsEditable()
  static const int MEDIA_ERR_SRC_NOT_SUPPORTED = 4;

  @DomName('MediaError.code')
  @DocsEditable()
  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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory MediaKeyError._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MediaKeyError.internal_() { }

  @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.MediaKeyEvent')
  @DocsEditable()
  factory MediaKeyEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkMediaKeyEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkMediaKeyEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MediaKeyEvent.internal_() : super.internal_();


  @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.MediaKeyMessageEvent')
  @DocsEditable()
  factory MediaKeyMessageEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkMediaKeyMessageEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkMediaKeyMessageEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MediaKeyMessageEvent.internal_() : super.internal_();


  @DomName('MediaKeyMessageEvent.message')
  @DocsEditable()
  ByteBuffer get message => _blink.BlinkMediaKeyMessageEvent.instance.message_Getter_(this);
  
  @DomName('MediaKeyMessageEvent.messageType')
  @DocsEditable()
  @Experimental() // untriaged
  String get messageType => _blink.BlinkMediaKeyMessageEvent.instance.messageType_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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MediaKeySession.internal_() : super.internal_();


  @DomName('MediaKeySession.closed')
  @DocsEditable()
  @Experimental() // untriaged
  Future get closed => convertNativePromiseToDartFuture(_blink.BlinkMediaKeySession.instance.closed_Getter_(this));
  
  @DomName('MediaKeySession.expiration')
  @DocsEditable()
  @Experimental() // untriaged
  num get expiration => _blink.BlinkMediaKeySession.instance.expiration_Getter_(this);
  
  @DomName('MediaKeySession.keyStatuses')
  @DocsEditable()
  @Experimental() // untriaged
  MediaKeyStatusMap get keyStatuses => _blink.BlinkMediaKeySession.instance.keyStatuses_Getter_(this);
  
  @DomName('MediaKeySession.sessionId')
  @DocsEditable()
  String get sessionId => _blink.BlinkMediaKeySession.instance.sessionId_Getter_(this);
  
  @DomName('MediaKeySession.close')
  @DocsEditable()
  Future close() => convertNativePromiseToDartFuture(_blink.BlinkMediaKeySession.instance.close_Callback_0_(this));
  
  @DomName('MediaKeySession.generateRequest')
  @DocsEditable()
  @Experimental() // untriaged
  Future generateRequest(String initDataType, /*BufferSource*/ initData) => convertNativePromiseToDartFuture(_blink.BlinkMediaKeySession.instance.generateRequest_Callback_2_(this, initDataType, initData));
  
  @DomName('MediaKeySession.load')
  @DocsEditable()
  @Experimental() // untriaged
  Future load(String sessionId) => convertNativePromiseToDartFuture(_blink.BlinkMediaKeySession.instance.load_Callback_1_(this, sessionId));
  
  @DomName('MediaKeySession.remove')
  @DocsEditable()
  @Experimental() // untriaged
  Future remove() => convertNativePromiseToDartFuture(_blink.BlinkMediaKeySession.instance.remove_Callback_0_(this));
  
  @DomName('MediaKeySession.update')
  @DocsEditable()
  Future _update(/*BufferSource*/ response) => convertNativePromiseToDartFuture(_blink.BlinkMediaKeySession.instance.update_Callback_1_(this, 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.


@DocsEditable()
@DomName('MediaKeyStatusMap')
@Experimental() // untriaged
class MediaKeyStatusMap extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory MediaKeyStatusMap._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MediaKeyStatusMap.internal_() { }

  @DomName('MediaKeyStatusMap.size')
  @DocsEditable()
  @Experimental() // untriaged
  int get size => _blink.BlinkMediaKeyStatusMap.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.


@DocsEditable()
@DomName('MediaKeySystemAccess')
@Experimental() // untriaged
class MediaKeySystemAccess extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory MediaKeySystemAccess._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MediaKeySystemAccess.internal_() { }

  @DomName('MediaKeySystemAccess.keySystem')
  @DocsEditable()
  @Experimental() // untriaged
  String get keySystem => _blink.BlinkMediaKeySystemAccess.instance.keySystem_Getter_(this);
  
  @DomName('MediaKeySystemAccess.createMediaKeys')
  @DocsEditable()
  @Experimental() // untriaged
  Future createMediaKeys() => convertNativePromiseToDartFuture(_blink.BlinkMediaKeySystemAccess.instance.createMediaKeys_Callback_0_(this));
  
  @DomName('MediaKeySystemAccess.getConfiguration')
  @DocsEditable()
  @Experimental() // untriaged
   getConfiguration() => convertNativeDictionaryToDartDictionary((_blink.BlinkMediaKeySystemAccess.instance.getConfiguration_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('MediaKeys')
// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html
@Experimental()
class MediaKeys extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory MediaKeys._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MediaKeys.internal_() { }

  MediaKeySession _createSession([String sessionType]) {
    if (sessionType != null) {
      return _blink.BlinkMediaKeys.instance.createSession_Callback_1_(this, sessionType);
    }
    return _blink.BlinkMediaKeys.instance.createSession_Callback_0_(this);
  }

  @DomName('MediaKeys.setServerCertificate')
  @DocsEditable()
  @Experimental() // untriaged
  Future setServerCertificate(/*BufferSource*/ serverCertificate) => convertNativePromiseToDartFuture(_blink.BlinkMediaKeys.instance.setServerCertificate_Callback_1_(this, serverCertificate));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory MediaList._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MediaList.internal_() { }

  @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()
  set mediaText(String value) => _blink.BlinkMediaList.instance.mediaText_Setter_(this, value);
  
  @DomName('MediaList.appendMedium')
  @DocsEditable()
  void appendMedium(String medium) => _blink.BlinkMediaList.instance.appendMedium_Callback_1_(this, medium);
  
  @DomName('MediaList.deleteMedium')
  @DocsEditable()
  void deleteMedium(String medium) => _blink.BlinkMediaList.instance.deleteMedium_Callback_1_(this, medium);
  
  @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 EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MediaQueryList._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaQueryList.changeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> changeEvent = const EventStreamProvider<Event>('change');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MediaQueryList.internal_() : super.internal_();


  @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);
  
  @DomName('MediaQueryList.addListener')
  @DocsEditable()
  void addListener(EventListener listener) => _blink.BlinkMediaQueryList.instance.addListener_Callback_1_(this, listener);
  
  @DomName('MediaQueryList.removeListener')
  @DocsEditable()
  void removeListener(EventListener listener) => _blink.BlinkMediaQueryList.instance.removeListener_Callback_1_(this, listener);
  
  @DomName('MediaQueryList.onchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onChange => changeEvent.forTarget(this);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('MediaQueryListEvent')
@Experimental() // untriaged
class MediaQueryListEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MediaQueryListEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaQueryListEvent.MediaQueryListEvent')
  @DocsEditable()
  factory MediaQueryListEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkMediaQueryListEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkMediaQueryListEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MediaQueryListEvent.internal_() : super.internal_();


  @DomName('MediaQueryListEvent.matches')
  @DocsEditable()
  @Experimental() // untriaged
  bool get matches => _blink.BlinkMediaQueryListEvent.instance.matches_Getter_(this);
  
  @DomName('MediaQueryListEvent.media')
  @DocsEditable()
  @Experimental() // untriaged
  String get media => _blink.BlinkMediaQueryListEvent.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('MediaSession')
@Experimental() // untriaged
class MediaSession extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory MediaSession._() { throw new UnsupportedError("Not supported"); }

  @DomName('MediaSession.MediaSession')
  @DocsEditable()
  factory MediaSession() {
    return _blink.BlinkMediaSession.instance.constructorCallback_0_();
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MediaSession.internal_() { }

  @DomName('MediaSession.activate')
  @DocsEditable()
  @Experimental() // untriaged
  void activate() => _blink.BlinkMediaSession.instance.activate_Callback_0_(this);
  
  @DomName('MediaSession.deactivate')
  @DocsEditable()
  @Experimental() // untriaged
  void deactivate() => _blink.BlinkMediaSession.instance.deactivate_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('MediaSource')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE, '11')
// https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#mediasource
@Experimental()
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_();
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MediaSource.internal_() : super.internal_();


  /// Checks if this type is supported on the current platform.
  static bool get supported => true;

  @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()
  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");
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MediaStream.internal_() : super.internal_();


  @DomName('MediaStream.active')
  @DocsEditable()
  @Experimental() // untriaged
  bool get active => _blink.BlinkMediaStream.instance.active_Getter_(this);
  
  @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"); }

  @DomName('MediaStreamEvent.MediaStreamEvent')
  @DocsEditable()
  factory MediaStreamEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkMediaStreamEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkMediaStreamEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MediaStreamEvent.internal_() : super.internal_();


  /// 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');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MediaStreamTrack.internal_() : super.internal_();


  @DomName('MediaStreamTrack.enabled')
  @DocsEditable()
  bool get enabled => _blink.BlinkMediaStreamTrack.instance.enabled_Getter_(this);
  
  @DomName('MediaStreamTrack.enabled')
  @DocsEditable()
  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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MediaStreamTrackEvent.internal_() : super.internal_();


  /// 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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory MemoryInfo._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MemoryInfo.internal_() { }

  @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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MenuElement.internal_() : super.internal_();

  /**
   * 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
  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
  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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MenuItemElement.internal_() : super.internal_();

  /**
   * 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
  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
  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
  set disabled(bool value) => _blink.BlinkHTMLMenuItemElement.instance.disabled_Setter_(this, value);
  
  @DomName('HTMLMenuItemElement.icon')
  @DocsEditable()
  @Experimental() // untriaged
  String get icon => _blink.BlinkHTMLMenuItemElement.instance.icon_Getter_(this);
  
  @DomName('HTMLMenuItemElement.icon')
  @DocsEditable()
  @Experimental() // untriaged
  set icon(String value) => _blink.BlinkHTMLMenuItemElement.instance.icon_Setter_(this, value);
  
  @DomName('HTMLMenuItemElement.label')
  @DocsEditable()
  @Experimental() // untriaged
  String get label => _blink.BlinkHTMLMenuItemElement.instance.label_Getter_(this);
  
  @DomName('HTMLMenuItemElement.label')
  @DocsEditable()
  @Experimental() // untriaged
  set label(String value) => _blink.BlinkHTMLMenuItemElement.instance.label_Setter_(this, value);
  
  @DomName('HTMLMenuItemElement.radiogroup')
  @DocsEditable()
  @Experimental() // untriaged
  String get radiogroup => _blink.BlinkHTMLMenuItemElement.instance.radiogroup_Getter_(this);
  
  @DomName('HTMLMenuItemElement.radiogroup')
  @DocsEditable()
  @Experimental() // untriaged
  set radiogroup(String value) => _blink.BlinkHTMLMenuItemElement.instance.radiogroup_Setter_(this, value);
  
  @DomName('HTMLMenuItemElement.type')
  @DocsEditable()
  @Experimental() // untriaged
  String get type => _blink.BlinkHTMLMenuItemElement.instance.type_Getter_(this);
  
  @DomName('HTMLMenuItemElement.type')
  @DocsEditable()
  @Experimental() // untriaged
  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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory MessageChannel._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MessageChannel.internal_() { }

  @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<MessagePort> messagePorts}) {
    if (source == null) {
      source = window;
    }
    MessageEvent event = document._createEvent("MessageEvent");
    event._initMessageEvent(type, canBubble, cancelable, data, origin,
        lastEventId, source, messagePorts);
    return event;
  }

  // TODO(alanknight): This really should be generated by the
  // _OutputConversion in the systemnative.py script, but that doesn't
  // use those conversions right now, so do this as a one-off.
  @DomName('MessageEvent.data')
  @DocsEditable()
  dynamic get data => convertNativeToDart_SerializedScriptValue(
      _blink.BlinkMessageEvent.instance.data_Getter_(this));



  @DomName('MessageEvent.MessageEvent')
  @DocsEditable()
  factory MessageEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkMessageEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkMessageEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MessageEvent.internal_() : super.internal_();


  @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 => _convertNativeToDart_EventTarget(_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> portsArg) => _blink.BlinkMessageEvent.instance.initMessageEvent_Callback_8_(this, typeArg, canBubbleArg, cancelableArg, dataArg, originArg, lastEventIdArg, sourceArg, portsArg);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MessagePort.internal_() : super.internal_();


  @DomName('MessagePort.close')
  @DocsEditable()
  void close() => _blink.BlinkMessagePort.instance.close_Callback_0_(this);
  
  void postMessage(Object message, [List<MessagePort> transfer]) {
    if (transfer != null) {
      _blink.BlinkMessagePort.instance.postMessage_Callback_2_(this, convertDartToNative_SerializedScriptValue(message), transfer);
      return;
    }
    _blink.BlinkMessagePort.instance.postMessage_Callback_1_(this, convertDartToNative_SerializedScriptValue(message));
    return;
  }

  @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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MetaElement.internal_() : super.internal_();

  /**
   * 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()
  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()
  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()
  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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory Metadata._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Metadata.internal_() { }

  @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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MeterElement.internal_() : super.internal_();

  /**
   * 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()
  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()
  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()
  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()
  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()
  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()
  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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MidiAccess.internal_() : super.internal_();


  @DomName('MIDIAccess.inputs')
  @DocsEditable()
  MidiInputMap get inputs => _blink.BlinkMIDIAccess.instance.inputs_Getter_(this);
  
  @DomName('MIDIAccess.outputs')
  @DocsEditable()
  MidiOutputMap get outputs => _blink.BlinkMIDIAccess.instance.outputs_Getter_(this);
  
  @DomName('MIDIAccess.sysexEnabled')
  @DocsEditable()
  @Experimental() // untriaged
  bool get sysexEnabled => _blink.BlinkMIDIAccess.instance.sysexEnabled_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('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.MIDIConnectionEvent')
  @DocsEditable()
  factory MidiConnectionEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkMIDIConnectionEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkMIDIConnectionEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MidiConnectionEvent.internal_() : super.internal_();


  @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');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MidiInput.internal_() : super.internal_();


  /// 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('MIDIInputMap')
@Experimental() // untriaged
class MidiInputMap extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory MidiInputMap._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MidiInputMap.internal_() { }

  @DomName('MIDIInputMap.size')
  @DocsEditable()
  @Experimental() // untriaged
  int get size => _blink.BlinkMIDIInputMap.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.


@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.MIDIMessageEvent')
  @DocsEditable()
  factory MidiMessageEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkMIDIMessageEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkMIDIMessageEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MidiMessageEvent.internal_() : super.internal_();


  @DomName('MIDIMessageEvent.data')
  @DocsEditable()
  Uint8List get data => _blink.BlinkMIDIMessageEvent.instance.data_Getter_(this);
  
  @DomName('MIDIMessageEvent.receivedTime')
  @DocsEditable()
  num 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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MidiOutput.internal_() : super.internal_();


  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('MIDIOutputMap')
@Experimental() // untriaged
class MidiOutputMap extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory MidiOutputMap._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MidiOutputMap.internal_() { }

  @DomName('MIDIOutputMap.size')
  @DocsEditable()
  @Experimental() // untriaged
  int get size => _blink.BlinkMIDIOutputMap.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.


@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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MidiPort.internal_() : super.internal_();


  @DomName('MIDIPort.connection')
  @DocsEditable()
  @Experimental() // untriaged
  String get connection => _blink.BlinkMIDIPort.instance.connection_Getter_(this);
  
  @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.state')
  @DocsEditable()
  @Experimental() // untriaged
  String get state => _blink.BlinkMIDIPort.instance.state_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);
  
  @DomName('MIDIPort.close')
  @DocsEditable()
  @Experimental() // untriaged
  Future close() => convertNativePromiseToDartFuture(_blink.BlinkMIDIPort.instance.close_Callback_0_(this));
  
  @DomName('MIDIPort.open')
  @DocsEditable()
  @Experimental() // untriaged
  Future open() => convertNativePromiseToDartFuture(_blink.BlinkMIDIPort.instance.open_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('MimeType')
@Experimental() // non-standard
class MimeType extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory MimeType._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MimeType.internal_() { }

  @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 DartHtmlDomObject with ListMixin<MimeType>, ImmutableListMixin<MimeType> implements List<MimeType> {
  // To suppress missing implicit constructor warnings.
  factory MimeTypeArray._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MimeTypeArray.internal_() { }

  @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 _nativeIndexedGetter(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.


  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.item')
  @DocsEditable()
  MimeType item(int index) => _blink.BlinkMimeTypeArray.instance.item_Callback_1_(this, index);
  
  MimeType namedItem(String name) {
    if ((name is String || name == null)) {
      return _blink.BlinkMimeTypeArray.instance.namedItem_Callback_1_(this, name);
    }
    if ((name is String || name == null)) {
      return _blink.BlinkMimeTypeArray.instance.namedItem_Callback_1_(this, name);
    }
    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('HTMLModElement')
@Unstable()
class ModElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory ModElement._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ModElement.internal_() : super.internal_();

  /**
   * 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()
  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()
  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;
  }

  @DomName('MouseEvent.MouseEvent')
  @DocsEditable()
  factory MouseEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkMouseEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkMouseEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MouseEvent.internal_() : super.internal_();


  @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.buttons')
  @DocsEditable()
  @Experimental() // untriaged
  int get buttons => _blink.BlinkMouseEvent.instance.buttons_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.layerX')
  @DocsEditable()
  @Experimental() // untriaged
  int get _layerX => _blink.BlinkMouseEvent.instance.layerX_Getter_(this);
  
  @DomName('MouseEvent.layerY')
  @DocsEditable()
  @Experimental() // untriaged
  int get _layerY => _blink.BlinkMouseEvent.instance.layerY_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.pageX')
  @DocsEditable()
  @Experimental() // untriaged
  int get _pageX => _blink.BlinkMouseEvent.instance.pageX_Getter_(this);
  
  @DomName('MouseEvent.pageY')
  @DocsEditable()
  @Experimental() // untriaged
  int get _pageY => _blink.BlinkMouseEvent.instance.pageY_Getter_(this);
  
  @DomName('MouseEvent.region')
  @DocsEditable()
  @Experimental() // untriaged
  String get region => _blink.BlinkMouseEvent.instance.region_Getter_(this);
  
  @DomName('MouseEvent.relatedTarget')
  @DocsEditable()
  EventTarget get relatedTarget => _convertNativeToDart_EventTarget(_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.which')
  @DocsEditable()
  @Experimental() // untriaged
  int get _which => _blink.BlinkMouseEvent.instance.which_Getter_(this);
  
  @DomName('MouseEvent.initMouseEvent')
  @DocsEditable()
  void _initMouseEvent(String type, bool bubbles, bool cancelable, Window view, int detail, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, int button, EventTarget relatedTarget) => _blink.BlinkMouseEvent.instance.initMouseEvent_Callback_15_(this, type, bubbles, cancelable, view, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, _convertDartToNative_EventTarget(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.FIREFOX)
  @Experimental()
  Point get movement => new Point(_movementX, _movementY);

  /**
   * The coordinates of the mouse pointer in target node coordinates.
   *
   * This value may vary between platforms if the target node moves
   * after the event has fired or if the element has CSS transforms affecting
   * it.
   */
  Point get offset => new Point(_offsetX, _offsetY);

  @DomName('MouseEvent.screenX')
  @DomName('MouseEvent.screenY')
  Point get screen => new Point(_screenX, _screenY);

  @DomName('MouseEvent.layerX')
  @DomName('MouseEvent.layerY')
  Point get layer => new Point(_layerX, _layerY);

  @DomName('MouseEvent.pageX')
  @DomName('MouseEvent.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.


@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 DartHtmlDomObject {

  @DomName('MutationObserver.MutationObserver')
  @DocsEditable()
  factory MutationObserver._(MutationCallback callback) => _create(callback);


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MutationObserver.internal_() { }

  @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, convertDartToNative_Dictionary(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;
  }
  @DocsEditable()
  static MutationObserver _create(callback) => _blink.BlinkMutationObserver.instance.constructorCallback_1_(callback);

  /**
   * 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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory MutationRecord._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  MutationRecord.internal_() { }

  @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 DartHtmlDomObject implements NavigatorStorageUtils, 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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Navigator.internal_() { }

  @DomName('Navigator.bluetooth')
  @DocsEditable()
  @Experimental() // untriaged
  Bluetooth get bluetooth => _blink.BlinkNavigator.instance.bluetooth_Getter_(this);
  
  @DomName('Navigator.connection')
  @DocsEditable()
  @Experimental() // untriaged
  NetworkInformation get connection => _blink.BlinkNavigator.instance.connection_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.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.mediaDevices')
  @DocsEditable()
  @Experimental() // untriaged
  MediaDevices get mediaDevices => _blink.BlinkNavigator.instance.mediaDevices_Getter_(this);
  
  @DomName('Navigator.mimeTypes')
  @DocsEditable()
  @Experimental() // nonstandard
  MimeTypeArray get mimeTypes => _blink.BlinkNavigator.instance.mimeTypes_Getter_(this);
  
  @DomName('Navigator.permissions')
  @DocsEditable()
  @Experimental() // untriaged
  Permissions get permissions => _blink.BlinkNavigator.instance.permissions_Getter_(this);
  
  @DomName('Navigator.presentation')
  @DocsEditable()
  @Experimental() // untriaged
  Presentation get presentation => _blink.BlinkNavigator.instance.presentation_Getter_(this);
  
  @DomName('Navigator.productSub')
  @DocsEditable()
  @Unstable()
  String get productSub => _blink.BlinkNavigator.instance.productSub_Getter_(this);
  
  @DomName('Navigator.serviceWorker')
  @DocsEditable()
  @Experimental() // untriaged
  ServiceWorkerContainer get serviceWorker => _blink.BlinkNavigator.instance.serviceWorker_Getter_(this);
  
  @DomName('Navigator.services')
  @DocsEditable()
  @Experimental() // untriaged
  ServicePortCollection get services => _blink.BlinkNavigator.instance.services_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() => convertNativePromiseToDartFuture(_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.getVRDevices')
  @DocsEditable()
  @Experimental() // untriaged
  Future getVRDevices() => convertNativePromiseToDartFuture(_blink.BlinkNavigator.instance.getVRDevices_Callback_0_(this));
  
  @DomName('Navigator.registerProtocolHandler')
  @DocsEditable()
  @Unstable()
  void registerProtocolHandler(String scheme, String url, String title) => _blink.BlinkNavigator.instance.registerProtocolHandler_Callback_3_(this, scheme, url, title);
  
  Future requestMidiAccess([Map options]) {
    if (options != null) {
      return _blink.BlinkNavigator.instance.requestMIDIAccess_Callback_1_(this, convertDartToNative_Dictionary(options));
    }
    return _blink.BlinkNavigator.instance.requestMIDIAccess_Callback_0_(this);
  }

  @DomName('Navigator.requestMediaKeySystemAccess')
  @DocsEditable()
  @Experimental() // untriaged
  Future requestMediaKeySystemAccess(String keySystem, List<Map> supportedConfigurations) => convertNativePromiseToDartFuture(_blink.BlinkNavigator.instance.requestMediaKeySystemAccess_Callback_2_(this, keySystem, supportedConfigurations));
  
  @DomName('Navigator.sendBeacon')
  @DocsEditable()
  @Experimental() // untriaged
  bool sendBeacon(String url, Object data) => _blink.BlinkNavigator.instance.sendBeacon_Callback_2_(this, url, data);
  
  @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, convertDartToNative_Dictionary(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);
  
  @DomName('Navigator.cookieEnabled')
  @DocsEditable()
  @Unstable()
  bool get cookieEnabled => _blink.BlinkNavigator.instance.cookieEnabled_Getter_(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);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 DartHtmlDomObject {
  // 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 DartHtmlDomObject {
  // 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 DartHtmlDomObject {
  // 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 DartHtmlDomObject {
  // 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('NavigatorStorageUtils')
@Experimental() // untriaged
class NavigatorStorageUtils extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory NavigatorStorageUtils._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  NavigatorStorageUtils.internal_() { }

  @DomName('NavigatorStorageUtils.cookieEnabled')
  @DocsEditable()
  @Experimental() // untriaged
  bool get cookieEnabled => _blink.BlinkNavigatorStorageUtils.instance.cookieEnabled_Getter_(this);
  
  @DomName('NavigatorStorageUtils.getStorageUpdates')
  @DocsEditable()
  @Experimental() // untriaged
  void getStorageUpdates() => _blink.BlinkNavigatorStorageUtils.instance.getStorageUpdates_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('NavigatorUserMediaError')
// http://dev.w3.org/2011/webrtc/editor/getusermedia.html#idl-def-NavigatorUserMediaError
@Experimental()
class NavigatorUserMediaError extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory NavigatorUserMediaError._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  NavigatorUserMediaError.internal_() { }

  @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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  NetworkInformation.internal_() : super.internal_();


  @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;
    // We aren't preserving identity of nodes in JSINTEROP mode
    if (_this != node.parentNode) return false;
    _this._removeChild(node);
    return true;
  }

  void _filter(bool test(Node node), bool removeMatching) {
    // This implementation of removeWhere/retainWhere is more efficient
    // than the default in ListBase. Child nodes can be removed in constant
    // time.
    Node child = _this.firstChild;
    while (child != null) {
      Node nextChild = child.nextNode;
      if (test(child) == removeMatching) {
        _this._removeChild(child);
      }
      child = nextChild;
    }
  }

  void removeWhere(bool test(Node node)) {
    _filter(test, true);
  }

  void retainWhere(bool test(Node node)) {
    _filter(test, false);
  }

  void clear() {
    _this._clearChildren();
  }

  void operator []=(int index, Node value) {
    _this._replaceChild(value, this[index]);
  }

  Iterator<Node> get iterator => _this.childNodes.iterator;

  // From List<Node>:

  // TODO(jacobr): this could be implemented for child node lists.
  // The exception we throw here is misleading.
  void sort([Comparator<Node> compare]) {
    throw new UnsupportedError("Cannot sort Node list");
  }

  void shuffle([Random random]) {
    throw new UnsupportedError("Cannot shuffle Node list");
  }

  // FIXME: implement these.
  void setRange(int start, int end, Iterable<Node> iterable,
                [int skipCount = 0]) {
    throw new UnsupportedError("Cannot setRange on Node list");
  }

  void fillRange(int start, int end, [Node fill]) {
    throw new UnsupportedError("Cannot fillRange on Node list");
  }
  // -- end List<Node> mixins.

  // TODO(jacobr): benchmark whether this is more efficient or whether caching
  // a local copy of childNodes is more efficient.
  int get length => _this.childNodes.length;

  set length(int value) {
    throw new UnsupportedError(
        "Cannot set length on immutable List.");
  }

  Node operator[](int index) => _this.childNodes[index];

  List<Node> get rawList => _this.childNodes;
}


@DomName('Node')
class Node extends EventTarget {

  // Custom element created callback.
  Node._created() : super._created();

  /**
   * A modifiable list of this node's children.
   */
  List<Node> get nodes {
    return new _ChildNodeListLazy(this);
  }

  set nodes(Iterable<Node> value) {
    // Copy list first since we don't want liveness during iteration.
    // TODO(jacobr): there is a better way to do this.
    var copy = value.toList();
    text = '';
    for (Node node in copy) {
      append(node);
    }
  }

  /**
   * Removes this node from the DOM.
   */
  @DomName('Node.removeChild')
  void remove() {
    // TODO(jacobr): should we throw an exception if parent is already null?
    // TODO(vsm): Use the native remove when available.
    if (this.parentNode != null) {
      final Node parent = this.parentNode;
      parentNode._removeChild(this);
    }
  }

  /**
   * Replaces this node with another node.
   */
  @DomName('Node.replaceChild')
  Node replaceWith(Node otherNode) {
    try {
      final Node parent = this.parentNode;
      parent._replaceChild(otherNode, this);
    } catch (e) {

    };
    return this;
  }

  /**
   * Inserts all of the nodes into this node directly before refChild.
   *
   * See also:
   *
   * * [insertBefore]
   */
  Node insertAllBefore(Iterable<Node> newNodes, Node refChild) {
    if (newNodes is _ChildNodeListLazy) {
      _ChildNodeListLazy otherList = newNodes;
      if (identical(otherList._this, this)) {
        throw new ArgumentError(newNodes);
      }

      // Optimized route for copying between nodes.
      for (var i = 0, len = otherList.length; i < len; ++i) {
        this.insertBefore(otherList._this.firstChild, refChild);
      }
    } else {
      for (var node in newNodes) {
        this.insertBefore(node, refChild);
      }
    }
  }

  void _clearChildren() {
    while (firstChild != null) {
      _removeChild(firstChild);
    }
  }

  /**
   * Print out a String representation of this Node.
   */
  String toString() {
    String value = nodeValue;  // Fetch DOM Node property once.
    return value == null ? super.toString() : value;
  }

  /**
   * A list of this node's children.
   *
   * ## Other resources
   *
   * * [Node.childNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)
   *   from MDN.
   */
  @DomName('Node.childNodes')
  @DocsEditable()
  List<Node> get childNodes => _blink.BlinkNode.instance.childNodes_Getter_(this);
  // To suppress missing implicit constructor warnings.
  factory Node._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Node.internal_() : super.internal_();


  @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);
  
  /**
   * 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()
  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 node) => _blink.BlinkNode.instance.appendChild_Callback_1_(this, node);
  
  /**
   * 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 node, Node child) => _blink.BlinkNode.instance.insertBefore_Callback_2_(this, node, child);
  
  @DomName('Node.removeChild')
  @DocsEditable()
  Node _removeChild(Node child) => _blink.BlinkNode.instance.removeChild_Callback_1_(this, child);
  
  @DomName('Node.replaceChild')
  @DocsEditable()
  Node _replaceChild(Node node, Node child) => _blink.BlinkNode.instance.replaceChild_Callback_2_(this, node, child);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory NodeFilter._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  NodeFilter.internal_() { }

  @DomName('NodeFilter.FILTER_ACCEPT')
  @DocsEditable()
  static const int FILTER_ACCEPT = 1;

  @DomName('NodeFilter.FILTER_REJECT')
  @DocsEditable()
  static const int FILTER_REJECT = 2;

  @DomName('NodeFilter.FILTER_SKIP')
  @DocsEditable()
  static const int FILTER_SKIP = 3;

  @DomName('NodeFilter.SHOW_ALL')
  @DocsEditable()
  static const int SHOW_ALL = 0xFFFFFFFF;

  @DomName('NodeFilter.SHOW_COMMENT')
  @DocsEditable()
  static const int SHOW_COMMENT = 0x80;

  @DomName('NodeFilter.SHOW_DOCUMENT')
  @DocsEditable()
  static const int SHOW_DOCUMENT = 0x100;

  @DomName('NodeFilter.SHOW_DOCUMENT_FRAGMENT')
  @DocsEditable()
  static const int SHOW_DOCUMENT_FRAGMENT = 0x400;

  @DomName('NodeFilter.SHOW_DOCUMENT_TYPE')
  @DocsEditable()
  static const int SHOW_DOCUMENT_TYPE = 0x200;

  @DomName('NodeFilter.SHOW_ELEMENT')
  @DocsEditable()
  static const int SHOW_ELEMENT = 0x1;

  @DomName('NodeFilter.SHOW_PROCESSING_INSTRUCTION')
  @DocsEditable()
  static const int SHOW_PROCESSING_INSTRUCTION = 0x40;

  @DomName('NodeFilter.SHOW_TEXT')
  @DocsEditable()
  static const int SHOW_TEXT = 0x4;

}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('NodeIterator')
@Unstable()
class NodeIterator extends DartHtmlDomObject {
  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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  NodeIterator.internal_() { }

  @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 DartHtmlDomObject with ListMixin<Node>, ImmutableListMixin<Node> implements List<Node> {
  // To suppress missing implicit constructor warnings.
  factory NodeList._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  NodeList.internal_() { }

  @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 _nativeIndexedGetter(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.


  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) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('NonDocumentTypeChildNode')
@Experimental() // untriaged
class NonDocumentTypeChildNode extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory NonDocumentTypeChildNode._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  NonDocumentTypeChildNode.internal_() { }

  @DomName('NonDocumentTypeChildNode.nextElementSibling')
  @DocsEditable()
  @Experimental() // untriaged
  Element get nextElementSibling => _blink.BlinkNonDocumentTypeChildNode.instance.nextElementSibling_Getter_(this);
  
  @DomName('NonDocumentTypeChildNode.previousElementSibling')
  @DocsEditable()
  @Experimental() // untriaged
  Element get previousElementSibling => _blink.BlinkNonDocumentTypeChildNode.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('NonElementParentNode')
@Experimental() // untriaged
class NonElementParentNode extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory NonElementParentNode._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  NonElementParentNode.internal_() { }

  @DomName('NonElementParentNode.getElementById')
  @DocsEditable()
  @Experimental() // untriaged
  Element getElementById(String elementId) => _blink.BlinkNonElementParentNode.instance.getElementById_Callback_1_(this, elementId);
  
}
// 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 dir: null, String body: null,
      String lang: null, String tag: null, String icon: null}) {

    var parsedOptions = {};
    if (dir != null) parsedOptions['dir'] = dir;
    if (body != null) parsedOptions['body'] = body;
    if (lang != null) parsedOptions['lang'] = lang;
    if (tag != null) parsedOptions['tag'] = tag;
    if (icon != null) parsedOptions['icon'] = icon;
    return Notification._factoryNotification(title, parsedOptions);
  }
  // To suppress missing implicit constructor warnings.
  factory Notification._() { throw new UnsupportedError("Not supported"); }

  /**
   * Static factory designed to expose `click` events to event
   * handlers that are not necessarily instances of [Notification].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Notification.clickEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> clickEvent = const EventStreamProvider<Event>('click');

  /**
   * Static factory designed to expose `close` events to event
   * handlers that are not necessarily instances of [Notification].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Notification.closeEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> closeEvent = const EventStreamProvider<Event>('close');

  /**
   * Static factory designed to expose `error` events to event
   * handlers that are not necessarily instances of [Notification].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Notification.errorEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');

  /**
   * Static factory designed to expose `show` events to event
   * handlers that are not necessarily instances of [Notification].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Notification.showEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> showEvent = const EventStreamProvider<Event>('show');

  @DomName('Notification.Notification')
  @DocsEditable()
  static Notification _factoryNotification(String title, [Map options]) {
    if (options != null) {
      var options_1 = convertDartToNative_Dictionary(options);
      return _blink.BlinkNotification.instance.constructorCallback_2_(title, options_1);
    }
    return _blink.BlinkNotification.instance.constructorCallback_1_(title);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Notification.internal_() : super.internal_();


  /// Checks if this type is supported on the current platform.
  static bool get supported => true;

  @DomName('Notification.body')
  @DocsEditable()
  @Experimental() // untriaged
  String get body => _blink.BlinkNotification.instance.body_Getter_(this);
  
  @DomName('Notification.data')
  @DocsEditable()
  @Experimental() // untriaged
  Object get data => (_blink.BlinkNotification.instance.data_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.silent')
  @DocsEditable()
  @Experimental() // untriaged
  bool get silent => _blink.BlinkNotification.instance.silent_Getter_(this);
  
  @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.vibrate')
  @DocsEditable()
  @Experimental() // untriaged
  List<int> get vibrate => _blink.BlinkNotification.instance.vibrate_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.


@DocsEditable()
@DomName('NotificationEvent')
@Experimental() // untriaged
class NotificationEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory NotificationEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('NotificationEvent.NotificationEvent')
  @DocsEditable()
  factory NotificationEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkNotificationEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkNotificationEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  NotificationEvent.internal_() : super.internal_();


  @DomName('NotificationEvent.notification')
  @DocsEditable()
  @Experimental() // untriaged
  Notification get notification => _blink.BlinkNotificationEvent.instance.notification_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('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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  OListElement.internal_() : super.internal_();

  /**
   * 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()
  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()
  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()
  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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ObjectElement.internal_() : super.internal_();

  /**
   * 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()
  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()
  set height(String value) => _blink.BlinkHTMLObjectElement.instance.height_Setter_(this, value);
  
  @DomName('HTMLObjectElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLObjectElement.instance.name_Getter_(this);
  
  @DomName('HTMLObjectElement.name')
  @DocsEditable()
  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()
  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()
  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()
  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.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() => _blink.BlinkHTMLObjectElement.instance.reportValidity_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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  OptGroupElement.internal_() : super.internal_();

  /**
   * 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()
  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()
  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]) {
    if (selected != null) {
      return _blink.BlinkHTMLOptionElement.instance.constructorCallback_4_(data, value, defaultSelected, selected);
    }
    if (defaultSelected != null) {
      return _blink.BlinkHTMLOptionElement.instance.constructorCallback_3_(data, value, defaultSelected);
    }
    return _blink.BlinkHTMLOptionElement.instance.constructorCallback_2_(data, value);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  OptionElement.internal_() : super.internal_();

  /**
   * 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()
  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()
  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()
  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()
  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()
  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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  OutputElement.internal_() : super.internal_();

  /**
   * 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()
  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()
  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()
  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.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() => _blink.BlinkHTMLOutputElement.instance.reportValidity_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('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.PageTransitionEvent')
  @DocsEditable()
  factory PageTransitionEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkPageTransitionEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkPageTransitionEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PageTransitionEvent.internal_() : super.internal_();


  @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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ParagraphElement.internal_() : super.internal_();

  /**
   * 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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ParamElement.internal_() : super.internal_();

  /**
   * 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()
  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()
  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 DartHtmlDomObject {
  // 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('PasswordCredential')
@Experimental() // untriaged
class PasswordCredential extends Credential {
  // To suppress missing implicit constructor warnings.
  factory PasswordCredential._() { throw new UnsupportedError("Not supported"); }

  @DomName('PasswordCredential.PasswordCredential')
  @DocsEditable()
  factory PasswordCredential(String id, String password, [String name, String iconURL]) {
    if (iconURL != null) {
      return _blink.BlinkPasswordCredential.instance.constructorCallback_4_(id, password, name, iconURL);
    }
    if (name != null) {
      return _blink.BlinkPasswordCredential.instance.constructorCallback_3_(id, password, name);
    }
    return _blink.BlinkPasswordCredential.instance.constructorCallback_2_(id, password);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PasswordCredential.internal_() : super.internal_();


  @DomName('PasswordCredential.formData')
  @DocsEditable()
  @Experimental() // untriaged
  FormData get formData => _blink.BlinkPasswordCredential.instance.formData_Getter_(this);
  
  @DomName('PasswordCredential.password')
  @DocsEditable()
  @Experimental() // untriaged
  String get password => _blink.BlinkPasswordCredential.instance.password_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('Path2D')
@Experimental() // untriaged
class Path2D extends DartHtmlDomObject 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");
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Path2D.internal_() { }

  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');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Performance.internal_() : super.internal_();


  /// 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.clearFrameTimings')
  @DocsEditable()
  @Experimental() // untriaged
  void clearFrameTimings() => _blink.BlinkPerformance.instance.clearFrameTimings_Callback_0_(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()
  num now() => _blink.BlinkPerformance.instance.now_Callback_0_(this);
  
  @DomName('Performance.setFrameTimingBufferSize')
  @DocsEditable()
  @Experimental() // untriaged
  void setFrameTimingBufferSize(int maxSize) => _blink.BlinkPerformance.instance.setFrameTimingBufferSize_Callback_1_(this, maxSize);
  
  @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('PerformanceCompositeTiming')
@Experimental() // untriaged
class PerformanceCompositeTiming extends PerformanceEntry {
  // To suppress missing implicit constructor warnings.
  factory PerformanceCompositeTiming._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PerformanceCompositeTiming.internal_() : super.internal_();


  @DomName('PerformanceCompositeTiming.sourceFrame')
  @DocsEditable()
  @Experimental() // untriaged
  int get sourceFrame => _blink.BlinkPerformanceCompositeTiming.instance.sourceFrame_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('PerformanceEntry')
// http://www.w3.org/TR/performance-timeline/#sec-PerformanceEntry-interface
@Experimental()
class PerformanceEntry extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory PerformanceEntry._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PerformanceEntry.internal_() { }

  @DomName('PerformanceEntry.duration')
  @DocsEditable()
  num 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()
  num 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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PerformanceMark.internal_() : super.internal_();


}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PerformanceMeasure.internal_() : super.internal_();


}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory PerformanceNavigation._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PerformanceNavigation.internal_() { }

  @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('PerformanceRenderTiming')
@Experimental() // untriaged
class PerformanceRenderTiming extends PerformanceEntry {
  // To suppress missing implicit constructor warnings.
  factory PerformanceRenderTiming._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PerformanceRenderTiming.internal_() : super.internal_();


  @DomName('PerformanceRenderTiming.sourceFrame')
  @DocsEditable()
  @Experimental() // untriaged
  int get sourceFrame => _blink.BlinkPerformanceRenderTiming.instance.sourceFrame_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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PerformanceResourceTiming.internal_() : super.internal_();


  @DomName('PerformanceResourceTiming.connectEnd')
  @DocsEditable()
  num get connectEnd => _blink.BlinkPerformanceResourceTiming.instance.connectEnd_Getter_(this);
  
  @DomName('PerformanceResourceTiming.connectStart')
  @DocsEditable()
  num get connectStart => _blink.BlinkPerformanceResourceTiming.instance.connectStart_Getter_(this);
  
  @DomName('PerformanceResourceTiming.domainLookupEnd')
  @DocsEditable()
  num get domainLookupEnd => _blink.BlinkPerformanceResourceTiming.instance.domainLookupEnd_Getter_(this);
  
  @DomName('PerformanceResourceTiming.domainLookupStart')
  @DocsEditable()
  num get domainLookupStart => _blink.BlinkPerformanceResourceTiming.instance.domainLookupStart_Getter_(this);
  
  @DomName('PerformanceResourceTiming.fetchStart')
  @DocsEditable()
  num 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()
  num get redirectEnd => _blink.BlinkPerformanceResourceTiming.instance.redirectEnd_Getter_(this);
  
  @DomName('PerformanceResourceTiming.redirectStart')
  @DocsEditable()
  num get redirectStart => _blink.BlinkPerformanceResourceTiming.instance.redirectStart_Getter_(this);
  
  @DomName('PerformanceResourceTiming.requestStart')
  @DocsEditable()
  @Experimental() // nonstandard
  num get requestStart => _blink.BlinkPerformanceResourceTiming.instance.requestStart_Getter_(this);
  
  @DomName('PerformanceResourceTiming.responseEnd')
  @DocsEditable()
  @Experimental() // nonstandard
  num get responseEnd => _blink.BlinkPerformanceResourceTiming.instance.responseEnd_Getter_(this);
  
  @DomName('PerformanceResourceTiming.responseStart')
  @DocsEditable()
  @Experimental() // nonstandard
  num get responseStart => _blink.BlinkPerformanceResourceTiming.instance.responseStart_Getter_(this);
  
  @DomName('PerformanceResourceTiming.secureConnectionStart')
  @DocsEditable()
  num get secureConnectionStart => _blink.BlinkPerformanceResourceTiming.instance.secureConnectionStart_Getter_(this);
  
  @DomName('PerformanceResourceTiming.workerStart')
  @DocsEditable()
  @Experimental() // untriaged
  num get workerStart => _blink.BlinkPerformanceResourceTiming.instance.workerStart_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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory PerformanceTiming._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PerformanceTiming.internal_() { }

  @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('PeriodicSyncEvent')
@Experimental() // untriaged
class PeriodicSyncEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory PeriodicSyncEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('PeriodicSyncEvent.PeriodicSyncEvent')
  @DocsEditable()
  factory PeriodicSyncEvent(String type, Map init) {
    var init_1 = convertDartToNative_Dictionary(init);
    return _blink.BlinkPeriodicSyncEvent.instance.constructorCallback_2_(type, init_1);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PeriodicSyncEvent.internal_() : super.internal_();


  @DomName('PeriodicSyncEvent.registration')
  @DocsEditable()
  @Experimental() // untriaged
  PeriodicSyncRegistration get registration => _blink.BlinkPeriodicSyncEvent.instance.registration_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('PeriodicSyncManager')
@Experimental() // untriaged
class PeriodicSyncManager extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory PeriodicSyncManager._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PeriodicSyncManager.internal_() { }

  @DomName('PeriodicSyncManager.minPossiblePeriod')
  @DocsEditable()
  @Experimental() // untriaged
  int get minPossiblePeriod => _blink.BlinkPeriodicSyncManager.instance.minPossiblePeriod_Getter_(this);
  
  @DomName('PeriodicSyncManager.getRegistration')
  @DocsEditable()
  @Experimental() // untriaged
  Future getRegistration(String tag) => convertNativePromiseToDartFuture(_blink.BlinkPeriodicSyncManager.instance.getRegistration_Callback_1_(this, tag));
  
  @DomName('PeriodicSyncManager.getRegistrations')
  @DocsEditable()
  @Experimental() // untriaged
  Future getRegistrations() => convertNativePromiseToDartFuture(_blink.BlinkPeriodicSyncManager.instance.getRegistrations_Callback_0_(this));
  
  @DomName('PeriodicSyncManager.permissionState')
  @DocsEditable()
  @Experimental() // untriaged
  Future permissionState() => convertNativePromiseToDartFuture(_blink.BlinkPeriodicSyncManager.instance.permissionState_Callback_0_(this));
  
  Future register([Map options]) {
    if (options != null) {
      return _blink.BlinkPeriodicSyncManager.instance.register_Callback_1_(this, convertDartToNative_Dictionary(options));
    }
    return _blink.BlinkPeriodicSyncManager.instance.register_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('PeriodicSyncRegistration')
@Experimental() // untriaged
class PeriodicSyncRegistration extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory PeriodicSyncRegistration._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PeriodicSyncRegistration.internal_() { }

  @DomName('PeriodicSyncRegistration.minPeriod')
  @DocsEditable()
  @Experimental() // untriaged
  int get minPeriod => _blink.BlinkPeriodicSyncRegistration.instance.minPeriod_Getter_(this);
  
  @DomName('PeriodicSyncRegistration.networkState')
  @DocsEditable()
  @Experimental() // untriaged
  String get networkState => _blink.BlinkPeriodicSyncRegistration.instance.networkState_Getter_(this);
  
  @DomName('PeriodicSyncRegistration.powerState')
  @DocsEditable()
  @Experimental() // untriaged
  String get powerState => _blink.BlinkPeriodicSyncRegistration.instance.powerState_Getter_(this);
  
  @DomName('PeriodicSyncRegistration.tag')
  @DocsEditable()
  @Experimental() // untriaged
  String get tag => _blink.BlinkPeriodicSyncRegistration.instance.tag_Getter_(this);
  
  @DomName('PeriodicSyncRegistration.unregister')
  @DocsEditable()
  @Experimental() // untriaged
  Future unregister() => convertNativePromiseToDartFuture(_blink.BlinkPeriodicSyncRegistration.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('PermissionStatus')
@Experimental() // untriaged
class PermissionStatus extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory PermissionStatus._() { throw new UnsupportedError("Not supported"); }

  @DomName('PermissionStatus.changeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> changeEvent = const EventStreamProvider<Event>('change');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PermissionStatus.internal_() : super.internal_();


  @DomName('PermissionStatus.state')
  @DocsEditable()
  @Experimental() // untriaged
  String get state => _blink.BlinkPermissionStatus.instance.state_Getter_(this);
  
  @DomName('PermissionStatus.status')
  @DocsEditable()
  @Experimental() // untriaged
  String get status => _blink.BlinkPermissionStatus.instance.status_Getter_(this);
  
  @DomName('PermissionStatus.onchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onChange => changeEvent.forTarget(this);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('Permissions')
@Experimental() // untriaged
class Permissions extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory Permissions._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Permissions.internal_() { }

  @DomName('Permissions.query')
  @DocsEditable()
  @Experimental() // untriaged
  Future query(Object permission) => convertNativePromiseToDartFuture(_blink.BlinkPermissions.instance.query_Callback_1_(this, 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('HTMLPictureElement')
@Experimental() // untriaged
class PictureElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory PictureElement._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PictureElement.internal_() : super.internal_();

  /**
   * 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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory Plugin._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Plugin.internal_() { }

  @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.item')
  @DocsEditable()
  MimeType item(int index) => _blink.BlinkPlugin.instance.item_Callback_1_(this, index);
  
  MimeType namedItem(String name) {
    if ((name is String || name == null)) {
      return _blink.BlinkPlugin.instance.namedItem_Callback_1_(this, name);
    }
    if ((name is String || name == null)) {
      return _blink.BlinkPlugin.instance.namedItem_Callback_1_(this, name);
    }
    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('PluginArray')
@Experimental() // non-standard
class PluginArray extends DartHtmlDomObject with ListMixin<Plugin>, ImmutableListMixin<Plugin> implements List<Plugin> {
  // To suppress missing implicit constructor warnings.
  factory PluginArray._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PluginArray.internal_() { }

  @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 _nativeIndexedGetter(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.


  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.item')
  @DocsEditable()
  Plugin item(int index) => _blink.BlinkPluginArray.instance.item_Callback_1_(this, index);
  
  Plugin namedItem(String name) {
    if ((name is String || name == null)) {
      return _blink.BlinkPluginArray.instance.namedItem_Callback_1_(this, name);
    }
    if ((name is String || name == null)) {
      return _blink.BlinkPluginArray.instance.namedItem_Callback_1_(this, name);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @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('PluginPlaceholderElement')
@Experimental() // untriaged
class PluginPlaceholderElement extends DivElement {
  // To suppress missing implicit constructor warnings.
  factory PluginPlaceholderElement._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PluginPlaceholderElement.internal_() : super.internal_();

  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  PluginPlaceholderElement.created() : super.created();

  @DomName('PluginPlaceholderElement.closeable')
  @DocsEditable()
  @Experimental() // untriaged
  bool get closeable => _blink.BlinkPluginPlaceholderElement.instance.closeable_Getter_(this);
  
  @DomName('PluginPlaceholderElement.closeable')
  @DocsEditable()
  @Experimental() // untriaged
  set closeable(bool value) => _blink.BlinkPluginPlaceholderElement.instance.closeable_Setter_(this, value);
  
  @DomName('PluginPlaceholderElement.message')
  @DocsEditable()
  @Experimental() // untriaged
  String get message => _blink.BlinkPluginPlaceholderElement.instance.message_Getter_(this);
  
  @DomName('PluginPlaceholderElement.message')
  @DocsEditable()
  @Experimental() // untriaged
  set message(String value) => _blink.BlinkPluginPlaceholderElement.instance.message_Setter_(this, value);
  
  @DomName('PluginPlaceholderElement.createdCallback')
  @DocsEditable()
  @Experimental() // untriaged
  void createdCallback() => _blink.BlinkPluginPlaceholderElement.instance.createdCallback_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('PointerEvent')
@Experimental() // untriaged
class PointerEvent extends MouseEvent {
  // To suppress missing implicit constructor warnings.
  factory PointerEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('PointerEvent.PointerEvent')
  @DocsEditable()
  factory PointerEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkPointerEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkPointerEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PointerEvent.internal_() : super.internal_();


  @DomName('PointerEvent.height')
  @DocsEditable()
  @Experimental() // untriaged
  num get height => _blink.BlinkPointerEvent.instance.height_Getter_(this);
  
  @DomName('PointerEvent.isPrimary')
  @DocsEditable()
  @Experimental() // untriaged
  bool get isPrimary => _blink.BlinkPointerEvent.instance.isPrimary_Getter_(this);
  
  @DomName('PointerEvent.pointerId')
  @DocsEditable()
  @Experimental() // untriaged
  int get pointerId => _blink.BlinkPointerEvent.instance.pointerId_Getter_(this);
  
  @DomName('PointerEvent.pointerType')
  @DocsEditable()
  @Experimental() // untriaged
  String get pointerType => _blink.BlinkPointerEvent.instance.pointerType_Getter_(this);
  
  @DomName('PointerEvent.pressure')
  @DocsEditable()
  @Experimental() // untriaged
  num get pressure => _blink.BlinkPointerEvent.instance.pressure_Getter_(this);
  
  @DomName('PointerEvent.tiltX')
  @DocsEditable()
  @Experimental() // untriaged
  int get tiltX => _blink.BlinkPointerEvent.instance.tiltX_Getter_(this);
  
  @DomName('PointerEvent.tiltY')
  @DocsEditable()
  @Experimental() // untriaged
  int get tiltY => _blink.BlinkPointerEvent.instance.tiltY_Getter_(this);
  
  @DomName('PointerEvent.width')
  @DocsEditable()
  @Experimental() // untriaged
  num get width => _blink.BlinkPointerEvent.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('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.PopStateEvent')
  @DocsEditable()
  factory PopStateEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkPopStateEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkPopStateEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PopStateEvent.internal_() : super.internal_();


  @DomName('PopStateEvent.state')
  @DocsEditable()
  Object get state => convertNativeToDart_SerializedScriptValue(_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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory PositionError._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PositionError.internal_() { }

  @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('PositionSensorVRDevice')
@Experimental() // untriaged
class PositionSensorVRDevice extends VRDevice {
  // To suppress missing implicit constructor warnings.
  factory PositionSensorVRDevice._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PositionSensorVRDevice.internal_() : super.internal_();


  @DomName('PositionSensorVRDevice.getImmediateState')
  @DocsEditable()
  @Experimental() // untriaged
  VRPositionState getImmediateState() => _blink.BlinkPositionSensorVRDevice.instance.getImmediateState_Callback_0_(this);
  
  @DomName('PositionSensorVRDevice.getState')
  @DocsEditable()
  @Experimental() // untriaged
  VRPositionState getState() => _blink.BlinkPositionSensorVRDevice.instance.getState_Callback_0_(this);
  
  @DomName('PositionSensorVRDevice.resetSensor')
  @DocsEditable()
  @Experimental() // untriaged
  void resetSensor() => _blink.BlinkPositionSensorVRDevice.instance.resetSensor_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('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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PreElement.internal_() : super.internal_();

  /**
   * 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('Presentation')
@Experimental() // untriaged
class Presentation extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory Presentation._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Presentation.internal_() : super.internal_();


  @DomName('Presentation.session')
  @DocsEditable()
  @Experimental() // untriaged
  PresentationSession get session => _blink.BlinkPresentation.instance.session_Getter_(this);
  
  @DomName('Presentation.getAvailability')
  @DocsEditable()
  @Experimental() // untriaged
  Future getAvailability(String url) => convertNativePromiseToDartFuture(_blink.BlinkPresentation.instance.getAvailability_Callback_1_(this, url));
  
  @DomName('Presentation.joinSession')
  @DocsEditable()
  @Experimental() // untriaged
  Future joinSession(String url, String presentationId) => convertNativePromiseToDartFuture(_blink.BlinkPresentation.instance.joinSession_Callback_2_(this, url, presentationId));
  
  @DomName('Presentation.startSession')
  @DocsEditable()
  @Experimental() // untriaged
  Future startSession(String url) => convertNativePromiseToDartFuture(_blink.BlinkPresentation.instance.startSession_Callback_1_(this, 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('PresentationAvailability')
@Experimental() // untriaged
class PresentationAvailability extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory PresentationAvailability._() { throw new UnsupportedError("Not supported"); }

  @DomName('PresentationAvailability.changeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> changeEvent = const EventStreamProvider<Event>('change');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PresentationAvailability.internal_() : super.internal_();


  @DomName('PresentationAvailability.value')
  @DocsEditable()
  @Experimental() // untriaged
  bool get value => _blink.BlinkPresentationAvailability.instance.value_Getter_(this);
  
  @DomName('PresentationAvailability.onchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onChange => changeEvent.forTarget(this);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('PresentationSession')
@Experimental() // untriaged
class PresentationSession extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory PresentationSession._() { throw new UnsupportedError("Not supported"); }

  @DomName('PresentationSession.messageEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PresentationSession.internal_() : super.internal_();


  @DomName('PresentationSession.binaryType')
  @DocsEditable()
  @Experimental() // untriaged
  String get binaryType => _blink.BlinkPresentationSession.instance.binaryType_Getter_(this);
  
  @DomName('PresentationSession.binaryType')
  @DocsEditable()
  @Experimental() // untriaged
  set binaryType(String value) => _blink.BlinkPresentationSession.instance.binaryType_Setter_(this, value);
  
  @DomName('PresentationSession.id')
  @DocsEditable()
  @Experimental() // untriaged
  String get id => _blink.BlinkPresentationSession.instance.id_Getter_(this);
  
  @DomName('PresentationSession.state')
  @DocsEditable()
  @Experimental() // untriaged
  String get state => _blink.BlinkPresentationSession.instance.state_Getter_(this);
  
  @DomName('PresentationSession.close')
  @DocsEditable()
  @Experimental() // untriaged
  void close() => _blink.BlinkPresentationSession.instance.close_Callback_0_(this);
  
  void send(data_OR_message) {
    if ((data_OR_message is String || data_OR_message == null)) {
      _blink.BlinkPresentationSession.instance.send_Callback_1_(this, data_OR_message);
      return;
    }
    if ((data_OR_message is Blob || data_OR_message == null)) {
      _blink.BlinkPresentationSession.instance.send_Callback_1_(this, data_OR_message);
      return;
    }
    if ((data_OR_message is TypedData || data_OR_message == null)) {
      _blink.BlinkPresentationSession.instance.send_Callback_1_(this, data_OR_message);
      return;
    }
    if ((data_OR_message is ByteBuffer || data_OR_message == null)) {
      _blink.BlinkPresentationSession.instance.send_Callback_1_(this, data_OR_message);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('PresentationSession.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('ProcessingInstruction')
@Unstable()
class ProcessingInstruction extends CharacterData {
  // To suppress missing implicit constructor warnings.
  factory ProcessingInstruction._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ProcessingInstruction.internal_() : super.internal_();


  @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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ProgressElement.internal_() : super.internal_();

  /**
   * 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()
  set max(num value) => _blink.BlinkHTMLProgressElement.instance.max_Setter_(this, value);
  
  @DomName('HTMLProgressElement.position')
  @DocsEditable()
  num 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()
  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.ProgressEvent')
  @DocsEditable()
  factory ProgressEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkProgressEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkProgressEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ProgressEvent.internal_() : super.internal_();


  @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('PromiseRejectionEvent')
@Experimental() // untriaged
class PromiseRejectionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory PromiseRejectionEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('PromiseRejectionEvent.PromiseRejectionEvent')
  @DocsEditable()
  factory PromiseRejectionEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkPromiseRejectionEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkPromiseRejectionEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PromiseRejectionEvent.internal_() : super.internal_();


  @DomName('PromiseRejectionEvent.promise')
  @DocsEditable()
  @Experimental() // untriaged
  Future get promise => convertNativePromiseToDartFuture(_blink.BlinkPromiseRejectionEvent.instance.promise_Getter_(this));
  
  @DomName('PromiseRejectionEvent.reason')
  @DocsEditable()
  @Experimental() // untriaged
  Object get reason => (_blink.BlinkPromiseRejectionEvent.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('PushEvent')
@Experimental() // untriaged
class PushEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory PushEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('PushEvent.PushEvent')
  @DocsEditable()
  factory PushEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkPushEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkPushEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PushEvent.internal_() : super.internal_();


  @DomName('PushEvent.data')
  @DocsEditable()
  @Experimental() // untriaged
  PushMessageData 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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory PushManager._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PushManager.internal_() { }

  @DomName('PushManager.getSubscription')
  @DocsEditable()
  @Experimental() // untriaged
  Future getSubscription() => convertNativePromiseToDartFuture(_blink.BlinkPushManager.instance.getSubscription_Callback_0_(this));
  
  Future permissionState([Map options]) {
    if (options != null) {
      return _blink.BlinkPushManager.instance.permissionState_Callback_1_(this, convertDartToNative_Dictionary(options));
    }
    return _blink.BlinkPushManager.instance.permissionState_Callback_0_(this);
  }

  Future subscribe([Map options]) {
    if (options != null) {
      return _blink.BlinkPushManager.instance.subscribe_Callback_1_(this, convertDartToNative_Dictionary(options));
    }
    return _blink.BlinkPushManager.instance.subscribe_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('PushMessageData')
@Experimental() // untriaged
class PushMessageData extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory PushMessageData._() { throw new UnsupportedError("Not supported"); }

  @DomName('PushMessageData.PushMessageData')
  @DocsEditable()
  factory PushMessageData(String message) {
    return _blink.BlinkPushMessageData.instance.constructorCallback_1_(message);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PushMessageData.internal_() { }

  @DomName('PushMessageData.arrayBuffer')
  @DocsEditable()
  @Experimental() // untriaged
  ByteBuffer arrayBuffer() => _blink.BlinkPushMessageData.instance.arrayBuffer_Callback_0_(this);
  
  @DomName('PushMessageData.blob')
  @DocsEditable()
  @Experimental() // untriaged
  Blob blob() => _blink.BlinkPushMessageData.instance.blob_Callback_0_(this);
  
  @DomName('PushMessageData.json')
  @DocsEditable()
  @Experimental() // untriaged
  Object json() => (_blink.BlinkPushMessageData.instance.json_Callback_0_(this));
  
  @DomName('PushMessageData.text')
  @DocsEditable()
  @Experimental() // untriaged
  String text() => _blink.BlinkPushMessageData.instance.text_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('PushSubscription')
@Experimental() // untriaged
class PushSubscription extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory PushSubscription._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  PushSubscription.internal_() { }

  @DomName('PushSubscription.endpoint')
  @DocsEditable()
  @Experimental() // untriaged
  String get endpoint => _blink.BlinkPushSubscription.instance.endpoint_Getter_(this);
  
  @DomName('PushSubscription.unsubscribe')
  @DocsEditable()
  @Experimental() // untriaged
  Future unsubscribe() => convertNativePromiseToDartFuture(_blink.BlinkPushSubscription.instance.unsubscribe_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('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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  QuoteElement.internal_() : super.internal_();

  /**
   * 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()
  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 DartHtmlDomObject {
  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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Range.internal_() { }

  @DomName('Range.END_TO_END')
  @DocsEditable()
  static const int END_TO_END = 2;

  @DomName('Range.END_TO_START')
  @DocsEditable()
  static const int END_TO_START = 3;

  @DomName('Range.START_TO_END')
  @DocsEditable()
  static const int START_TO_END = 1;

  @DomName('Range.START_TO_START')
  @DocsEditable()
  static const int START_TO_START = 0;

  @DomName('Range.collapsed')
  @DocsEditable()
  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.compareBoundaryPoints')
  @DocsEditable()
  @Experimental() // untriaged
  int compareBoundaryPoints(int how, Range sourceRange) => _blink.BlinkRange.instance.compareBoundaryPoints_Callback_2_(this, how, sourceRange);
  
  @DomName('Range.comparePoint')
  @DocsEditable()
  int comparePoint(Node node, int offset) => _blink.BlinkRange.instance.comparePoint_Callback_2_(this, node, offset);
  
  @DomName('Range.createContextualFragment')
  @DocsEditable()
  DocumentFragment createContextualFragment(String fragment) => _blink.BlinkRange.instance.createContextualFragment_Callback_1_(this, fragment);
  
  @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() => make_dart_rectangle(_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 node) => _blink.BlinkRange.instance.insertNode_Callback_1_(this, node);
  
  @DomName('Range.isPointInRange')
  @DocsEditable()
  bool isPointInRange(Node node, int offset) => _blink.BlinkRange.instance.isPointInRange_Callback_2_(this, node, offset);
  
  @DomName('Range.selectNode')
  @DocsEditable()
  void selectNode(Node node) => _blink.BlinkRange.instance.selectNode_Callback_1_(this, node);
  
  @DomName('Range.selectNodeContents')
  @DocsEditable()
  void selectNodeContents(Node node) => _blink.BlinkRange.instance.selectNodeContents_Callback_1_(this, node);
  
  @DomName('Range.setEnd')
  @DocsEditable()
  void setEnd(Node node, int offset) => _blink.BlinkRange.instance.setEnd_Callback_2_(this, node, offset);
  
  @DomName('Range.setEndAfter')
  @DocsEditable()
  void setEndAfter(Node node) => _blink.BlinkRange.instance.setEndAfter_Callback_1_(this, node);
  
  @DomName('Range.setEndBefore')
  @DocsEditable()
  void setEndBefore(Node node) => _blink.BlinkRange.instance.setEndBefore_Callback_1_(this, node);
  
  @DomName('Range.setStart')
  @DocsEditable()
  void setStart(Node node, int offset) => _blink.BlinkRange.instance.setStart_Callback_2_(this, node, offset);
  
  @DomName('Range.setStartAfter')
  @DocsEditable()
  void setStartAfter(Node node) => _blink.BlinkRange.instance.setStartAfter_Callback_1_(this, node);
  
  @DomName('Range.setStartBefore')
  @DocsEditable()
  void setStartBefore(Node node) => _blink.BlinkRange.instance.setStartBefore_Callback_1_(this, node);
  
  @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('ReadableByteStream')
@Experimental() // untriaged
class ReadableByteStream extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory ReadableByteStream._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ReadableByteStream.internal_() { }

  Future cancel([Object reason]) {
    if (reason != null) {
      return _blink.BlinkReadableByteStream.instance.cancel_Callback_1_(this, reason);
    }
    return _blink.BlinkReadableByteStream.instance.cancel_Callback_0_(this);
  }

  @DomName('ReadableByteStream.getReader')
  @DocsEditable()
  @Experimental() // untriaged
  ReadableByteStreamReader getReader() => _blink.BlinkReadableByteStream.instance.getReader_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('ReadableByteStreamReader')
@Experimental() // untriaged
class ReadableByteStreamReader extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory ReadableByteStreamReader._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ReadableByteStreamReader.internal_() { }

  @DomName('ReadableByteStreamReader.closed')
  @DocsEditable()
  @Experimental() // untriaged
  Future get closed => convertNativePromiseToDartFuture(_blink.BlinkReadableByteStreamReader.instance.closed_Getter_(this));
  
  Future cancel([Object reason]) {
    if (reason != null) {
      return _blink.BlinkReadableByteStreamReader.instance.cancel_Callback_1_(this, reason);
    }
    return _blink.BlinkReadableByteStreamReader.instance.cancel_Callback_0_(this);
  }

  @DomName('ReadableByteStreamReader.read')
  @DocsEditable()
  @Experimental() // untriaged
  Future read() => convertNativePromiseToDartFuture(_blink.BlinkReadableByteStreamReader.instance.read_Callback_0_(this));
  
  @DomName('ReadableByteStreamReader.releaseLock')
  @DocsEditable()
  @Experimental() // untriaged
  void releaseLock() => _blink.BlinkReadableByteStreamReader.instance.releaseLock_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('ReadableStream')
@Experimental() // untriaged
class ReadableStream extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory ReadableStream._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ReadableStream.internal_() { }

  Future cancel([Object reason]) {
    if (reason != null) {
      return _blink.BlinkReadableStream.instance.cancel_Callback_1_(this, reason);
    }
    return _blink.BlinkReadableStream.instance.cancel_Callback_0_(this);
  }

  @DomName('ReadableStream.getReader')
  @DocsEditable()
  @Experimental() // untriaged
  ReadableStreamReader getReader() => _blink.BlinkReadableStream.instance.getReader_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('ReadableStreamReader')
@Experimental() // untriaged
class ReadableStreamReader extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory ReadableStreamReader._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ReadableStreamReader.internal_() { }

  @DomName('ReadableStreamReader.closed')
  @DocsEditable()
  @Experimental() // untriaged
  Future get closed => convertNativePromiseToDartFuture(_blink.BlinkReadableStreamReader.instance.closed_Getter_(this));
  
  Future cancel([Object reason]) {
    if (reason != null) {
      return _blink.BlinkReadableStreamReader.instance.cancel_Callback_1_(this, reason);
    }
    return _blink.BlinkReadableStreamReader.instance.cancel_Callback_0_(this);
  }

  @DomName('ReadableStreamReader.read')
  @DocsEditable()
  @Experimental() // untriaged
  Future read() => convertNativePromiseToDartFuture(_blink.BlinkReadableStreamReader.instance.read_Callback_0_(this));
  
  @DomName('ReadableStreamReader.releaseLock')
  @DocsEditable()
  @Experimental() // untriaged
  void releaseLock() => _blink.BlinkReadableStreamReader.instance.releaseLock_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('RelatedEvent')
@Experimental() // untriaged
class RelatedEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory RelatedEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('RelatedEvent.RelatedEvent')
  @DocsEditable()
  factory RelatedEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkRelatedEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkRelatedEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  RelatedEvent.internal_() : super.internal_();


  @DomName('RelatedEvent.relatedTarget')
  @DocsEditable()
  @Experimental() // untriaged
  EventTarget get relatedTarget => _convertNativeToDart_EventTarget(_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('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');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  RtcDataChannel.internal_() : super.internal_();


  @DomName('RTCDataChannel.binaryType')
  @DocsEditable()
  String get binaryType => _blink.BlinkRTCDataChannel.instance.binaryType_Getter_(this);
  
  @DomName('RTCDataChannel.binaryType')
  @DocsEditable()
  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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  RtcDataChannelEvent.internal_() : super.internal_();


  @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');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  RtcDtmfSender.internal_() : super.internal_();


  @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.RTCDTMFToneChangeEvent')
  @DocsEditable()
  factory RtcDtmfToneChangeEvent(String type, Map eventInitDict) {
    var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
    return _blink.BlinkRTCDTMFToneChangeEvent.instance.constructorCallback_2_(type, eventInitDict_1);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  RtcDtmfToneChangeEvent.internal_() : super.internal_();


  @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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory RtcIceCandidate._() { throw new UnsupportedError("Not supported"); }

  @DomName('RTCIceCandidate.RTCIceCandidate')
  @DocsEditable()
  factory RtcIceCandidate(Map candidateInitDict) {
    var candidateInitDict_1 = convertDartToNative_Dictionary(candidateInitDict);
    return _blink.BlinkRTCIceCandidate.instance.constructorCallback_1_(candidateInitDict_1);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  RtcIceCandidate.internal_() { }

  @DomName('RTCIceCandidate.candidate')
  @DocsEditable()
  String get candidate => _blink.BlinkRTCIceCandidate.instance.candidate_Getter_(this);
  
  @DomName('RTCIceCandidate.candidate')
  @DocsEditable()
  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()
  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()
  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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  RtcIceCandidateEvent.internal_() : super.internal_();


  @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) {
      var rtcConfiguration_1 = convertDartToNative_Dictionary(rtcConfiguration);
      var mediaConstraints_2 = convertDartToNative_Dictionary(mediaConstraints);
      return _blink.BlinkRTCPeerConnection.instance.constructorCallback_2_(rtcConfiguration_1, mediaConstraints_2);
    }
    var rtcConfiguration_1 = convertDartToNative_Dictionary(rtcConfiguration);
    return _blink.BlinkRTCPeerConnection.instance.constructorCallback_1_(rtcConfiguration_1);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  RtcPeerConnection.internal_() : super.internal_();


  @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, convertDartToNative_Dictionary(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, convertDartToNative_Dictionary(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, convertDartToNative_Dictionary(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, convertDartToNative_Dictionary(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, convertDartToNative_Dictionary(configuration), convertDartToNative_Dictionary(mediaConstraints));
      return;
    }
    if (configuration != null) {
      _blink.BlinkRTCPeerConnection.instance.updateIce_Callback_1_(this, convertDartToNative_Dictionary(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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory RtcSessionDescription._() { throw new UnsupportedError("Not supported"); }

  @DomName('RTCSessionDescription.RTCSessionDescription')
  @DocsEditable()
  factory RtcSessionDescription([Map descriptionInitDict]) {
    if (descriptionInitDict != null) {
      var descriptionInitDict_1 = convertDartToNative_Dictionary(descriptionInitDict);
      return _blink.BlinkRTCSessionDescription.instance.constructorCallback_1_(descriptionInitDict_1);
    }
    return _blink.BlinkRTCSessionDescription.instance.constructorCallback_0_();
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  RtcSessionDescription.internal_() { }

  @DomName('RTCSessionDescription.sdp')
  @DocsEditable()
  String get sdp => _blink.BlinkRTCSessionDescription.instance.sdp_Getter_(this);
  
  @DomName('RTCSessionDescription.sdp')
  @DocsEditable()
  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()
  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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory RtcStatsReport._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  RtcStatsReport.internal_() { }

  @DomName('RTCStatsReport.id')
  @DocsEditable()
  String get id => _blink.BlinkRTCStatsReport.instance.id_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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory RtcStatsResponse._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  RtcStatsResponse.internal_() { }

  RtcStatsReport namedItem(String name) {
    if ((name is String || name == null)) {
      return _blink.BlinkRTCStatsResponse.instance.namedItem_Callback_1_(this, name);
    }
    if ((name is String || name == null)) {
      return _blink.BlinkRTCStatsResponse.instance.namedItem_Callback_1_(this, name);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @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 DartHtmlDomObject {

  @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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Screen.internal_() { }

  @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');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ScreenOrientation.internal_() : super.internal_();


  @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) => convertNativePromiseToDartFuture(_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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ScriptElement.internal_() : super.internal_();

  /**
   * 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()
  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()
  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()
  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()
  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
  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()
  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()
  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()
  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('ScrollState')
@Experimental() // untriaged
class ScrollState extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory ScrollState._() { throw new UnsupportedError("Not supported"); }

  @DomName('ScrollState.ScrollState')
  @DocsEditable()
  factory ScrollState([num deltaX, num deltaY, num deltaGranularity, num velocityX, num velocityY, bool inInertialPhase, bool isBeginning, bool isEnding]) {
    if (isEnding != null) {
      return _blink.BlinkScrollState.instance.constructorCallback_8_(deltaX, deltaY, deltaGranularity, velocityX, velocityY, inInertialPhase, isBeginning, isEnding);
    }
    if (isBeginning != null) {
      return _blink.BlinkScrollState.instance.constructorCallback_7_(deltaX, deltaY, deltaGranularity, velocityX, velocityY, inInertialPhase, isBeginning);
    }
    if (inInertialPhase != null) {
      return _blink.BlinkScrollState.instance.constructorCallback_6_(deltaX, deltaY, deltaGranularity, velocityX, velocityY, inInertialPhase);
    }
    if (velocityY != null) {
      return _blink.BlinkScrollState.instance.constructorCallback_5_(deltaX, deltaY, deltaGranularity, velocityX, velocityY);
    }
    if (velocityX != null) {
      return _blink.BlinkScrollState.instance.constructorCallback_4_(deltaX, deltaY, deltaGranularity, velocityX);
    }
    if (deltaGranularity != null) {
      return _blink.BlinkScrollState.instance.constructorCallback_3_(deltaX, deltaY, deltaGranularity);
    }
    if (deltaY != null) {
      return _blink.BlinkScrollState.instance.constructorCallback_2_(deltaX, deltaY);
    }
    if (deltaX != null) {
      return _blink.BlinkScrollState.instance.constructorCallback_1_(deltaX);
    }
    return _blink.BlinkScrollState.instance.constructorCallback_0_();
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ScrollState.internal_() { }

  @DomName('ScrollState.deltaGranularity')
  @DocsEditable()
  @Experimental() // untriaged
  num get deltaGranularity => _blink.BlinkScrollState.instance.deltaGranularity_Getter_(this);
  
  @DomName('ScrollState.deltaX')
  @DocsEditable()
  @Experimental() // untriaged
  num get deltaX => _blink.BlinkScrollState.instance.deltaX_Getter_(this);
  
  @DomName('ScrollState.deltaY')
  @DocsEditable()
  @Experimental() // untriaged
  num get deltaY => _blink.BlinkScrollState.instance.deltaY_Getter_(this);
  
  @DomName('ScrollState.fromUserInput')
  @DocsEditable()
  @Experimental() // untriaged
  bool get fromUserInput => _blink.BlinkScrollState.instance.fromUserInput_Getter_(this);
  
  @DomName('ScrollState.inInertialPhase')
  @DocsEditable()
  @Experimental() // untriaged
  bool get inInertialPhase => _blink.BlinkScrollState.instance.inInertialPhase_Getter_(this);
  
  @DomName('ScrollState.isBeginning')
  @DocsEditable()
  @Experimental() // untriaged
  bool get isBeginning => _blink.BlinkScrollState.instance.isBeginning_Getter_(this);
  
  @DomName('ScrollState.isEnding')
  @DocsEditable()
  @Experimental() // untriaged
  bool get isEnding => _blink.BlinkScrollState.instance.isEnding_Getter_(this);
  
  @DomName('ScrollState.shouldPropagate')
  @DocsEditable()
  @Experimental() // untriaged
  bool get shouldPropagate => _blink.BlinkScrollState.instance.shouldPropagate_Getter_(this);
  
  @DomName('ScrollState.velocityX')
  @DocsEditable()
  @Experimental() // untriaged
  num get velocityX => _blink.BlinkScrollState.instance.velocityX_Getter_(this);
  
  @DomName('ScrollState.velocityY')
  @DocsEditable()
  @Experimental() // untriaged
  num get velocityY => _blink.BlinkScrollState.instance.velocityY_Getter_(this);
  
  @DomName('ScrollState.consumeDelta')
  @DocsEditable()
  @Experimental() // untriaged
  void consumeDelta(num x, num y) => _blink.BlinkScrollState.instance.consumeDelta_Callback_2_(this, 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('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.SecurityPolicyViolationEvent')
  @DocsEditable()
  factory SecurityPolicyViolationEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkSecurityPolicyViolationEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkSecurityPolicyViolationEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  SecurityPolicyViolationEvent.internal_() : super.internal_();


  @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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  SelectElement.internal_() : super.internal_();

  /**
   * 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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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 option) => _blink.BlinkHTMLSelectElement.instance.$__setter___Callback_2_(this, index, option);
  
  @DomName('HTMLSelectElement.add')
  @DocsEditable()
  @Experimental() // untriaged
  void add(Object element, Object 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()
  OptionElement namedItem(String name) => _blink.BlinkHTMLSelectElement.instance.namedItem_Callback_1_(this, name);
  
  @DomName('HTMLSelectElement.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() => _blink.BlinkHTMLSelectElement.instance.reportValidity_Callback_0_(this);
  
  @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 = new List<OptionElement>.from(this.querySelectorAll('option'));
    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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory Selection._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Selection.internal_() { }

  @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 allowPartialContainment) => _blink.BlinkSelection.instance.containsNode_Callback_2_(this, node, allowPartialContainment);
  
  @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('ServicePort')
@Experimental() // untriaged
class ServicePort extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory ServicePort._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ServicePort.internal_() { }

  @DomName('ServicePort.data')
  @DocsEditable()
  @Experimental() // untriaged
  Object get data => (_blink.BlinkServicePort.instance.data_Getter_(this));
  
  @DomName('ServicePort.name')
  @DocsEditable()
  @Experimental() // untriaged
  String get name => _blink.BlinkServicePort.instance.name_Getter_(this);
  
  @DomName('ServicePort.targetURL')
  @DocsEditable()
  @Experimental() // untriaged
  String get targetUrl => _blink.BlinkServicePort.instance.targetURL_Getter_(this);
  
  @DomName('ServicePort.close')
  @DocsEditable()
  @Experimental() // untriaged
  void close() => _blink.BlinkServicePort.instance.close_Callback_0_(this);
  
  void postMessage(/*SerializedScriptValue*/ message, [List<MessagePort> transfer]) {
    if (transfer != null) {
      _blink.BlinkServicePort.instance.postMessage_Callback_2_(this, convertDartToNative_SerializedScriptValue(message), transfer);
      return;
    }
    _blink.BlinkServicePort.instance.postMessage_Callback_1_(this, convertDartToNative_SerializedScriptValue(message));
    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('ServicePortCollection')
@Experimental() // untriaged
class ServicePortCollection extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory ServicePortCollection._() { throw new UnsupportedError("Not supported"); }

  @DomName('ServicePortCollection.messageEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ServicePortCollection.internal_() : super.internal_();


  Future connect(String url, [Map options]) {
    if (options != null) {
      return _blink.BlinkServicePortCollection.instance.connect_Callback_2_(this, url, convertDartToNative_Dictionary(options));
    }
    return _blink.BlinkServicePortCollection.instance.connect_Callback_1_(this, url);
  }

  @DomName('ServicePortCollection.match')
  @DocsEditable()
  @Experimental() // untriaged
  Future match(Map options) => convertNativePromiseToDartFuture(_blink.BlinkServicePortCollection.instance.match_Callback_1_(this, convertDartToNative_Dictionary(options)));
  
  Future matchAll([Map options]) {
    if (options != null) {
      return _blink.BlinkServicePortCollection.instance.matchAll_Callback_1_(this, convertDartToNative_Dictionary(options));
    }
    return _blink.BlinkServicePortCollection.instance.matchAll_Callback_0_(this);
  }

  @DomName('ServicePortCollection.onmessage')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('ServicePortConnectEvent')
@Experimental() // untriaged
class ServicePortConnectEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory ServicePortConnectEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('ServicePortConnectEvent.ServicePortConnectEvent')
  @DocsEditable()
  factory ServicePortConnectEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkServicePortConnectEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkServicePortConnectEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ServicePortConnectEvent.internal_() : super.internal_();


  @DomName('ServicePortConnectEvent.origin')
  @DocsEditable()
  @Experimental() // untriaged
  String get origin => _blink.BlinkServicePortConnectEvent.instance.origin_Getter_(this);
  
  @DomName('ServicePortConnectEvent.targetURL')
  @DocsEditable()
  @Experimental() // untriaged
  String get targetUrl => _blink.BlinkServicePortConnectEvent.instance.targetURL_Getter_(this);
  
  @DomName('ServicePortConnectEvent.respondWith')
  @DocsEditable()
  @Experimental() // untriaged
  Future respondWith(Future response) => convertNativePromiseToDartFuture(_blink.BlinkServicePortConnectEvent.instance.respondWith_Callback_1_(this, 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.


@DocsEditable()
@DomName('ServiceWorkerContainer')
@Experimental() // untriaged
class ServiceWorkerContainer extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory ServiceWorkerContainer._() { throw new UnsupportedError("Not supported"); }

  @DomName('ServiceWorkerContainer.messageEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ServiceWorkerContainer.internal_() : super.internal_();


  @DomName('ServiceWorkerContainer.controller')
  @DocsEditable()
  @Experimental() // untriaged
  _ServiceWorker get controller => _blink.BlinkServiceWorkerContainer.instance.controller_Getter_(this);
  
  @DomName('ServiceWorkerContainer.ready')
  @DocsEditable()
  @Experimental() // untriaged
  Future get ready => convertNativePromiseToDartFuture(_blink.BlinkServiceWorkerContainer.instance.ready_Getter_(this));
  
  Future getRegistration([String documentURL]) {
    if (documentURL != null) {
      return _blink.BlinkServiceWorkerContainer.instance.getRegistration_Callback_1_(this, documentURL);
    }
    return _blink.BlinkServiceWorkerContainer.instance.getRegistration_Callback_0_(this);
  }

  @DomName('ServiceWorkerContainer.getRegistrations')
  @DocsEditable()
  @Experimental() // untriaged
  Future getRegistrations() => convertNativePromiseToDartFuture(_blink.BlinkServiceWorkerContainer.instance.getRegistrations_Callback_0_(this));
  
  Future register(String url, [Map options]) {
    if (options != null) {
      return _blink.BlinkServiceWorkerContainer.instance.register_Callback_2_(this, url, convertDartToNative_Dictionary(options));
    }
    return _blink.BlinkServiceWorkerContainer.instance.register_Callback_1_(this, url);
  }

  @DomName('ServiceWorkerContainer.onmessage')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// 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');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ServiceWorkerGlobalScope.internal_() : super.internal_();


  @DomName('ServiceWorkerGlobalScope.clients')
  @DocsEditable()
  @Experimental() // untriaged
  Clients get clients => _blink.BlinkServiceWorkerGlobalScope.instance.clients_Getter_(this);
  
  @DomName('ServiceWorkerGlobalScope.ports')
  @DocsEditable()
  @Experimental() // untriaged
  StashedPortCollection get ports => _blink.BlinkServiceWorkerGlobalScope.instance.ports_Getter_(this);
  
  @DomName('ServiceWorkerGlobalScope.registration')
  @DocsEditable()
  @Experimental() // untriaged
  ServiceWorkerRegistration get registration => _blink.BlinkServiceWorkerGlobalScope.instance.registration_Getter_(this);
  
  @DomName('ServiceWorkerGlobalScope.close')
  @DocsEditable()
  @Experimental() // untriaged
  void close() => _blink.BlinkServiceWorkerGlobalScope.instance.close_Callback_0_(this);
  
  Future _fetch(/*RequestInfo*/ input, [Map init]) {
    if (init != null) {
      return _blink.BlinkServiceWorkerGlobalScope.instance.fetch_Callback_2_(this, input, convertDartToNative_Dictionary(init));
    }
    return _blink.BlinkServiceWorkerGlobalScope.instance.fetch_Callback_1_(this, input);
  }

  @DomName('ServiceWorkerGlobalScope.skipWaiting')
  @DocsEditable()
  @Experimental() // untriaged
  Future skipWaiting() => convertNativePromiseToDartFuture(_blink.BlinkServiceWorkerGlobalScope.instance.skipWaiting_Callback_0_(this));
  
  @DomName('ServiceWorkerGlobalScope.onmessage')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

}
// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


// TODO(alanknight): Provide a nicer constructor that uses named parameters
// rather than an initialization map.
@DomName('ServiceWorkerMessageEvent')
@Experimental() // untriaged
class ServiceWorkerMessageEvent extends Event {

  // TODO(alanknight): This really should be generated by the
  // _OutputConversion in the systemnative.py script, but that doesn't
  // use those conversions right now, so do this as a one-off.
  @DomName('ServiceWorkerMessageEvent.data')
  @DocsEditable()
  dynamic get data => convertNativeToDart_SerializedScriptValue(
      _blink.BlinkMessageEvent.instance.data_Getter_(this));

  // To suppress missing implicit constructor warnings.
  factory ServiceWorkerMessageEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('ServiceWorkerMessageEvent.ServiceWorkerMessageEvent')
  @DocsEditable()
  factory ServiceWorkerMessageEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkServiceWorkerMessageEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkServiceWorkerMessageEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ServiceWorkerMessageEvent.internal_() : super.internal_();


  @DomName('ServiceWorkerMessageEvent.lastEventId')
  @DocsEditable()
  @Experimental() // untriaged
  String get lastEventId => _blink.BlinkServiceWorkerMessageEvent.instance.lastEventId_Getter_(this);
  
  @DomName('ServiceWorkerMessageEvent.origin')
  @DocsEditable()
  @Experimental() // untriaged
  String get origin => _blink.BlinkServiceWorkerMessageEvent.instance.origin_Getter_(this);
  
  @DomName('ServiceWorkerMessageEvent.ports')
  @DocsEditable()
  @Experimental() // untriaged
  List<MessagePort> get ports => (_blink.BlinkServiceWorkerMessageEvent.instance.ports_Getter_(this));
  
  @DomName('ServiceWorkerMessageEvent.source')
  @DocsEditable()
  @Experimental() // untriaged
  Object get source => (_blink.BlinkServiceWorkerMessageEvent.instance.source_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('ServiceWorkerRegistration')
@Experimental() // untriaged
class ServiceWorkerRegistration extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory ServiceWorkerRegistration._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ServiceWorkerRegistration.internal_() : super.internal_();


  @DomName('ServiceWorkerRegistration.active')
  @DocsEditable()
  @Experimental() // untriaged
  _ServiceWorker get active => _blink.BlinkServiceWorkerRegistration.instance.active_Getter_(this);
  
  @DomName('ServiceWorkerRegistration.geofencing')
  @DocsEditable()
  @Experimental() // untriaged
  Geofencing get geofencing => _blink.BlinkServiceWorkerRegistration.instance.geofencing_Getter_(this);
  
  @DomName('ServiceWorkerRegistration.installing')
  @DocsEditable()
  @Experimental() // untriaged
  _ServiceWorker get installing => _blink.BlinkServiceWorkerRegistration.instance.installing_Getter_(this);
  
  @DomName('ServiceWorkerRegistration.periodicSync')
  @DocsEditable()
  @Experimental() // untriaged
  PeriodicSyncManager get periodicSync => _blink.BlinkServiceWorkerRegistration.instance.periodicSync_Getter_(this);
  
  @DomName('ServiceWorkerRegistration.pushManager')
  @DocsEditable()
  @Experimental() // untriaged
  PushManager get pushManager => _blink.BlinkServiceWorkerRegistration.instance.pushManager_Getter_(this);
  
  @DomName('ServiceWorkerRegistration.scope')
  @DocsEditable()
  @Experimental() // untriaged
  String get scope => _blink.BlinkServiceWorkerRegistration.instance.scope_Getter_(this);
  
  @DomName('ServiceWorkerRegistration.sync')
  @DocsEditable()
  @Experimental() // untriaged
  SyncManager get sync => _blink.BlinkServiceWorkerRegistration.instance.sync_Getter_(this);
  
  @DomName('ServiceWorkerRegistration.waiting')
  @DocsEditable()
  @Experimental() // untriaged
  _ServiceWorker get waiting => _blink.BlinkServiceWorkerRegistration.instance.waiting_Getter_(this);
  
  Future getNotifications([Map filter]) {
    if (filter != null) {
      return _blink.BlinkServiceWorkerRegistration.instance.getNotifications_Callback_1_(this, convertDartToNative_Dictionary(filter));
    }
    return _blink.BlinkServiceWorkerRegistration.instance.getNotifications_Callback_0_(this);
  }

  Future showNotification(String title, [Map options]) {
    if (options != null) {
      return _blink.BlinkServiceWorkerRegistration.instance.showNotification_Callback_2_(this, title, convertDartToNative_Dictionary(options));
    }
    return _blink.BlinkServiceWorkerRegistration.instance.showNotification_Callback_1_(this, title);
  }

  @DomName('ServiceWorkerRegistration.unregister')
  @DocsEditable()
  @Experimental() // untriaged
  Future unregister() => convertNativePromiseToDartFuture(_blink.BlinkServiceWorkerRegistration.instance.unregister_Callback_0_(this));
  
  @DomName('ServiceWorkerRegistration.update')
  @DocsEditable()
  @Experimental() // untriaged
  void update() => _blink.BlinkServiceWorkerRegistration.instance.update_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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ShadowElement.internal_() : super.internal_();

  /**
   * 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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ShadowRoot.internal_() : super.internal_();


  @DomName('ShadowRoot.activeElement')
  @DocsEditable()
  Element get activeElement => _blink.BlinkShadowRoot.instance.activeElement_Getter_(this);
  
  @DomName('ShadowRoot.delegatesFocus')
  @DocsEditable()
  @Experimental() // untriaged
  bool get delegatesFocus => _blink.BlinkShadowRoot.instance.delegatesFocus_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()
  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.elementsFromPoint')
  @DocsEditable()
  @Experimental() // untriaged
  List<Element> elementsFromPoint(int x, int y) => (_blink.BlinkShadowRoot.instance.elementsFromPoint_Callback_2_(this, x, y));
  
  @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
  set resetStyleInheritance(bool value) {
    _shadowRootDeprecationReport();
  }

  @deprecated
  bool get applyAuthorStyles {
    _shadowRootDeprecationReport();
    // Default value from when it was specified.
    return false;
  }

  @deprecated
  set applyAuthorStyles(bool value) {
    _shadowRootDeprecationReport();
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('SharedArrayBuffer')
@Experimental() // untriaged
class SharedArrayBuffer extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory SharedArrayBuffer._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  SharedArrayBuffer.internal_() { }

  @DomName('SharedArrayBuffer.byteLength')
  @DocsEditable()
  @Experimental() // untriaged
  int get byteLength => _blink.BlinkSharedArrayBuffer.instance.byteLength_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('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);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  SharedWorker.internal_() : super.internal_();


  @DomName('SharedWorker.port')
  @DocsEditable()
  MessagePort get port => _blink.BlinkSharedWorker.instance.port_Getter_(this);
  
  @DomName('SharedWorker.workerStart')
  @DocsEditable()
  @Experimental() // untriaged
  num 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');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  SharedWorkerGlobalScope.internal_() : super.internal_();


  @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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  SourceBuffer.internal_() : super.internal_();


  @DomName('SourceBuffer.appendWindowEnd')
  @DocsEditable()
  @Experimental() // untriaged
  num get appendWindowEnd => _blink.BlinkSourceBuffer.instance.appendWindowEnd_Getter_(this);
  
  @DomName('SourceBuffer.appendWindowEnd')
  @DocsEditable()
  @Experimental() // untriaged
  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
  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
  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()
  set timestampOffset(num value) => _blink.BlinkSourceBuffer.instance.timestampOffset_Setter_(this, value);
  
  @DomName('SourceBuffer.trackDefaults')
  @DocsEditable()
  @Experimental() // untriaged
  TrackDefaultList get trackDefaults => _blink.BlinkSourceBuffer.instance.trackDefaults_Getter_(this);
  
  @DomName('SourceBuffer.trackDefaults')
  @DocsEditable()
  @Experimental() // untriaged
  set trackDefaults(TrackDefaultList value) => _blink.BlinkSourceBuffer.instance.trackDefaults_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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  SourceBufferList.internal_() : super.internal_();


  @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 _nativeIndexedGetter(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.


  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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  SourceElement.internal_() : super.internal_();

  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  SourceElement.created() : super.created();

  @DomName('HTMLSourceElement.media')
  @DocsEditable()
  String get media => _blink.BlinkHTMLSourceElement.instance.media_Getter_(this);
  
  @DomName('HTMLSourceElement.media')
  @DocsEditable()
  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
  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()
  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
  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()
  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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory SourceInfo._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  SourceInfo.internal_() { }

  @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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  SpanElement.internal_() : super.internal_();

  /**
   * 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 DartHtmlDomObject {
  // 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_();
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  SpeechGrammar.internal_() { }

  @DomName('SpeechGrammar.src')
  @DocsEditable()
  String get src => _blink.BlinkSpeechGrammar.instance.src_Getter_(this);
  
  @DomName('SpeechGrammar.src')
  @DocsEditable()
  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()
  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 DartHtmlDomObject 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_();
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  SpeechGrammarList.internal_() { }

  @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 _nativeIndexedGetter(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.


  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_();
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  SpeechRecognition.internal_() : super.internal_();


  /// Checks if this type is supported on the current platform.
  static bool get supported => true;

  @DomName('SpeechRecognition.audioTrack')
  @DocsEditable()
  @Experimental() // untriaged
  MediaStreamTrack get audioTrack => _blink.BlinkSpeechRecognition.instance.audioTrack_Getter_(this);
  
  @DomName('SpeechRecognition.audioTrack')
  @DocsEditable()
  @Experimental() // untriaged
  set audioTrack(MediaStreamTrack value) => _blink.BlinkSpeechRecognition.instance.audioTrack_Setter_(this, value);
  
  @DomName('SpeechRecognition.continuous')
  @DocsEditable()
  bool get continuous => _blink.BlinkSpeechRecognition.instance.continuous_Getter_(this);
  
  @DomName('SpeechRecognition.continuous')
  @DocsEditable()
  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()
  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()
  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()
  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()
  set maxAlternatives(int value) => _blink.BlinkSpeechRecognition.instance.maxAlternatives_Setter_(this, value);
  
  @DomName('SpeechRecognition.serviceURI')
  @DocsEditable()
  @Experimental() // untriaged
  String get serviceUri => _blink.BlinkSpeechRecognition.instance.serviceURI_Getter_(this);
  
  @DomName('SpeechRecognition.serviceURI')
  @DocsEditable()
  @Experimental() // untriaged
  set serviceUri(String value) => _blink.BlinkSpeechRecognition.instance.serviceURI_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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionAlternative._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  SpeechRecognitionAlternative.internal_() { }

  @DomName('SpeechRecognitionAlternative.confidence')
  @DocsEditable()
  num 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.SpeechRecognitionError')
  @DocsEditable()
  factory SpeechRecognitionError(String type, [Map initDict]) {
    if (initDict != null) {
      var initDict_1 = convertDartToNative_Dictionary(initDict);
      return _blink.BlinkSpeechRecognitionError.instance.constructorCallback_2_(type, initDict_1);
    }
    return _blink.BlinkSpeechRecognitionError.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  SpeechRecognitionError.internal_() : super.internal_();


  @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.SpeechRecognitionEvent')
  @DocsEditable()
  factory SpeechRecognitionEvent(String type, [Map initDict]) {
    if (initDict != null) {
      var initDict_1 = convertDartToNative_Dictionary(initDict);
      return _blink.BlinkSpeechRecognitionEvent.instance.constructorCallback_2_(type, initDict_1);
    }
    return _blink.BlinkSpeechRecognitionEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  SpeechRecognitionEvent.internal_() : super.internal_();


  @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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory SpeechRecognitionResult._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  SpeechRecognitionResult.internal_() { }

  @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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  SpeechSynthesis.internal_() : super.internal_();


  @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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  SpeechSynthesisEvent.internal_() : super.internal_();


  @DomName('SpeechSynthesisEvent.charIndex')
  @DocsEditable()
  int get charIndex => _blink.BlinkSpeechSynthesisEvent.instance.charIndex_Getter_(this);
  
  @DomName('SpeechSynthesisEvent.elapsedTime')
  @DocsEditable()
  num get elapsedTime => _blink.BlinkSpeechSynthesisEvent.instance.elapsedTime_Getter_(this);
  
  @DomName('SpeechSynthesisEvent.name')
  @DocsEditable()
  String get name => _blink.BlinkSpeechSynthesisEvent.instance.name_Getter_(this);
  
  @DomName('SpeechSynthesisEvent.utterance')
  @DocsEditable()
  @Experimental() // untriaged
  SpeechSynthesisUtterance get utterance => _blink.BlinkSpeechSynthesisEvent.instance.utterance_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);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  SpeechSynthesisUtterance.internal_() : super.internal_();


  @DomName('SpeechSynthesisUtterance.lang')
  @DocsEditable()
  String get lang => _blink.BlinkSpeechSynthesisUtterance.instance.lang_Getter_(this);
  
  @DomName('SpeechSynthesisUtterance.lang')
  @DocsEditable()
  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()
  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()
  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()
  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()
  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()
  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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory SpeechSynthesisVoice._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  SpeechSynthesisVoice.internal_() { }

  @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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('StashedMessagePort')
@Experimental() // untriaged
class StashedMessagePort extends MessagePort {
  // To suppress missing implicit constructor warnings.
  factory StashedMessagePort._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  StashedMessagePort.internal_() : super.internal_();


  @DomName('StashedMessagePort.name')
  @DocsEditable()
  @Experimental() // untriaged
  String get name => _blink.BlinkStashedMessagePort.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('StashedPortCollection')
@Experimental() // untriaged
class StashedPortCollection extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory StashedPortCollection._() { throw new UnsupportedError("Not supported"); }

  @DomName('StashedPortCollection.messageEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  StashedPortCollection.internal_() : super.internal_();


  @DomName('StashedPortCollection.add')
  @DocsEditable()
  @Experimental() // untriaged
  StashedMessagePort add(String name, MessagePort port) => _blink.BlinkStashedPortCollection.instance.add_Callback_2_(this, name, port);
  
  @DomName('StashedPortCollection.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.


/**
 * 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 DartHtmlDomObject
    implements Map<String, String> {

  void addAll(Map<String, String> other) {
    other.forEach((k, v) { this[k] = v; });
  }

  // TODO(nweiz): update this when maps support lazy iteration
  bool containsValue(Object value) => values.any((e) => e == value);

  bool containsKey(Object key) => _getItem(key) != null;

  String operator [](Object key) => _getItem(key);

  void operator []=(String key, String value) { _setItem(key, value); }

  String putIfAbsent(String key, String ifAbsent()) {
    if (!containsKey(key)) this[key] = ifAbsent();
    return this[key];
  }

  String remove(Object key) {
    final value = this[key];
    _removeItem(key);
    return value;
  }

  void clear() => _clear();

  void forEach(void f(String key, String value)) {
    for (var i = 0; true; i++) {
      final key = _key(i);
      if (key == null) return;

      f(key, this[key]);
    }
  }

  Iterable<String> get keys {
    final keys = <String>[];
    forEach((k, v) => keys.add(k));
    return keys;
  }

  Iterable<String> get values {
    final values = <String>[];
    forEach((k, v) => values.add(v));
    return values;
  }

  int get length => _length;

  bool get isEmpty => _key(0) == null;

  bool get isNotEmpty => !isEmpty;
  // To suppress missing implicit constructor warnings.
  factory Storage._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Storage.internal_() { }

  @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}) {

    StorageEvent e = document._createEvent("StorageEvent");
    e._initStorageEvent(type, canBubble, cancelable, key, oldValue,
        newValue, url, storageArea);
    return e;
  }

  @DomName('StorageEvent.StorageEvent')
  @DocsEditable()
  factory StorageEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkStorageEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkStorageEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  StorageEvent.internal_() : super.internal_();


  @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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory StorageInfo._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  StorageInfo.internal_() { }

  @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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory StorageQuota._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  StorageQuota.internal_() { }

  @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) => convertNativePromiseToDartFuture(_blink.BlinkStorageQuota.instance.queryInfo_Callback_1_(this, type));
  
  @DomName('StorageQuota.requestPersistentQuota')
  @DocsEditable()
  @Experimental() // untriaged
  Future requestPersistentQuota(int newQuota) => convertNativePromiseToDartFuture(_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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  StyleElement.internal_() : super.internal_();

  /**
   * 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()
  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()
  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()
  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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory StyleMedia._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  StyleMedia.internal_() { }

  @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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory StyleSheet._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  StyleSheet.internal_() { }

  @DomName('StyleSheet.disabled')
  @DocsEditable()
  bool get disabled => _blink.BlinkStyleSheet.instance.disabled_Getter_(this);
  
  @DomName('StyleSheet.disabled')
  @DocsEditable()
  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('SyncEvent')
@Experimental() // untriaged
class SyncEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory SyncEvent._() { throw new UnsupportedError("Not supported"); }

  @DomName('SyncEvent.SyncEvent')
  @DocsEditable()
  factory SyncEvent(String type, Map init) {
    var init_1 = convertDartToNative_Dictionary(init);
    return _blink.BlinkSyncEvent.instance.constructorCallback_2_(type, init_1);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  SyncEvent.internal_() : super.internal_();


  @DomName('SyncEvent.registration')
  @DocsEditable()
  @Experimental() // untriaged
  SyncRegistration get registration => _blink.BlinkSyncEvent.instance.registration_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('SyncManager')
@Experimental() // untriaged
class SyncManager extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory SyncManager._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  SyncManager.internal_() { }

  @DomName('SyncManager.getRegistration')
  @DocsEditable()
  @Experimental() // untriaged
  Future getRegistration(String tag) => convertNativePromiseToDartFuture(_blink.BlinkSyncManager.instance.getRegistration_Callback_1_(this, tag));
  
  @DomName('SyncManager.getRegistrations')
  @DocsEditable()
  @Experimental() // untriaged
  Future getRegistrations() => convertNativePromiseToDartFuture(_blink.BlinkSyncManager.instance.getRegistrations_Callback_0_(this));
  
  @DomName('SyncManager.permissionState')
  @DocsEditable()
  @Experimental() // untriaged
  Future permissionState() => convertNativePromiseToDartFuture(_blink.BlinkSyncManager.instance.permissionState_Callback_0_(this));
  
  Future register([Map options]) {
    if (options != null) {
      return _blink.BlinkSyncManager.instance.register_Callback_1_(this, convertDartToNative_Dictionary(options));
    }
    return _blink.BlinkSyncManager.instance.register_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('SyncRegistration')
@Experimental() // untriaged
class SyncRegistration extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory SyncRegistration._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  SyncRegistration.internal_() { }

  @DomName('SyncRegistration.tag')
  @DocsEditable()
  @Experimental() // untriaged
  String get tag => _blink.BlinkSyncRegistration.instance.tag_Getter_(this);
  
  @DomName('SyncRegistration.unregister')
  @DocsEditable()
  @Experimental() // untriaged
  Future unregister() => convertNativePromiseToDartFuture(_blink.BlinkSyncRegistration.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('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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  TableCaptionElement.internal_() : super.internal_();

  /**
   * 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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  TableCellElement.internal_() : super.internal_();

  /**
   * 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()
  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()
  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()
  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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  TableColElement.internal_() : super.internal_();

  /**
   * 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()
  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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  TableElement.internal_() : super.internal_();

  /**
   * 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()
  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()
  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()
  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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  TableRowElement.internal_() : super.internal_();

  /**
   * 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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  TableSectionElement.internal_() : super.internal_();

  /**
   * 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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  TemplateElement.internal_() : super.internal_();

  /**
   * 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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Text.internal_() : super.internal_();


  @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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  TextAreaElement.internal_() : super.internal_();

  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  TextAreaElement.created() : super.created();

  @DomName('HTMLTextAreaElement.autocapitalize')
  @DocsEditable()
  @Experimental() // untriaged
  String get autocapitalize => _blink.BlinkHTMLTextAreaElement.instance.autocapitalize_Getter_(this);
  
  @DomName('HTMLTextAreaElement.autocapitalize')
  @DocsEditable()
  @Experimental() // untriaged
  set autocapitalize(String value) => _blink.BlinkHTMLTextAreaElement.instance.autocapitalize_Setter_(this, value);
  
  @DomName('HTMLTextAreaElement.autofocus')
  @DocsEditable()
  bool get autofocus => _blink.BlinkHTMLTextAreaElement.instance.autofocus_Getter_(this);
  
  @DomName('HTMLTextAreaElement.autofocus')
  @DocsEditable()
  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()
  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()
  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()
  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()
  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
  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()
  set maxLength(int value) => _blink.BlinkHTMLTextAreaElement.instance.maxLength_Setter_(this, value);
  
  @DomName('HTMLTextAreaElement.minLength')
  @DocsEditable()
  @Experimental() // untriaged
  int get minLength => _blink.BlinkHTMLTextAreaElement.instance.minLength_Getter_(this);
  
  @DomName('HTMLTextAreaElement.minLength')
  @DocsEditable()
  @Experimental() // untriaged
  set minLength(int value) => _blink.BlinkHTMLTextAreaElement.instance.minLength_Setter_(this, value);
  
  @DomName('HTMLTextAreaElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLTextAreaElement.instance.name_Getter_(this);
  
  @DomName('HTMLTextAreaElement.name')
  @DocsEditable()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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()
  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.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() => _blink.BlinkHTMLTextAreaElement.instance.reportValidity_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;
    }
    TextEvent e = document._createEvent("TextEvent");
    e._initTextEvent(type, canBubble, cancelable, view, data);
    return e;
  }
  // To suppress missing implicit constructor warnings.
  factory TextEvent._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  TextEvent.internal_() : super.internal_();


  @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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory TextMetrics._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  TextMetrics.internal_() { }

  @DomName('TextMetrics.actualBoundingBoxAscent')
  @DocsEditable()
  @Experimental() // untriaged
  num get actualBoundingBoxAscent => _blink.BlinkTextMetrics.instance.actualBoundingBoxAscent_Getter_(this);
  
  @DomName('TextMetrics.actualBoundingBoxDescent')
  @DocsEditable()
  @Experimental() // untriaged
  num get actualBoundingBoxDescent => _blink.BlinkTextMetrics.instance.actualBoundingBoxDescent_Getter_(this);
  
  @DomName('TextMetrics.actualBoundingBoxLeft')
  @DocsEditable()
  @Experimental() // untriaged
  num get actualBoundingBoxLeft => _blink.BlinkTextMetrics.instance.actualBoundingBoxLeft_Getter_(this);
  
  @DomName('TextMetrics.actualBoundingBoxRight')
  @DocsEditable()
  @Experimental() // untriaged
  num get actualBoundingBoxRight => _blink.BlinkTextMetrics.instance.actualBoundingBoxRight_Getter_(this);
  
  @DomName('TextMetrics.alphabeticBaseline')
  @DocsEditable()
  @Experimental() // untriaged
  num get alphabeticBaseline => _blink.BlinkTextMetrics.instance.alphabeticBaseline_Getter_(this);
  
  @DomName('TextMetrics.emHeightAscent')
  @DocsEditable()
  @Experimental() // untriaged
  num get emHeightAscent => _blink.BlinkTextMetrics.instance.emHeightAscent_Getter_(this);
  
  @DomName('TextMetrics.emHeightDescent')
  @DocsEditable()
  @Experimental() // untriaged
  num get emHeightDescent => _blink.BlinkTextMetrics.instance.emHeightDescent_Getter_(this);
  
  @DomName('TextMetrics.fontBoundingBoxAscent')
  @DocsEditable()
  @Experimental() // untriaged
  num get fontBoundingBoxAscent => _blink.BlinkTextMetrics.instance.fontBoundingBoxAscent_Getter_(this);
  
  @DomName('TextMetrics.fontBoundingBoxDescent')
  @DocsEditable()
  @Experimental() // untriaged
  num get fontBoundingBoxDescent => _blink.BlinkTextMetrics.instance.fontBoundingBoxDescent_Getter_(this);
  
  @DomName('TextMetrics.hangingBaseline')
  @DocsEditable()
  @Experimental() // untriaged
  num get hangingBaseline => _blink.BlinkTextMetrics.instance.hangingBaseline_Getter_(this);
  
  @DomName('TextMetrics.ideographicBaseline')
  @DocsEditable()
  @Experimental() // untriaged
  num get ideographicBaseline => _blink.BlinkTextMetrics.instance.ideographicBaseline_Getter_(this);
  
  @DomName('TextMetrics.width')
  @DocsEditable()
  num 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');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  TextTrack.internal_() : super.internal_();


  @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()
  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');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  TextTrackCue.internal_() : super.internal_();


  @DomName('TextTrackCue.endTime')
  @DocsEditable()
  num get endTime => _blink.BlinkTextTrackCue.instance.endTime_Getter_(this);
  
  @DomName('TextTrackCue.endTime')
  @DocsEditable()
  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()
  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()
  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()
  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 DartHtmlDomObject with ListMixin<TextTrackCue>, ImmutableListMixin<TextTrackCue> implements List<TextTrackCue> {
  // To suppress missing implicit constructor warnings.
  factory TextTrackCueList._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  TextTrackCueList.internal_() { }

  @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 _nativeIndexedGetter(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.


  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');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  TextTrackList.internal_() : super.internal_();


  @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 _nativeIndexedGetter(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.


  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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory TimeRanges._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  TimeRanges.internal_() { }

  @DomName('TimeRanges.length')
  @DocsEditable()
  int get length => _blink.BlinkTimeRanges.instance.length_Getter_(this);
  
  @DomName('TimeRanges.end')
  @DocsEditable()
  num end(int index) => _blink.BlinkTimeRanges.instance.end_Callback_1_(this, index);
  
  @DomName('TimeRanges.start')
  @DocsEditable()
  num 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('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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  TitleElement.internal_() : super.internal_();

  /**
   * 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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory Touch._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Touch.internal_() { }

  @DomName('Touch.clientX')
  @DocsEditable()
  num get _clientX => _blink.BlinkTouch.instance.clientX_Getter_(this);
  
  @DomName('Touch.clientY')
  @DocsEditable()
  num get _clientY => _blink.BlinkTouch.instance.clientY_Getter_(this);
  
  @DomName('Touch.force')
  @DocsEditable()
  @Experimental() // untriaged
  num 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()
  num get _pageX => _blink.BlinkTouch.instance.pageX_Getter_(this);
  
  @DomName('Touch.pageY')
  @DocsEditable()
  num get _pageY => _blink.BlinkTouch.instance.pageY_Getter_(this);
  
  @DomName('Touch.radiusX')
  @DocsEditable()
  @Experimental() // untriaged
  num get _radiusX => _blink.BlinkTouch.instance.radiusX_Getter_(this);
  
  @DomName('Touch.radiusY')
  @DocsEditable()
  @Experimental() // untriaged
  num get _radiusY => _blink.BlinkTouch.instance.radiusY_Getter_(this);
  
  @DomName('Touch.rotationAngle')
  @DocsEditable()
  @Experimental() // untriaged
  num get rotationAngle => _blink.BlinkTouch.instance.rotationAngle_Getter_(this);
  
  @DomName('Touch.screenX')
  @DocsEditable()
  num get _screenX => _blink.BlinkTouch.instance.screenX_Getter_(this);
  
  @DomName('Touch.screenY')
  @DocsEditable()
  num get _screenY => _blink.BlinkTouch.instance.screenY_Getter_(this);
  
  @DomName('Touch.target')
  @DocsEditable()
  EventTarget get target => _convertNativeToDart_EventTarget(_blink.BlinkTouch.instance.target_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.instance.clientX_Getter_(this).round();
  int get __clientY => _blink.BlinkTouch.instance.clientY_Getter_(this).round();
  int get __screenX => _blink.BlinkTouch.instance.screenX_Getter_(this).round();
  int get __screenY => _blink.BlinkTouch.instance.screenY_Getter_(this).round();
  int get __pageX => _blink.BlinkTouch.instance.pageX_Getter_(this).round();
  int get __pageY => _blink.BlinkTouch.instance.pageY_Getter_(this).round();
  int get __radiusX => _blink.BlinkTouch.instance.radiusX_Getter_(this).round();
  int get __radiusY => _blink.BlinkTouch.instance.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;
    }
    TouchEvent e = document._createEvent("TouchEvent");
    e._initTouchEvent(touches, targetTouches, changedTouches, type, view,
        screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey);
    return e;
  }
  // To suppress missing implicit constructor warnings.
  factory TouchEvent._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  TouchEvent.internal_() : super.internal_();


  @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 DartHtmlDomObject 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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  TouchList.internal_() { }

  /// 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 _nativeIndexedGetter(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.


  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('TrackDefault')
@Experimental() // untriaged
class TrackDefault extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory TrackDefault._() { throw new UnsupportedError("Not supported"); }

  @DomName('TrackDefault.TrackDefault')
  @DocsEditable()
  factory TrackDefault(String type, String language, String label, List<String> kinds, [String byteStreamTrackID]) {
    if (byteStreamTrackID != null) {
      List kinds_1 = convertDartToNative_StringArray(kinds);
      return _blink.BlinkTrackDefault.instance.constructorCallback_5_(type, language, label, kinds_1, byteStreamTrackID);
    }
    List kinds_1 = convertDartToNative_StringArray(kinds);
    return _blink.BlinkTrackDefault.instance.constructorCallback_4_(type, language, label, kinds_1);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  TrackDefault.internal_() { }

  @DomName('TrackDefault.byteStreamTrackID')
  @DocsEditable()
  @Experimental() // untriaged
  String get byteStreamTrackID => _blink.BlinkTrackDefault.instance.byteStreamTrackID_Getter_(this);
  
  @DomName('TrackDefault.kinds')
  @DocsEditable()
  @Experimental() // untriaged
  List<String> get kinds => _blink.BlinkTrackDefault.instance.kinds_Getter_(this);
  
  @DomName('TrackDefault.label')
  @DocsEditable()
  @Experimental() // untriaged
  String get label => _blink.BlinkTrackDefault.instance.label_Getter_(this);
  
  @DomName('TrackDefault.language')
  @DocsEditable()
  @Experimental() // untriaged
  String get language => _blink.BlinkTrackDefault.instance.language_Getter_(this);
  
  @DomName('TrackDefault.type')
  @DocsEditable()
  @Experimental() // untriaged
  String get type => _blink.BlinkTrackDefault.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('TrackDefaultList')
@Experimental() // untriaged
class TrackDefaultList extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory TrackDefaultList._() { throw new UnsupportedError("Not supported"); }

  @DomName('TrackDefaultList.TrackDefaultList')
  @DocsEditable()
  factory TrackDefaultList([List<TrackDefault> trackDefaults]) {
    if (trackDefaults != null) {
      return _blink.BlinkTrackDefaultList.instance.constructorCallback_1_(trackDefaults);
    }
    return _blink.BlinkTrackDefaultList.instance.constructorCallback_0_();
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  TrackDefaultList.internal_() { }

  @DomName('TrackDefaultList.length')
  @DocsEditable()
  @Experimental() // untriaged
  int get length => _blink.BlinkTrackDefaultList.instance.length_Getter_(this);
  
  @DomName('TrackDefaultList.item')
  @DocsEditable()
  @Experimental() // untriaged
  TrackDefault item(int index) => _blink.BlinkTrackDefaultList.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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  TrackElement.internal_() : super.internal_();

  /**
   * 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()
  set defaultValue(bool value) => _blink.BlinkHTMLTrackElement.instance.default_Setter_(this, value);
  
  @DomName('HTMLTrackElement.kind')
  @DocsEditable()
  String get kind => _blink.BlinkHTMLTrackElement.instance.kind_Getter_(this);
  
  @DomName('HTMLTrackElement.kind')
  @DocsEditable()
  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()
  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()
  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()
  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.TrackEvent')
  @DocsEditable()
  factory TrackEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkTrackEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkTrackEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  TrackEvent.internal_() : super.internal_();


  @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.TransitionEvent')
  @DocsEditable()
  factory TransitionEvent(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkTransitionEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkTransitionEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  TransitionEvent.internal_() : super.internal_();


  @DomName('TransitionEvent.elapsedTime')
  @DocsEditable()
  num 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 DartHtmlDomObject {
  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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  TreeWalker.internal_() { }

  @DomName('TreeWalker.currentNode')
  @DocsEditable()
  Node get currentNode => _blink.BlinkTreeWalker.instance.currentNode_Getter_(this);
  
  @DomName('TreeWalker.currentNode')
  @DocsEditable()
  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;
    }
    UIEvent e = document._createEvent("UIEvent");
    e._initUIEvent(type, canBubble, cancelable, view, detail);
    return e;
  }

  @DomName('UIEvent.UIEvent')
  @DocsEditable()
  factory UIEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkUIEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkUIEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  UIEvent.internal_() : super.internal_();


  @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.sourceDevice')
  @DocsEditable()
  @Experimental() // untriaged
  InputDevice get sourceDevice => _blink.BlinkUIEvent.instance.sourceDevice_Getter_(this);
  
  @DomName('UIEvent.view')
  @DocsEditable()
  WindowBase get view => _convertNativeToDart_Window(_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 bubbles, bool cancelable, Window view, int detail) => _blink.BlinkUIEvent.instance.initUIEvent_Callback_5_(this, type, bubbles, cancelable, view, detail);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  UListElement.internal_() : super.internal_();

  /**
   * 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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  UnknownElement.internal_() : super.internal_();

  /**
   * 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 DartHtmlDomObject implements UrlUtils {
  // To suppress missing implicit constructor warnings.
  factory Url._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Url.internal_() { }

  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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 DartHtmlDomObject {
  // 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
  set hash(String value);

  @DomName('URLUtils.host')
  @DocsEditable()
  @Experimental() // untriaged
  String get host;

  @DomName('URLUtils.host')
  @DocsEditable()
  @Experimental() // untriaged
  set host(String value);

  @DomName('URLUtils.hostname')
  @DocsEditable()
  @Experimental() // untriaged
  String get hostname;

  @DomName('URLUtils.hostname')
  @DocsEditable()
  @Experimental() // untriaged
  set hostname(String value);

  @DomName('URLUtils.href')
  @DocsEditable()
  @Experimental() // untriaged
  String get href;

  @DomName('URLUtils.href')
  @DocsEditable()
  @Experimental() // untriaged
  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
  set password(String value);

  @DomName('URLUtils.pathname')
  @DocsEditable()
  @Experimental() // untriaged
  String get pathname;

  @DomName('URLUtils.pathname')
  @DocsEditable()
  @Experimental() // untriaged
  set pathname(String value);

  @DomName('URLUtils.port')
  @DocsEditable()
  @Experimental() // untriaged
  String get port;

  @DomName('URLUtils.port')
  @DocsEditable()
  @Experimental() // untriaged
  set port(String value);

  @DomName('URLUtils.protocol')
  @DocsEditable()
  @Experimental() // untriaged
  String get protocol;

  @DomName('URLUtils.protocol')
  @DocsEditable()
  @Experimental() // untriaged
  set protocol(String value);

  @DomName('URLUtils.search')
  @DocsEditable()
  @Experimental() // untriaged
  String get search;

  @DomName('URLUtils.search')
  @DocsEditable()
  @Experimental() // untriaged
  set search(String value);

  @DomName('URLUtils.username')
  @DocsEditable()
  @Experimental() // untriaged
  String get username;

  @DomName('URLUtils.username')
  @DocsEditable()
  @Experimental() // untriaged
  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 DartHtmlDomObject {
  // 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('VRDevice')
@Experimental() // untriaged
class VRDevice extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory VRDevice._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  VRDevice.internal_() { }

  @DomName('VRDevice.deviceId')
  @DocsEditable()
  @Experimental() // untriaged
  String get deviceId => _blink.BlinkVRDevice.instance.deviceId_Getter_(this);
  
  @DomName('VRDevice.deviceName')
  @DocsEditable()
  @Experimental() // untriaged
  String get deviceName => _blink.BlinkVRDevice.instance.deviceName_Getter_(this);
  
  @DomName('VRDevice.hardwareUnitId')
  @DocsEditable()
  @Experimental() // untriaged
  String get hardwareUnitId => _blink.BlinkVRDevice.instance.hardwareUnitId_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('VREyeParameters')
@Experimental() // untriaged
class VREyeParameters extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory VREyeParameters._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  VREyeParameters.internal_() { }

  @DomName('VREyeParameters.currentFieldOfView')
  @DocsEditable()
  @Experimental() // untriaged
  VRFieldOfView get currentFieldOfView => _blink.BlinkVREyeParameters.instance.currentFieldOfView_Getter_(this);
  
  @DomName('VREyeParameters.eyeTranslation')
  @DocsEditable()
  @Experimental() // untriaged
  DomPoint get eyeTranslation => _blink.BlinkVREyeParameters.instance.eyeTranslation_Getter_(this);
  
  @DomName('VREyeParameters.maximumFieldOfView')
  @DocsEditable()
  @Experimental() // untriaged
  VRFieldOfView get maximumFieldOfView => _blink.BlinkVREyeParameters.instance.maximumFieldOfView_Getter_(this);
  
  @DomName('VREyeParameters.minimumFieldOfView')
  @DocsEditable()
  @Experimental() // untriaged
  VRFieldOfView get minimumFieldOfView => _blink.BlinkVREyeParameters.instance.minimumFieldOfView_Getter_(this);
  
  @DomName('VREyeParameters.recommendedFieldOfView')
  @DocsEditable()
  @Experimental() // untriaged
  VRFieldOfView get recommendedFieldOfView => _blink.BlinkVREyeParameters.instance.recommendedFieldOfView_Getter_(this);
  
  @DomName('VREyeParameters.renderRect')
  @DocsEditable()
  @Experimental() // untriaged
  _DomRect get renderRect => _blink.BlinkVREyeParameters.instance.renderRect_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('VRFieldOfView')
@Experimental() // untriaged
class VRFieldOfView extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory VRFieldOfView._() { throw new UnsupportedError("Not supported"); }

  @DomName('VRFieldOfView.VRFieldOfView')
  @DocsEditable()
  factory VRFieldOfView([Map fov]) {
    if (fov != null) {
      var fov_1 = convertDartToNative_Dictionary(fov);
      return _blink.BlinkVRFieldOfView.instance.constructorCallback_1_(fov_1);
    }
    return _blink.BlinkVRFieldOfView.instance.constructorCallback_0_();
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  VRFieldOfView.internal_() { }

  @DomName('VRFieldOfView.downDegrees')
  @DocsEditable()
  @Experimental() // untriaged
  num get downDegrees => _blink.BlinkVRFieldOfView.instance.downDegrees_Getter_(this);
  
  @DomName('VRFieldOfView.downDegrees')
  @DocsEditable()
  @Experimental() // untriaged
  set downDegrees(num value) => _blink.BlinkVRFieldOfView.instance.downDegrees_Setter_(this, value);
  
  @DomName('VRFieldOfView.leftDegrees')
  @DocsEditable()
  @Experimental() // untriaged
  num get leftDegrees => _blink.BlinkVRFieldOfView.instance.leftDegrees_Getter_(this);
  
  @DomName('VRFieldOfView.leftDegrees')
  @DocsEditable()
  @Experimental() // untriaged
  set leftDegrees(num value) => _blink.BlinkVRFieldOfView.instance.leftDegrees_Setter_(this, value);
  
  @DomName('VRFieldOfView.rightDegrees')
  @DocsEditable()
  @Experimental() // untriaged
  num get rightDegrees => _blink.BlinkVRFieldOfView.instance.rightDegrees_Getter_(this);
  
  @DomName('VRFieldOfView.rightDegrees')
  @DocsEditable()
  @Experimental() // untriaged
  set rightDegrees(num value) => _blink.BlinkVRFieldOfView.instance.rightDegrees_Setter_(this, value);
  
  @DomName('VRFieldOfView.upDegrees')
  @DocsEditable()
  @Experimental() // untriaged
  num get upDegrees => _blink.BlinkVRFieldOfView.instance.upDegrees_Getter_(this);
  
  @DomName('VRFieldOfView.upDegrees')
  @DocsEditable()
  @Experimental() // untriaged
  set upDegrees(num value) => _blink.BlinkVRFieldOfView.instance.upDegrees_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('VRPositionState')
@Experimental() // untriaged
class VRPositionState extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory VRPositionState._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  VRPositionState.internal_() { }

  @DomName('VRPositionState.angularAcceleration')
  @DocsEditable()
  @Experimental() // untriaged
  DomPoint get angularAcceleration => _blink.BlinkVRPositionState.instance.angularAcceleration_Getter_(this);
  
  @DomName('VRPositionState.angularVelocity')
  @DocsEditable()
  @Experimental() // untriaged
  DomPoint get angularVelocity => _blink.BlinkVRPositionState.instance.angularVelocity_Getter_(this);
  
  @DomName('VRPositionState.linearAcceleration')
  @DocsEditable()
  @Experimental() // untriaged
  DomPoint get linearAcceleration => _blink.BlinkVRPositionState.instance.linearAcceleration_Getter_(this);
  
  @DomName('VRPositionState.linearVelocity')
  @DocsEditable()
  @Experimental() // untriaged
  DomPoint get linearVelocity => _blink.BlinkVRPositionState.instance.linearVelocity_Getter_(this);
  
  @DomName('VRPositionState.orientation')
  @DocsEditable()
  @Experimental() // untriaged
  DomPoint get orientation => _blink.BlinkVRPositionState.instance.orientation_Getter_(this);
  
  @DomName('VRPositionState.position')
  @DocsEditable()
  @Experimental() // untriaged
  DomPoint get position => _blink.BlinkVRPositionState.instance.position_Getter_(this);
  
  @DomName('VRPositionState.timeStamp')
  @DocsEditable()
  @Experimental() // untriaged
  num get timeStamp => _blink.BlinkVRPositionState.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('ValidityState')
class ValidityState extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory ValidityState._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  ValidityState.internal_() { }

  @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.tooShort')
  @DocsEditable()
  @Experimental() // untriaged
  bool get tooShort => _blink.BlinkValidityState.instance.tooShort_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");


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  VideoElement.internal_() : super.internal_();

  /**
   * 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()
  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()
  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()
  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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory VideoPlaybackQuality._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  VideoPlaybackQuality.internal_() { }

  @DomName('VideoPlaybackQuality.corruptedVideoFrames')
  @DocsEditable()
  @Experimental() // untriaged
  int get corruptedVideoFrames => _blink.BlinkVideoPlaybackQuality.instance.corruptedVideoFrames_Getter_(this);
  
  @DomName('VideoPlaybackQuality.creationTime')
  @DocsEditable()
  @Experimental() // untriaged
  num 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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory VideoTrack._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  VideoTrack.internal_() { }

  @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
  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');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  VideoTrackList.internal_() : super.internal_();


  @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);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  VttCue.internal_() : super.internal_();


  @DomName('VTTCue.align')
  @DocsEditable()
  @Experimental() // untriaged
  String get align => _blink.BlinkVTTCue.instance.align_Getter_(this);
  
  @DomName('VTTCue.align')
  @DocsEditable()
  @Experimental() // untriaged
  set align(String value) => _blink.BlinkVTTCue.instance.align_Setter_(this, value);
  
  @DomName('VTTCue.line')
  @DocsEditable()
  @Experimental() // untriaged
  Object get line => (_blink.BlinkVTTCue.instance.line_Getter_(this));
  
  @DomName('VTTCue.line')
  @DocsEditable()
  @Experimental() // untriaged
  set line(Object value) => _blink.BlinkVTTCue.instance.line_Setter_(this, value);
  
  @DomName('VTTCue.position')
  @DocsEditable()
  @Experimental() // untriaged
  Object get position => (_blink.BlinkVTTCue.instance.position_Getter_(this));
  
  @DomName('VTTCue.position')
  @DocsEditable()
  @Experimental() // untriaged
  set position(Object 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
  set regionId(String value) => _blink.BlinkVTTCue.instance.regionId_Setter_(this, value);
  
  @DomName('VTTCue.size')
  @DocsEditable()
  @Experimental() // untriaged
  num get size => _blink.BlinkVTTCue.instance.size_Getter_(this);
  
  @DomName('VTTCue.size')
  @DocsEditable()
  @Experimental() // untriaged
  set size(num 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
  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
  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
  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 DartHtmlDomObject {
  // 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_();
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  VttRegion.internal_() { }

  @DomName('VTTRegion.height')
  @DocsEditable()
  @Experimental() // untriaged
  int get height => _blink.BlinkVTTRegion.instance.height_Getter_(this);
  
  @DomName('VTTRegion.height')
  @DocsEditable()
  @Experimental() // untriaged
  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
  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
  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
  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
  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
  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
  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
  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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory VttRegionList._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  VttRegionList.internal_() { }

  @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, [Object protocols]) {
    if (protocols != null) {
      return _blink.BlinkWebSocket.instance.constructorCallback_2_(url, protocols);
    }
    return _blink.BlinkWebSocket.instance.constructorCallback_1_(url);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  WebSocket.internal_() : super.internal_();


  /// 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()
  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)) {
      _blink.BlinkWebSocket.instance.send_Callback_1_(this, data);
      return;
    }
    if ((data is Blob)) {
      _blink.BlinkWebSocket.instance.send_Callback_1_(this, data);
      return;
    }
    if ((data is TypedData)) {
      _blink.BlinkWebSocket.instance.send_Callback_1_(this, data);
      return;
    }
    if ((data is ByteBuffer)) {
      _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, num deltaX: 0, num deltaY: 0, num deltaZ: 0,
      int deltaMode: 0,
      int detail: 0, int screenX: 0, int screenY: 0, int clientX: 0,
      int clientY: 0, int button: 0, bool canBubble: true,
      bool cancelable: true, bool ctrlKey: false, bool altKey: false,
      bool shiftKey: false, bool metaKey: false, EventTarget relatedTarget}) {

    var options = {
      'view': view,
      'deltaMode': deltaMode,
      'deltaX': deltaX,
      'deltaY': deltaY,
      'deltaZ': deltaZ,
      'detail': detail,
      'screenX': screenX,
      'screenY': screenY,
      'clientX': clientX,
      'clientY': clientY,
      'button': button,
      'bubbles': canBubble,
      'cancelable': cancelable,
      'ctrlKey': ctrlKey,
      'altKey': altKey,
      'shiftKey': shiftKey,
      'metaKey': metaKey,
      'relatedTarget': relatedTarget,
    };

    return _blink.BlinkWheelEvent.instance.constructorCallback_2_(type, convertDartToNative_Dictionary(options));
  }


  @DomName('WheelEvent.WheelEvent')
  @DocsEditable()
  factory WheelEvent._(String type, [Map eventInitDict]) {
    if (eventInitDict != null) {
      var eventInitDict_1 = convertDartToNative_Dictionary(eventInitDict);
      return _blink.BlinkWheelEvent.instance.constructorCallback_2_(type, eventInitDict_1);
    }
    return _blink.BlinkWheelEvent.instance.constructorCallback_1_(type);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  WheelEvent.internal_() : super.internal_();


  @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()
  num get _deltaX => _blink.BlinkWheelEvent.instance.deltaX_Getter_(this);
  
  @DomName('WheelEvent.deltaY')
  @DocsEditable()
  num get _deltaY => _blink.BlinkWheelEvent.instance.deltaY_Getter_(this);
  
  @DomName('WheelEvent.deltaZ')
  @DocsEditable()
  num get deltaZ => _blink.BlinkWheelEvent.instance.deltaZ_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(FrameRequestCallback 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');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Window.internal_() : super.internal_();


  /**
   * Indicates that file system data cannot be cleared unless given user
   * permission.
   *
   * ## Other resources
   *
   * * [Exploring the FileSystem
   *   APIs](http://www.html5rocks.com/en/tutorials/file/filesystem/)
   *   from HTML5Rocks.
   * * [File API](http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem)
   *   from W3C.
   */
  @DomName('Window.PERSISTENT')
  @DocsEditable()
  // http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem
  @Experimental()
  static const int PERSISTENT = 1;

  /**
   * Indicates that file system data can be cleared at any time.
   *
   * ## Other resources
   *
   * * [Exploring the FileSystem
   *   APIs](http://www.html5rocks.com/en/tutorials/file/filesystem/) from HTML5Rocks.
   * * [File API](http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem)
   *   from W3C.
   */
  @DomName('Window.TEMPORARY')
  @DocsEditable()
  // http://www.w3.org/TR/file-system-api/#idl-def-LocalFileSystem
  @Experimental()
  static const int TEMPORARY = 0;

  /**
   * The application cache for this window.
   *
   * ## Other resources
   *
   * * [A beginner's guide to using the application
   *   cache](http://www.html5rocks.com/en/tutorials/appcache/beginner)
   *   from HTML5Rocks.
   * * [Application cache
   *   API](https://html.spec.whatwg.org/multipage/browsers.html#application-cache-api)
   *   from WHATWG.
   */
  @DomName('Window.applicationCache')
  @DocsEditable()
  ApplicationCache get applicationCache => _blink.BlinkWindow.instance.applicationCache_Getter_(this);
  
  @DomName('Window.caches')
  @DocsEditable()
  @Experimental() // untriaged
  CacheStorage get caches => _blink.BlinkWindow.instance.caches_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
  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
  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
  num 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](https://html.spec.whatwg.org/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](https://html.spec.whatwg.org/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](https://html.spec.whatwg.org/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()
  set name(String value) => _blink.BlinkWindow.instance.name_Setter_(this, value);
  
  /**
   * The user agent accessing this window.
   *
   * ## Other resources
   *
   * * [The navigator
   *   object](https://html.spec.whatwg.org/multipage/webappapis.html#the-navigator-object)
   *   from WHATWG.
   */
  @DomName('Window.navigator')
  @DocsEditable()
  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 => _convertNativeToDart_Window(_blink.BlinkWindow.instance.opener_Getter_(this));
  
  @DomName('Window.opener')
  @DocsEditable()
  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()
  num 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()
  num get _pageYOffset => _blink.BlinkWindow.instance.pageYOffset_Getter_(this);
  
  @DomName('Window.parent')
  @DocsEditable()
  WindowBase get parent => _convertNativeToDart_Window(_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()
  num get _scrollX => _blink.BlinkWindow.instance.scrollX_Getter_(this);
  
  @DomName('Window.scrollY')
  @DocsEditable()
  num get _scrollY => _blink.BlinkWindow.instance.scrollY_Getter_(this);
  
  /**
   * This window's scroll bars.
   *
   * ## Other resources
   *
   * * [Browser interface
   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
   *   from WHATWG.
   */
  @DomName('Window.scrollbars')
  @DocsEditable()
  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 => _convertNativeToDart_Window(_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()
  set status(String value) => _blink.BlinkWindow.instance.status_Setter_(this, value);
  
  /**
   * This window's status bar.
   *
   * ## Other resources
   *
   * * [Browser interface
   *   elements](https://html.spec.whatwg.org/multipage/browsers.html#browser-interface-elements)
   *   from WHATWG.
   */
  @DomName('Window.statusbar')
  @DocsEditable()
  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/)
   *   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](https://html.spec.whatwg.org/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 => _convertNativeToDart_Window(_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 => _convertNativeToDart_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 handle) => _blink.BlinkWindow.instance.cancelAnimationFrame_Callback_1_(this, handle);
  
  @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);
  }

  Future fetch(/*RequestInfo*/ input, [Map init]) {
    if (init != null) {
      return _blink.BlinkWindow.instance.fetch_Callback_2_(this, input, convertDartToNative_Dictionary(init));
    }
    return _blink.BlinkWindow.instance.fetch_Callback_1_(this, input);
  }

  /**
   * 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 elt, String pseudoElt) => _blink.BlinkWindow.instance.getComputedStyle_Callback_2_(this, elt, pseudoElt);
  
  /**
   * 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(int x, int y) => _blink.BlinkWindow.instance.moveBy_Callback_2_(this, x, y);
  
  @DomName('Window.moveTo')
  @DocsEditable()
  void _moveTo(int x, int y) => _blink.BlinkWindow.instance.moveTo_Callback_2_(this, x, y);
  
  @DomName('Window.open')
  @DocsEditable()
  WindowBase open(String url, String target, [String features]) => _convertNativeToDart_Window(_blink.BlinkWindow.instance.open_Callback_3_(this, url, target, features));
  
  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(Object message, String targetOrigin, [List<MessagePort> transfer]) => _blink.BlinkWindow.instance.postMessage_Callback_3_(this, convertDartToNative_SerializedScriptValue(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(FrameRequestCallback 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(int x, int 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(int x, int y) => _blink.BlinkWindow.instance.resizeTo_Callback_2_(this, x, y);
  
  void scroll([options_OR_x, y, Map scrollOptions]) {
    if (options_OR_x == null && y == null && scrollOptions == null) {
      _blink.BlinkWindow.instance.scroll_Callback_0_(this);
      return;
    }
    if ((options_OR_x is Map) && y == null && scrollOptions == null) {
      _blink.BlinkWindow.instance.scroll_Callback_1_(this, options_OR_x);
      return;
    }
    if ((y is num) && (options_OR_x is num) && scrollOptions == null) {
      _blink.BlinkWindow.instance.scroll_Callback_2_(this, options_OR_x, y);
      return;
    }
    if ((y is int) && (options_OR_x is int) && scrollOptions == null) {
      _blink.BlinkWindow.instance.scroll_Callback_2_(this, options_OR_x, y);
      return;
    }
    if ((scrollOptions is Map) && (y is int) && (options_OR_x is int)) {
      _blink.BlinkWindow.instance.scroll_Callback_3_(this, options_OR_x, y, convertDartToNative_Dictionary(scrollOptions));
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  void scrollBy([options_OR_x, y, Map scrollOptions]) {
    if (options_OR_x == null && y == null && scrollOptions == null) {
      _blink.BlinkWindow.instance.scrollBy_Callback_0_(this);
      return;
    }
    if ((options_OR_x is Map) && y == null && scrollOptions == null) {
      _blink.BlinkWindow.instance.scrollBy_Callback_1_(this, options_OR_x);
      return;
    }
    if ((y is num) && (options_OR_x is num) && scrollOptions == null) {
      _blink.BlinkWindow.instance.scrollBy_Callback_2_(this, options_OR_x, y);
      return;
    }
    if ((y is int) && (options_OR_x is int) && scrollOptions == null) {
      _blink.BlinkWindow.instance.scrollBy_Callback_2_(this, options_OR_x, y);
      return;
    }
    if ((scrollOptions is Map) && (y is int) && (options_OR_x is int)) {
      _blink.BlinkWindow.instance.scrollBy_Callback_3_(this, options_OR_x, y, convertDartToNative_Dictionary(scrollOptions));
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  void scrollTo([options_OR_x, y, Map scrollOptions]) {
    if (options_OR_x == null && y == null && scrollOptions == null) {
      _blink.BlinkWindow.instance.scrollTo_Callback_0_(this);
      return;
    }
    if ((options_OR_x is Map) && y == null && scrollOptions == null) {
      _blink.BlinkWindow.instance.scrollTo_Callback_1_(this, options_OR_x);
      return;
    }
    if ((y is num) && (options_OR_x is num) && scrollOptions == null) {
      _blink.BlinkWindow.instance.scrollTo_Callback_2_(this, options_OR_x, y);
      return;
    }
    if ((y is int) && (options_OR_x is int) && scrollOptions == null) {
      _blink.BlinkWindow.instance.scrollTo_Callback_2_(this, options_OR_x, y);
      return;
    }
    if ((scrollOptions is Map) && (y is int) && (options_OR_x is int)) {
      _blink.BlinkWindow.instance.scrollTo_Callback_3_(this, options_OR_x, y, convertDartToNative_Dictionary(scrollOptions));
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  /**
   * 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 atob) => _blink.BlinkWindow.instance.atob_Callback_1_(this, atob);
  
  @DomName('Window.btoa')
  @DocsEditable()
  String btoa(String btoa) => _blink.BlinkWindow.instance.btoa_Callback_1_(this, btoa);
  
  int _setInterval_String(String handler, [int timeout, Object arguments]) {
    if (timeout != null) {
      return _blink.BlinkWindow.instance.setInterval_Callback_3_(this, handler, timeout, arguments);
    }
    return _blink.BlinkWindow.instance.setInterval_Callback_1_(this, handler);
  }

  int _setTimeout_String(String handler, [int timeout, Object arguments]) {
    if (timeout != null) {
      return _blink.BlinkWindow.instance.setTimeout_Callback_3_(this, handler, timeout, arguments);
    }
    return _blink.BlinkWindow.instance.setTimeout_Callback_1_(this, handler);
  }

  void _clearInterval([int handle]) {
    if (handle != null) {
      _blink.BlinkWindow.instance.clearInterval_Callback_1_(this, handle);
      return;
    }
    _blink.BlinkWindow.instance.clearInterval_Callback_0_(this);
    return;
  }

  void _clearTimeout([int handle]) {
    if (handle != null) {
      _blink.BlinkWindow.instance.clearTimeout_Callback_1_(this, handle);
      return;
    }
    _blink.BlinkWindow.instance.clearTimeout_Callback_0_(this);
    return;
  }

  int _setInterval(Object handler, [int timeout]) {
    if (timeout != null) {
      return _blink.BlinkWindow.instance.setInterval_Callback_2_(this, handler, timeout);
    }
    return _blink.BlinkWindow.instance.setInterval_Callback_1_(this, handler);
  }

  int _setTimeout(Object handler, [int timeout]) {
    if (timeout != null) {
      return _blink.BlinkWindow.instance.setTimeout_Callback_2_(this, handler, timeout);
    }
    return _blink.BlinkWindow.instance.setTimeout_Callback_1_(this, handler);
  }

  /// Stream of `contentloaded` events handled by this [Window].
  @DomName('Window.onDOMContentLoaded')
  @DocsEditable()
  Stream<Event> get onContentLoaded => contentLoadedEvent.forTarget(this);

  /// Stream of `abort` events handled by this [Window].
  @DomName('Window.onabort')
  @DocsEditable()
  Stream<Event> get onAbort => Element.abortEvent.forTarget(this);

  /// Stream of `blur` events handled by this [Window].
  @DomName('Window.onblur')
  @DocsEditable()
  Stream<Event> get onBlur => Element.blurEvent.forTarget(this);

  @DomName('Window.oncanplay')
  @DocsEditable()
  Stream<Event> get onCanPlay => Element.canPlayEvent.forTarget(this);

  @DomName('Window.oncanplaythrough')
  @DocsEditable()
  Stream<Event> get onCanPlayThrough => Element.canPlayThroughEvent.forTarget(this);

  /// Stream of `change` events handled by this [Window].
  @DomName('Window.onchange')
  @DocsEditable()
  Stream<Event> get onChange => Element.changeEvent.forTarget(this);

  /// Stream of `click` events handled by this [Window].
  @DomName('Window.onclick')
  @DocsEditable()
  Stream<MouseEvent> get onClick => Element.clickEvent.forTarget(this);

  /// Stream of `contextmenu` events handled by this [Window].
  @DomName('Window.oncontextmenu')
  @DocsEditable()
  Stream<MouseEvent> get onContextMenu => Element.contextMenuEvent.forTarget(this);

  /// Stream of `doubleclick` events handled by this [Window].
  @DomName('Window.ondblclick')
  @DocsEditable()
  Stream<Event> get onDoubleClick => Element.doubleClickEvent.forTarget(this);

  /// Stream of `devicemotion` events handled by this [Window].
  @DomName('Window.ondevicemotion')
  @DocsEditable()
  // http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
  @Experimental()
  Stream<DeviceMotionEvent> get onDeviceMotion => deviceMotionEvent.forTarget(this);

  /// Stream of `deviceorientation` events handled by this [Window].
  @DomName('Window.ondeviceorientation')
  @DocsEditable()
  // http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
  @Experimental()
  Stream<DeviceOrientationEvent> get onDeviceOrientation => deviceOrientationEvent.forTarget(this);

  /// Stream of `drag` events handled by this [Window].
  @DomName('Window.ondrag')
  @DocsEditable()
  Stream<MouseEvent> get onDrag => Element.dragEvent.forTarget(this);

  /// Stream of `dragend` events handled by this [Window].
  @DomName('Window.ondragend')
  @DocsEditable()
  Stream<MouseEvent> get onDragEnd => Element.dragEndEvent.forTarget(this);

  /// Stream of `dragenter` events handled by this [Window].
  @DomName('Window.ondragenter')
  @DocsEditable()
  Stream<MouseEvent> get onDragEnter => Element.dragEnterEvent.forTarget(this);

  /// Stream of `dragleave` events handled by this [Window].
  @DomName('Window.ondragleave')
  @DocsEditable()
  Stream<MouseEvent> get onDragLeave => Element.dragLeaveEvent.forTarget(this);

  /// Stream of `dragover` events handled by this [Window].
  @DomName('Window.ondragover')
  @DocsEditable()
  Stream<MouseEvent> get onDragOver => Element.dragOverEvent.forTarget(this);

  /// Stream of `dragstart` events handled by this [Window].
  @DomName('Window.ondragstart')
  @DocsEditable()
  Stream<MouseEvent> get onDragStart => Element.dragStartEvent.forTarget(this);

  /// Stream of `drop` events handled by this [Window].
  @DomName('Window.ondrop')
  @DocsEditable()
  Stream<MouseEvent> get onDrop => Element.dropEvent.forTarget(this);

  @DomName('Window.ondurationchange')
  @DocsEditable()
  Stream<Event> get onDurationChange => Element.durationChangeEvent.forTarget(this);

  @DomName('Window.onemptied')
  @DocsEditable()
  Stream<Event> get onEmptied => Element.emptiedEvent.forTarget(this);

  @DomName('Window.onended')
  @DocsEditable()
  Stream<Event> get onEnded => Element.endedEvent.forTarget(this);

  /// Stream of `error` events handled by this [Window].
  @DomName('Window.onerror')
  @DocsEditable()
  Stream<Event> get onError => Element.errorEvent.forTarget(this);

  /// Stream of `focus` events handled by this [Window].
  @DomName('Window.onfocus')
  @DocsEditable()
  Stream<Event> get onFocus => Element.focusEvent.forTarget(this);

  /// Stream of `hashchange` events handled by this [Window].
  @DomName('Window.onhashchange')
  @DocsEditable()
  Stream<Event> get onHashChange => hashChangeEvent.forTarget(this);

  /// Stream of `input` events handled by this [Window].
  @DomName('Window.oninput')
  @DocsEditable()
  Stream<Event> get onInput => Element.inputEvent.forTarget(this);

  /// Stream of `invalid` events handled by this [Window].
  @DomName('Window.oninvalid')
  @DocsEditable()
  Stream<Event> get onInvalid => Element.invalidEvent.forTarget(this);

  /// Stream of `keydown` events handled by this [Window].
  @DomName('Window.onkeydown')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyDown => Element.keyDownEvent.forTarget(this);

  /// Stream of `keypress` events handled by this [Window].
  @DomName('Window.onkeypress')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyPress => Element.keyPressEvent.forTarget(this);

  /// Stream of `keyup` events handled by this [Window].
  @DomName('Window.onkeyup')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyUp => Element.keyUpEvent.forTarget(this);

  /// Stream of `load` events handled by this [Window].
  @DomName('Window.onload')
  @DocsEditable()
  Stream<Event> get onLoad => Element.loadEvent.forTarget(this);

  @DomName('Window.onloadeddata')
  @DocsEditable()
  Stream<Event> get onLoadedData => Element.loadedDataEvent.forTarget(this);

  @DomName('Window.onloadedmetadata')
  @DocsEditable()
  Stream<Event> get onLoadedMetadata => Element.loadedMetadataEvent.forTarget(this);

  @DomName('Window.onloadstart')
  @DocsEditable()
  Stream<Event> get onLoadStart => loadStartEvent.forTarget(this);

  /// Stream of `message` events handled by this [Window].
  @DomName('Window.onmessage')
  @DocsEditable()
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

  /// Stream of `mousedown` events handled by this [Window].
  @DomName('Window.onmousedown')
  @DocsEditable()
  Stream<MouseEvent> get onMouseDown => Element.mouseDownEvent.forTarget(this);

  /// Stream of `mouseenter` events handled by this [Window].
  @DomName('Window.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseEnter => Element.mouseEnterEvent.forTarget(this);

  /// Stream of `mouseleave` events handled by this [Window].
  @DomName('Window.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseLeave => Element.mouseLeaveEvent.forTarget(this);

  /// Stream of `mousemove` events handled by this [Window].
  @DomName('Window.onmousemove')
  @DocsEditable()
  Stream<MouseEvent> get onMouseMove => Element.mouseMoveEvent.forTarget(this);

  /// Stream of `mouseout` events handled by this [Window].
  @DomName('Window.onmouseout')
  @DocsEditable()
  Stream<MouseEvent> get onMouseOut => Element.mouseOutEvent.forTarget(this);

  /// Stream of `mouseover` events handled by this [Window].
  @DomName('Window.onmouseover')
  @DocsEditable()
  Stream<MouseEvent> get onMouseOver => Element.mouseOverEvent.forTarget(this);

  /// Stream of `mouseup` events handled by this [Window].
  @DomName('Window.onmouseup')
  @DocsEditable()
  Stream<MouseEvent> get onMouseUp => Element.mouseUpEvent.forTarget(this);

  /// Stream of `mousewheel` events handled by this [Window].
  @DomName('Window.onmousewheel')
  @DocsEditable()
  Stream<WheelEvent> get onMouseWheel => Element.mouseWheelEvent.forTarget(this);

  /// Stream of `offline` events handled by this [Window].
  @DomName('Window.onoffline')
  @DocsEditable()
  Stream<Event> get onOffline => offlineEvent.forTarget(this);

  /// Stream of `online` events handled by this [Window].
  @DomName('Window.ononline')
  @DocsEditable()
  Stream<Event> get onOnline => onlineEvent.forTarget(this);

  /// Stream of `pagehide` events handled by this [Window].
  @DomName('Window.onpagehide')
  @DocsEditable()
  Stream<Event> get onPageHide => pageHideEvent.forTarget(this);

  /// Stream of `pageshow` events handled by this [Window].
  @DomName('Window.onpageshow')
  @DocsEditable()
  Stream<Event> get onPageShow => pageShowEvent.forTarget(this);

  @DomName('Window.onpause')
  @DocsEditable()
  Stream<Event> get onPause => Element.pauseEvent.forTarget(this);

  @DomName('Window.onplay')
  @DocsEditable()
  Stream<Event> get onPlay => Element.playEvent.forTarget(this);

  @DomName('Window.onplaying')
  @DocsEditable()
  Stream<Event> get onPlaying => Element.playingEvent.forTarget(this);

  /// Stream of `popstate` events handled by this [Window].
  @DomName('Window.onpopstate')
  @DocsEditable()
  Stream<PopStateEvent> get onPopState => popStateEvent.forTarget(this);

  @DomName('Window.onprogress')
  @DocsEditable()
  Stream<Event> get onProgress => progressEvent.forTarget(this);

  @DomName('Window.onratechange')
  @DocsEditable()
  Stream<Event> get onRateChange => Element.rateChangeEvent.forTarget(this);

  /// Stream of `reset` events handled by this [Window].
  @DomName('Window.onreset')
  @DocsEditable()
  Stream<Event> get onReset => Element.resetEvent.forTarget(this);

  /// Stream of `resize` events handled by this [Window].
  @DomName('Window.onresize')
  @DocsEditable()
  Stream<Event> get onResize => Element.resizeEvent.forTarget(this);

  /// Stream of `scroll` events handled by this [Window].
  @DomName('Window.onscroll')
  @DocsEditable()
  Stream<Event> get onScroll => Element.scrollEvent.forTarget(this);

  /// Stream of `search` events handled by this [Window].
  @DomName('Window.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  Stream<Event> get onSearch => Element.searchEvent.forTarget(this);

  @DomName('Window.onseeked')
  @DocsEditable()
  Stream<Event> get onSeeked => Element.seekedEvent.forTarget(this);

  @DomName('Window.onseeking')
  @DocsEditable()
  Stream<Event> get onSeeking => Element.seekingEvent.forTarget(this);

  /// Stream of `select` events handled by this [Window].
  @DomName('Window.onselect')
  @DocsEditable()
  Stream<Event> get onSelect => Element.selectEvent.forTarget(this);

  @DomName('Window.onstalled')
  @DocsEditable()
  Stream<Event> get onStalled => Element.stalledEvent.forTarget(this);

  /// Stream of `storage` events handled by this [Window].
  @DomName('Window.onstorage')
  @DocsEditable()
  Stream<StorageEvent> get onStorage => storageEvent.forTarget(this);

  /// Stream of `submit` events handled by this [Window].
  @DomName('Window.onsubmit')
  @DocsEditable()
  Stream<Event> get onSubmit => Element.submitEvent.forTarget(this);

  @DomName('Window.onsuspend')
  @DocsEditable()
  Stream<Event> get onSuspend => Element.suspendEvent.forTarget(this);

  @DomName('Window.ontimeupdate')
  @DocsEditable()
  Stream<Event> get onTimeUpdate => Element.timeUpdateEvent.forTarget(this);

  /// Stream of `touchcancel` events handled by this [Window].
  @DomName('Window.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchCancel => Element.touchCancelEvent.forTarget(this);

  /// Stream of `touchend` events handled by this [Window].
  @DomName('Window.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchEnd => Element.touchEndEvent.forTarget(this);

  /// Stream of `touchmove` events handled by this [Window].
  @DomName('Window.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchMove => Element.touchMoveEvent.forTarget(this);

  /// Stream of `touchstart` events handled by this [Window].
  @DomName('Window.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchStart => Element.touchStartEvent.forTarget(this);

  /// Stream of `transitionend` events handled by this [Window].
  @DomName('Window.ontransitionend')
  @DocsEditable()
  Stream<TransitionEvent> get onTransitionEnd => Element.transitionEndEvent.forTarget(this);

  /// Stream of `unload` events handled by this [Window].
  @DomName('Window.onunload')
  @DocsEditable()
  Stream<Event> get onUnload => unloadEvent.forTarget(this);

  @DomName('Window.onvolumechange')
  @DocsEditable()
  Stream<Event> get onVolumeChange => Element.volumeChangeEvent.forTarget(this);

  @DomName('Window.onwaiting')
  @DocsEditable()
  Stream<Event> get onWaiting => Element.waitingEvent.forTarget(this);

  /// Stream of `animationend` events handled by this [Window].
  @DomName('Window.onwebkitAnimationEnd')
  @DocsEditable()
  @Experimental()
  Stream<AnimationEvent> get onAnimationEnd => animationEndEvent.forTarget(this);

  /// Stream of `animationiteration` events handled by this [Window].
  @DomName('Window.onwebkitAnimationIteration')
  @DocsEditable()
  @Experimental()
  Stream<AnimationEvent> get onAnimationIteration => animationIterationEvent.forTarget(this);

  /// Stream of `animationstart` events handled by this [Window].
  @DomName('Window.onwebkitAnimationStart')
  @DocsEditable()
  @Experimental()
  Stream<AnimationEvent> get onAnimationStart => animationStartEvent.forTarget(this);


  /**
   * Static factory designed to expose `beforeunload` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.beforeunloadEvent')
  static const EventStreamProvider<BeforeUnloadEvent> beforeUnloadEvent =
      const _BeforeUnloadEventStreamProvider('beforeunload');

  /// Stream of `beforeunload` events handled by this [Window].
  @DomName('Window.onbeforeunload')
  Stream<Event> get onBeforeUnload => beforeUnloadEvent.forTarget(this);

  /**
   * Moves this window to a specific position.
   *
   * x and y can be negative.
   *
   * ## Other resources
   *
   * * [Window.moveTo](https://developer.mozilla.org/en-US/docs/Web/API/Window.moveTo)
   *   from MDN.
   * * [Window.moveTo](http://dev.w3.org/csswg/cssom-view/#dom-window-moveto)
   *   from W3C.
   */
  void moveTo(Point p) {
    _moveTo(p.x, p.y);
  }

  @DomName('Window.pageXOffset')
  @DocsEditable()
  int get pageXOffset => _blink.BlinkWindow.instance.pageXOffset_Getter_(this).round();

  @DomName('Window.pageYOffset')
  @DocsEditable()
  int get pageYOffset => _blink.BlinkWindow.instance.pageYOffset_Getter_(this).round();

  @DomName('Window.scrollX')
  @DocsEditable()
  int get scrollX => _blink.BlinkWindow.instance.scrollX_Getter_(this).round();

  @DomName('Window.scrollY')
  @DocsEditable()
  int get scrollY => _blink.BlinkWindow.instance.scrollY_Getter_(this).round();
}


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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory WindowBase64._() { throw new UnsupportedError("Not supported"); }

  @DomName('WindowBase64.atob')
  @DocsEditable()
  @Experimental() // untriaged
  String atob(String atob);

  @DomName('WindowBase64.btoa')
  @DocsEditable()
  @Experimental() // untriaged
  String btoa(String btoa);

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('WindowClient')
@Experimental() // untriaged
class WindowClient extends Client {
  // To suppress missing implicit constructor warnings.
  factory WindowClient._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  WindowClient.internal_() : super.internal_();


  @DomName('WindowClient.focused')
  @DocsEditable()
  @Experimental() // untriaged
  bool get focused => _blink.BlinkWindowClient.instance.focused_Getter_(this);
  
  @DomName('WindowClient.visibilityState')
  @DocsEditable()
  @Experimental() // untriaged
  String get visibilityState => _blink.BlinkWindowClient.instance.visibilityState_Getter_(this);
  
  @DomName('WindowClient.focus')
  @DocsEditable()
  @Experimental() // untriaged
  Future focus() => convertNativePromiseToDartFuture(_blink.BlinkWindowClient.instance.focus_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.


@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);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  Worker.internal_() : super.internal_();


  /// Checks if this type is supported on the current platform.
  static bool get supported => true;

  void postMessage(/*SerializedScriptValue*/ message, [List<MessagePort> transfer]) {
    if (transfer != null) {
      _blink.BlinkWorker.instance.postMessage_Callback_2_(this, convertDartToNative_SerializedScriptValue(message), transfer);
      return;
    }
    _blink.BlinkWorker.instance.postMessage_Callback_1_(this, convertDartToNative_SerializedScriptValue(message));
    return;
  }

  @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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  WorkerConsole.internal_() : super.internal_();


}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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');


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  WorkerGlobalScope.internal_() : super.internal_();


  @DomName('WorkerGlobalScope.PERSISTENT')
  @DocsEditable()
  @Experimental() // untriaged
  static const int PERSISTENT = 1;

  @DomName('WorkerGlobalScope.TEMPORARY')
  @DocsEditable()
  @Experimental() // untriaged
  static const int TEMPORARY = 0;

  @DomName('WorkerGlobalScope.caches')
  @DocsEditable()
  @Experimental() // untriaged
  CacheStorage get caches => _blink.BlinkWorkerGlobalScope.instance.caches_Getter_(this);
  
  @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);
  
  Future fetch(/*RequestInfo*/ input, [Map init]) {
    if (init != null) {
      return _blink.BlinkWorkerGlobalScope.instance.fetch_Callback_2_(this, input, convertDartToNative_Dictionary(init));
    }
    return _blink.BlinkWorkerGlobalScope.instance.fetch_Callback_1_(this, input);
  }

  @DomName('WorkerGlobalScope.importScripts')
  @DocsEditable()
  @Experimental() // untriaged
  void importScripts(String urls) => _blink.BlinkWorkerGlobalScope.instance.importScripts_Callback_1_(this, urls);
  
  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 atob) => _blink.BlinkWorkerGlobalScope.instance.atob_Callback_1_(this, atob);
  
  @DomName('WorkerGlobalScope.btoa')
  @DocsEditable()
  @Experimental() // untriaged
  String btoa(String btoa) => _blink.BlinkWorkerGlobalScope.instance.btoa_Callback_1_(this, btoa);
  
  int _setInterval_String(String handler, [int timeout, Object arguments]) {
    if (timeout != null) {
      return _blink.BlinkWorkerGlobalScope.instance.setInterval_Callback_3_(this, handler, timeout, arguments);
    }
    return _blink.BlinkWorkerGlobalScope.instance.setInterval_Callback_1_(this, handler);
  }

  int _setTimeout_String(String handler, [int timeout, Object arguments]) {
    if (timeout != null) {
      return _blink.BlinkWorkerGlobalScope.instance.setTimeout_Callback_3_(this, handler, timeout, arguments);
    }
    return _blink.BlinkWorkerGlobalScope.instance.setTimeout_Callback_1_(this, handler);
  }

  void _clearInterval([int handle]) {
    if (handle != null) {
      _blink.BlinkWorkerGlobalScope.instance.clearInterval_Callback_1_(this, handle);
      return;
    }
    _blink.BlinkWorkerGlobalScope.instance.clearInterval_Callback_0_(this);
    return;
  }

  void _clearTimeout([int handle]) {
    if (handle != null) {
      _blink.BlinkWorkerGlobalScope.instance.clearTimeout_Callback_1_(this, handle);
      return;
    }
    _blink.BlinkWorkerGlobalScope.instance.clearTimeout_Callback_0_(this);
    return;
  }

  int _setInterval(Object handler, [int timeout]) {
    if (timeout != null) {
      return _blink.BlinkWorkerGlobalScope.instance.setInterval_Callback_2_(this, handler, timeout);
    }
    return _blink.BlinkWorkerGlobalScope.instance.setInterval_Callback_1_(this, handler);
  }

  int _setTimeout(Object handler, [int timeout]) {
    if (timeout != null) {
      return _blink.BlinkWorkerGlobalScope.instance.setTimeout_Callback_2_(this, handler, timeout);
    }
    return _blink.BlinkWorkerGlobalScope.instance.setTimeout_Callback_1_(this, handler);
  }

  /// 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 EventTarget {
  // To suppress missing implicit constructor warnings.
  factory WorkerPerformance._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  WorkerPerformance.internal_() : super.internal_();


  @DomName('WorkerPerformance.memory')
  @DocsEditable()
  @Experimental() // untriaged
  MemoryInfo get memory => _blink.BlinkWorkerPerformance.instance.memory_Getter_(this);
  
  @DomName('WorkerPerformance.clearMarks')
  @DocsEditable()
  @Experimental() // untriaged
  void clearMarks(String markName) => _blink.BlinkWorkerPerformance.instance.clearMarks_Callback_1_(this, markName);
  
  @DomName('WorkerPerformance.clearMeasures')
  @DocsEditable()
  @Experimental() // untriaged
  void clearMeasures(String measureName) => _blink.BlinkWorkerPerformance.instance.clearMeasures_Callback_1_(this, measureName);
  
  @DomName('WorkerPerformance.getEntries')
  @DocsEditable()
  @Experimental() // untriaged
  List<PerformanceEntry> getEntries() => (_blink.BlinkWorkerPerformance.instance.getEntries_Callback_0_(this));
  
  @DomName('WorkerPerformance.getEntriesByName')
  @DocsEditable()
  @Experimental() // untriaged
  List<PerformanceEntry> getEntriesByName(String name, String entryType) => (_blink.BlinkWorkerPerformance.instance.getEntriesByName_Callback_2_(this, name, entryType));
  
  @DomName('WorkerPerformance.getEntriesByType')
  @DocsEditable()
  @Experimental() // untriaged
  List<PerformanceEntry> getEntriesByType(String entryType) => (_blink.BlinkWorkerPerformance.instance.getEntriesByType_Callback_1_(this, entryType));
  
  @DomName('WorkerPerformance.mark')
  @DocsEditable()
  @Experimental() // untriaged
  void mark(String markName) => _blink.BlinkWorkerPerformance.instance.mark_Callback_1_(this, markName);
  
  @DomName('WorkerPerformance.measure')
  @DocsEditable()
  @Experimental() // untriaged
  void measure(String measureName, String startMark, String endMark) => _blink.BlinkWorkerPerformance.instance.measure_Callback_3_(this, measureName, startMark, endMark);
  
  @DomName('WorkerPerformance.now')
  @DocsEditable()
  @Experimental() // untriaged
  num now() => _blink.BlinkWorkerPerformance.instance.now_Callback_0_(this);
  
  @DomName('WorkerPerformance.webkitClearResourceTimings')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // untriaged
  void clearResourceTimings() => _blink.BlinkWorkerPerformance.instance.webkitClearResourceTimings_Callback_0_(this);
  
  @DomName('WorkerPerformance.webkitSetResourceTimingBufferSize')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // untriaged
  void setResourceTimingBufferSize(int maxSize) => _blink.BlinkWorkerPerformance.instance.webkitSetResourceTimingBufferSize_Callback_1_(this, maxSize);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 DartHtmlDomObject {
  // 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_();
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  XPathEvaluator.internal_() { }

  @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);
  
  XPathResult evaluate(String expression, Node contextNode, XPathNSResolver resolver, [int type, Object inResult]) {
    if (type != null) {
      return _blink.BlinkXPathEvaluator.instance.evaluate_Callback_5_(this, expression, contextNode, resolver, type, inResult);
    }
    return _blink.BlinkXPathEvaluator.instance.evaluate_Callback_3_(this, expression, contextNode, resolver);
  }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory XPathExpression._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  XPathExpression.internal_() { }

  XPathResult evaluate(Node contextNode, [int type, Object inResult]) {
    if (type != null) {
      return _blink.BlinkXPathExpression.instance.evaluate_Callback_3_(this, contextNode, type, inResult);
    }
    return _blink.BlinkXPathExpression.instance.evaluate_Callback_1_(this, contextNode);
  }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory XPathNSResolver._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  XPathNSResolver.internal_() { }

  @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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory XPathResult._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  XPathResult.internal_() { }

  @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()
  num 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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  XmlDocument.internal_() : super.internal_();


}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 DartHtmlDomObject {
  // 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_();
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  XmlSerializer.internal_() { }

  @DomName('XMLSerializer.serializeToString')
  @DocsEditable()
  String serializeToString(Node root) => _blink.BlinkXMLSerializer.instance.serializeToString_Callback_1_(this, root);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('XSLTProcessor')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@deprecated // nonstandard
class XsltProcessor extends DartHtmlDomObject {
  // 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_();
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  XsltProcessor.internal_() { }

  /// 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 style) => _blink.BlinkXSLTProcessor.instance.importStylesheet_Callback_1_(this, style);
  
  @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 output) => _blink.BlinkXSLTProcessor.instance.transformToFragment_Callback_2_(this, source, output);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _Attr.internal_() : super.internal_();


  @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.value')
  @DocsEditable()
  String get value => _blink.BlinkAttr.instance.value_Getter_(this);
  
  @DomName('Attr.value')
  @DocsEditable()
  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('Cache')
@Experimental() // untriaged
class _Cache extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory _Cache._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _Cache.internal_() { }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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
class _CanvasPathMethods extends DartHtmlDomObject {
  // 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 DartHtmlDomObject 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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _ClientRect.internal_() { }

  @DomName('ClientRect.bottom')
  @DocsEditable()
  num get bottom => _blink.BlinkClientRect.instance.bottom_Getter_(this);
  
  @DomName('ClientRect.height')
  @DocsEditable()
  num get height => _blink.BlinkClientRect.instance.height_Getter_(this);
  
  @DomName('ClientRect.left')
  @DocsEditable()
  num get left => _blink.BlinkClientRect.instance.left_Getter_(this);
  
  @DomName('ClientRect.right')
  @DocsEditable()
  num get right => _blink.BlinkClientRect.instance.right_Getter_(this);
  
  @DomName('ClientRect.top')
  @DocsEditable()
  num get top => _blink.BlinkClientRect.instance.top_Getter_(this);
  
  @DomName('ClientRect.width')
  @DocsEditable()
  num 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 DartHtmlDomObject with ListMixin<Rectangle>, ImmutableListMixin<Rectangle> implements List<Rectangle> {
  // To suppress missing implicit constructor warnings.
  factory _ClientRectList._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _ClientRectList.internal_() { }

  @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 _nativeIndexedGetter(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.


  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.__getter__')
  @DocsEditable()
  @Experimental() // untriaged
  Rectangle __getter__(int index) => make_dart_rectangle(_blink.BlinkClientRectList.instance.$__getter___Callback_1_(this, index));
  
  @DomName('ClientRectList.item')
  @DocsEditable()
  Rectangle item(int index) => make_dart_rectangle(_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('CSSRuleList')
class _CssRuleList extends DartHtmlDomObject with ListMixin<CssRule>, ImmutableListMixin<CssRule> implements List<CssRule> {
  // To suppress missing implicit constructor warnings.
  factory _CssRuleList._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _CssRuleList.internal_() { }

  @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 _nativeIndexedGetter(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.


  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('DOMFileSystemSync')
@SupportedBrowser(SupportedBrowser.CHROME)
@Experimental()
// http://www.w3.org/TR/file-system-api/#the-filesystemsync-interface
class _DOMFileSystemSync extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory _DOMFileSystemSync._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _DOMFileSystemSync.internal_() { }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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()
class _DirectoryEntrySync extends _EntrySync {
  // To suppress missing implicit constructor warnings.
  factory _DirectoryEntrySync._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _DirectoryEntrySync.internal_() : super.internal_();


}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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()
class _DirectoryReaderSync extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory _DirectoryReaderSync._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _DirectoryReaderSync.internal_() { }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('DocumentType')
// http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-412266927
@deprecated // stable
class _DocumentType extends Node implements ChildNode {
  // To suppress missing implicit constructor warnings.
  factory _DocumentType._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _DocumentType.internal_() : super.internal_();


  // Override this methods for Dartium _DocumentType can't be abstract.
  Element get nextElementSibling => _blink.BlinkDocumentType.instance.nextElementSibling_Getter_(this);
  Element get previousElementSibling => _blink.BlinkDocumentType.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('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_();
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _DomRect.internal_() : super.internal_();


  @DomName('DOMRect.height')
  @DocsEditable()
  @Experimental() // untriaged
  num get height => _blink.BlinkDOMRect.instance.height_Getter_(this);
  
  @DomName('DOMRect.height')
  @DocsEditable()
  @Experimental() // untriaged
  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
  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
  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
  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()
class _EntrySync extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory _EntrySync._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _EntrySync.internal_() { }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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()
class _FileEntrySync extends _EntrySync {
  // To suppress missing implicit constructor warnings.
  factory _FileEntrySync._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _FileEntrySync.internal_() : super.internal_();


}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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()
class _FileReaderSync extends DartHtmlDomObject {
  // 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_();
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _FileReaderSync.internal_() { }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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()
class _FileWriterSync extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory _FileWriterSync._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _FileWriterSync.internal_() { }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 DartHtmlDomObject with ListMixin<Gamepad>, ImmutableListMixin<Gamepad> implements List<Gamepad> {
  // To suppress missing implicit constructor warnings.
  factory _GamepadList._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _GamepadList.internal_() { }

  @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 _nativeIndexedGetter(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.


  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
class _HTMLAllCollection extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory _HTMLAllCollection._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _HTMLAllCollection.internal_() { }

  Element _item(int index) {
    if ((index is int || index == null)) {
      return _blink.BlinkHTMLAllCollection.instance.item_Callback_1_(this, index);
    }
    if ((index is int || index == null)) {
      return _blink.BlinkHTMLAllCollection.instance.item_Callback_1_(this, index);
    }
    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('HTMLAppletElement')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#the-applet-element
@deprecated // deprecated
class _HTMLAppletElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory _HTMLAppletElement._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _HTMLAppletElement.internal_() : super.internal_();

  /**
   * 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
class _HTMLDirectoryElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory _HTMLDirectoryElement._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _HTMLDirectoryElement.internal_() : super.internal_();

  /**
   * 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
class _HTMLFontElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory _HTMLFontElement._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _HTMLFontElement.internal_() : super.internal_();

  /**
   * 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
class _HTMLFrameElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory _HTMLFrameElement._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _HTMLFrameElement.internal_() : super.internal_();

  /**
   * Constructor instantiated by the DOM when a custom element has been created.
   *
   * This can only be called by subclasses from their created constructor.
   */
  _HTMLFrameElement.created() : super.created();

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('HTMLFrameSetElement')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#frameset
@deprecated // deprecated
class _HTMLFrameSetElement extends HtmlElement implements WindowEventHandlers {
  // To suppress missing implicit constructor warnings.
  factory _HTMLFrameSetElement._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _HTMLFrameSetElement.internal_() : super.internal_();

  /**
   * 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();

  // Override these methods for Dartium _HTMLFrameSetElement can't be abstract.
  Stream<Event> get onHashChange => hashChangeEvent.forTarget(this);
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
  Stream<Event> get onOffline => offlineEvent.forTarget(this);
  Stream<Event> get onOnline => onlineEvent.forTarget(this);
  Stream<PopStateEvent> get onPopState => popStateEvent.forTarget(this);
  Stream<StorageEvent> get onStorage => storageEvent.forTarget(this);
  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('HTMLMarqueeElement')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#the-marquee-element
@deprecated // deprecated
class _HTMLMarqueeElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory _HTMLMarqueeElement._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _HTMLMarqueeElement.internal_() : super.internal_();

  /**
   * 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.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('NamedNodeMap')
// http://dom.spec.whatwg.org/#namednodemap
@deprecated // deprecated
class _NamedNodeMap extends DartHtmlDomObject with ListMixin<Node>, ImmutableListMixin<Node> implements List<Node> {
  // To suppress missing implicit constructor warnings.
  factory _NamedNodeMap._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _NamedNodeMap.internal_() { }

  @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 _nativeIndexedGetter(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.


  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.

  _Attr getNamedItem(String name) {
    if ((name is String)) {
      return _blink.BlinkNamedNodeMap.instance.getNamedItem_Callback_1_(this, name);
    }
    if ((name is String)) {
      return _blink.BlinkNamedNodeMap.instance.getNamedItem_Callback_1_(this, name);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('NamedNodeMap.getNamedItemNS')
  @DocsEditable()
  _Attr getNamedItemNS(String namespaceURI, String localName) => _blink.BlinkNamedNodeMap.instance.getNamedItemNS_Callback_2_(this, namespaceURI, localName);
  
  @DomName('NamedNodeMap.item')
  @DocsEditable()
  _Attr item(int index) => _blink.BlinkNamedNodeMap.instance.item_Callback_1_(this, index);
  
  @DomName('NamedNodeMap.removeNamedItem')
  @DocsEditable()
  _Attr removeNamedItem(String name) => _blink.BlinkNamedNodeMap.instance.removeNamedItem_Callback_1_(this, name);
  
  @DomName('NamedNodeMap.removeNamedItemNS')
  @DocsEditable()
  _Attr removeNamedItemNS(String namespaceURI, String localName) => _blink.BlinkNamedNodeMap.instance.removeNamedItemNS_Callback_2_(this, namespaceURI, localName);
  
  @DomName('NamedNodeMap.setNamedItem')
  @DocsEditable()
  _Attr setNamedItem(_Attr attr) => _blink.BlinkNamedNodeMap.instance.setNamedItem_Callback_1_(this, attr);
  
  @DomName('NamedNodeMap.setNamedItemNS')
  @DocsEditable()
  _Attr setNamedItemNS(_Attr attr) => _blink.BlinkNamedNodeMap.instance.setNamedItemNS_Callback_1_(this, attr);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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
class _PagePopupController extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory _PagePopupController._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _PagePopupController.internal_() { }

}
// 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')
class _RadioNodeList extends NodeList {
  // To suppress missing implicit constructor warnings.
  factory _RadioNodeList._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _RadioNodeList.internal_() : super.internal_();


  @DomName('RadioNodeList.item')
  @DocsEditable()
  @Experimental() // untriaged
  Node _item(int index) => _blink.BlinkRadioNodeList.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('Request')
@Experimental() // untriaged
class _Request extends Body {
  // To suppress missing implicit constructor warnings.
  factory _Request._() { throw new UnsupportedError("Not supported"); }

  @DomName('Request.Request')
  @DocsEditable()
  factory _Request(Object input, [Map requestInitDict]) {
    if (requestInitDict != null) {
      var requestInitDict_1 = convertDartToNative_Dictionary(requestInitDict);
      return _blink.BlinkRequest.instance.constructorCallback_2_(input, requestInitDict_1);
    }
    return _blink.BlinkRequest.instance.constructorCallback_1_(input);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _Request.internal_() : super.internal_();


  @DomName('Request.context')
  @DocsEditable()
  @Experimental() // untriaged
  String get context => _blink.BlinkRequest.instance.context_Getter_(this);
  
  @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);
  
  @DomName('Request.clone')
  @DocsEditable()
  @Experimental() // untriaged
  _Request clone() => _blink.BlinkRequest.instance.clone_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('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"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _ResourceProgressEvent.internal_() : super.internal_();


}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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
class _Response extends Body {
  // To suppress missing implicit constructor warnings.
  factory _Response._() { throw new UnsupportedError("Not supported"); }

  @DomName('Response.Response')
  @DocsEditable()
  factory _Response([Object body, Map responseInitDict]) {
    if (responseInitDict != null) {
      var responseInitDict_1 = convertDartToNative_Dictionary(responseInitDict);
      return _blink.BlinkResponse.instance.constructorCallback_2_(body, responseInitDict_1);
    }
    if (body != null) {
      return _blink.BlinkResponse.instance.constructorCallback_1_(body);
    }
    return _blink.BlinkResponse.instance.constructorCallback_0_();
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _Response.internal_() : super.internal_();


}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('ServiceWorker')
@Experimental() // untriaged
class _ServiceWorker extends EventTarget implements AbstractWorker {
  // To suppress missing implicit constructor warnings.
  factory _ServiceWorker._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _ServiceWorker.internal_() : super.internal_();


  // Override these methods for Dartium _ServiceWorker can't be abstract.
  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('SpeechRecognitionResultList')
// https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#speechrecognitionresultlist
@Experimental()
class _SpeechRecognitionResultList extends DartHtmlDomObject with ListMixin<SpeechRecognitionResult>, ImmutableListMixin<SpeechRecognitionResult> implements List<SpeechRecognitionResult> {
  // To suppress missing implicit constructor warnings.
  factory _SpeechRecognitionResultList._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _SpeechRecognitionResultList.internal_() { }

  @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 _nativeIndexedGetter(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.


  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 DartHtmlDomObject with ListMixin<StyleSheet>, ImmutableListMixin<StyleSheet> implements List<StyleSheet> {
  // To suppress missing implicit constructor warnings.
  factory _StyleSheetList._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _StyleSheetList.internal_() { }

  @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 _nativeIndexedGetter(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.


  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
class _SubtleCrypto extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory _SubtleCrypto._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _SubtleCrypto.internal_() { }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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
class _WebKitCSSMatrix extends DartHtmlDomObject {
  // 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);
  }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _WebKitCSSMatrix.internal_() { }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory _WindowTimers._() { throw new UnsupportedError("Not supported"); }

  int _setInterval_String(String handler, [int timeout, Object arguments]) {
    if (timeout != null) {
      return _blink.BlinkWindowTimers.instance.setInterval_Callback_3_(this, handler, timeout, arguments);
    }
    return _blink.BlinkWindowTimers.instance.setInterval_Callback_1_(this, handler);
  }

  int _setTimeout_String(String handler, [int timeout, Object arguments]) {
    if (timeout != null) {
      return _blink.BlinkWindowTimers.instance.setTimeout_Callback_3_(this, handler, timeout, arguments);
    }
    return _blink.BlinkWindowTimers.instance.setTimeout_Callback_1_(this, handler);
  }

  void _clearInterval([int handle]) {
    if (handle != null) {
      _blink.BlinkWindowTimers.instance.clearInterval_Callback_1_(this, handle);
      return;
    }
    _blink.BlinkWindowTimers.instance.clearInterval_Callback_0_(this);
    return;
  }

  void _clearTimeout([int handle]) {
    if (handle != null) {
      _blink.BlinkWindowTimers.instance.clearTimeout_Callback_1_(this, handle);
      return;
    }
    _blink.BlinkWindowTimers.instance.clearTimeout_Callback_0_(this);
    return;
  }

  int _setInterval(Object handler, [int timeout]) {
    if (timeout != null) {
      return _blink.BlinkWindowTimers.instance.setInterval_Callback_2_(this, handler, timeout);
    }
    return _blink.BlinkWindowTimers.instance.setInterval_Callback_1_(this, handler);
  }

  int _setTimeout(Object handler, [int timeout]) {
    if (timeout != null) {
      return _blink.BlinkWindowTimers.instance.setTimeout_Callback_2_(this, handler, timeout);
    }
    return _blink.BlinkWindowTimers.instance.setTimeout_Callback_1_(this, handler);
  }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DocsEditable()
@DomName('WorkerLocation')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#workerlocation
@Experimental()
class _WorkerLocation extends DartHtmlDomObject implements UrlUtilsReadOnly {
  // To suppress missing implicit constructor warnings.
  factory _WorkerLocation._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _WorkerLocation.internal_() { }

  // Override these methods for Dartium _WorkerLocation can't be abstract.
  String get hash => _blink.BlinkWorkerLocation.instance.hash_Getter_(this);
  String get host => _blink.BlinkWorkerLocation.instance.host_Getter_(this);
  String get hostname => _blink.BlinkWorkerLocation.instance.hostname_Getter_(this);
  String get href => _blink.BlinkWorkerLocation.instance.href_Getter_(this);
  String get origin => _blink.BlinkWorkerLocation.instance.origin_Getter_(this);
  String get pathname => _blink.BlinkWorkerLocation.instance.pathname_Getter_(this);
  String get port => _blink.BlinkWorkerLocation.instance.port_Getter_(this);
  String get protocol => _blink.BlinkWorkerLocation.instance.protocol_Getter_(this);
  String get search => _blink.BlinkWorkerLocation.instance.search_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('WorkerNavigator')
// http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#workernavigator
@Experimental()
class _WorkerNavigator extends DartHtmlDomObject implements NavigatorCpu, NavigatorOnLine, NavigatorID {
  // To suppress missing implicit constructor warnings.
  factory _WorkerNavigator._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _WorkerNavigator.internal_() { }

  // Override these methods for Dartium _WorkerNavigator can't be abstract.
  String get appCodeName => _blink.BlinkWorkerNavigator.instance.appCodeName_Getter_(this);
  String get appName => _blink.BlinkWorkerNavigator.instance.appCodeName_Getter_(this);
  String get appVersion => _blink.BlinkWorkerNavigator.instance.appVersion_Getter_(this);
  bool get dartEnabled => _blink.BlinkWorkerNavigator.instance.dartEnabled_Getter_(this);
  String get platform => _blink.BlinkWorkerNavigator.instance.platform_Getter_(this);
  String get product => _blink.BlinkWorkerNavigator.instance.product_Getter_(this);
  String get userAgent => _blink.BlinkWorkerNavigator.instance.userAgent_Getter_(this);
  int get hardwareConcurrency => _blink.BlinkWorkerNavigator.instance.hardwareConcurrency_Getter_(this);
  bool get onLine => _blink.BlinkWorkerNavigator.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('XMLHttpRequestProgressEvent')
@Experimental() // nonstandard
class _XMLHttpRequestProgressEvent extends ProgressEvent {
  // To suppress missing implicit constructor warnings.
  factory _XMLHttpRequestProgressEvent._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  _XMLHttpRequestProgressEvent.internal_() : super.internal_();


}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


abstract class _AttributeMap implements Map<String, String> {
  final Element _element;

  _AttributeMap(this._element);

  void addAll(Map<String, String> other) {
    other.forEach((k, v) { this[k] = v; });
  }

  bool containsValue(Object value) {
    for (var v in this.values) {
      if (value == v) {
        return true;
      }
    }
    return false;
  }

  String putIfAbsent(String key, String ifAbsent()) {
    if (!containsKey(key)) {
      this[key] = ifAbsent();
    }
    return this[key];
  }

  void clear() {
    for (var key in keys) {
      remove(key);
    }
  }

  void forEach(void f(String key, String value)) {
    for (var key in keys) {
      var value = this[key];
      f(key, value);
    }
  }

  Iterable<String> get keys {
    // TODO: generate a lazy collection instead.
    var attributes = _element._attributes;
    var keys = <String>[];
    for (int i = 0, len = attributes.length; i < len; i++) {
      _Attr attr = attributes[i];
      if (_matches(attr)) {
        keys.add(attr.name);
      }
    }
    return keys;
  }

  Iterable<String> get values {
    // TODO: generate a lazy collection instead.
    var attributes = _element._attributes;
    var values = <String>[];
    for (int i = 0, len = attributes.length; i < len; i++) {
      _Attr attr = attributes[i];
      if (_matches(attr)) {
        values.add(attr.value);
      }
    }
    return values;
  }

  /**
   * Returns true if there is no {key, value} pair in the map.
   */
  bool get isEmpty {
    return length == 0;
  }

  /**
   * Returns true if there is at least one {key, value} pair in the map.
   */
  bool get isNotEmpty => !isEmpty;

  /**
   * Checks to see if the node should be included in this map.
   */
  bool _matches(Node node);
}

/**
 * Wrapper to expose [Element.attributes] as a typed map.
 */
class _ElementAttributeMap extends _AttributeMap {

  _ElementAttributeMap(Element element): super(element);

  bool containsKey(Object key) {
    return _element._hasAttribute(key);
  }

  String operator [](Object key) {
    return _element.getAttribute(key);
  }

  void operator []=(String key, String value) {
    _element.setAttribute(key, value);
  }

  String remove(Object key) {
    String value = _element.getAttribute(key);
    _element._removeAttribute(key);
    return value;
  }

  /**
   * The number of {key, value} pairs in the map.
   */
  int get length {
    return keys.length;
  }

  bool _matches(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(Object key) {
    return _element._hasAttributeNS(_namespace, key);
  }

  String operator [](Object key) {
    return _element.getAttributeNS(_namespace, key);
  }

  void operator []=(String key, String value) {
    _element.setAttributeNS(_namespace, key, value);
  }

  String remove(Object key) {
    String value = this[key];
    _element._removeAttributeNS(_namespace, key);
    return value;
  }

  /**
   * The number of {key, value} pairs in the map.
   */
  int get length {
    return keys.length;
  }

  bool _matches(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(Object value) => values.any((v) => v == value);

  bool containsKey(Object key) => _attributes.containsKey(_attr(key));

  String operator [](Object key) => _attributes[_attr(key)];

  void operator []=(String key, String value) {
    _attributes[_attr(key)] = value;
  }

  String putIfAbsent(String key, String ifAbsent()) =>
    _attributes.putIfAbsent(_attr(key), ifAbsent);

  String remove(Object key) => _attributes.remove(_attr(key));

  void clear() {
    // Needs to operate on a snapshot since we are mutating the collection.
    for (String key in keys) {
      remove(key);
    }
  }

  void forEach(void f(String key, String value)) {
    _attributes.forEach((String key, String value) {
      if (_matches(key)) {
        f(_strip(key), value);
      }
    });
  }

  Iterable<String> get keys {
    final keys = <String>[];
    _attributes.forEach((String key, String value) {
      if (_matches(key)) {
        keys.add(_strip(key));
      }
    });
    return keys;
  }

  Iterable<String> get values {
    final values = <String>[];
    _attributes.forEach((String key, String value) {
      if (_matches(key)) {
        values.add(value);
      }
    });
    return values;
  }

  int get length => keys.length;

  // TODO: Use lazy iterator when it is available on Map.
  bool get isEmpty => length == 0;

  bool get isNotEmpty => !isEmpty;

  // Helpers.
  String _attr(String key) => 'data-${_toHyphenedName(key)}';
  bool _matches(String key) => key.startsWith('data-');
  String _strip(String key) => _toCamelCase(key.substring(5));

  /**
   * Converts a string name with hyphens into an identifier, by removing hyphens
   * and capitalizing the following letter. Optionally [startUppercase] to
   * captialize the first letter.
   */
  String _toCamelCase(String hyphenedName, {bool startUppercase: false}) {
    var segments = hyphenedName.split('-');
    int start = startUppercase ? 0 : 1;
    for (int i = start; i < segments.length; i++) {
      var segment = segments[i];
      if (segment.length > 0) {
        // Character between 'a'..'z' mapped to 'A'..'Z'
        segments[i] = '${segment[0].toUpperCase()}${segment.substring(1)}';
      }
    }
    return segments.join('');
  }

  /** Reverse of [toCamelCase]. */
  String _toHyphenedName(String word) {
    var sb = new StringBuffer();
    for (int i = 0; i < word.length; i++) {
      var lower = word[i].toLowerCase();
      if (word[i] != lower && i > 0) sb.write('-');
      sb.write(lower);
    }
    return sb.toString();
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * An object that can be drawn to a 2D canvas rendering context.
 *
 * The image drawn to the canvas depends on the type of this object:
 *
 * * If this object is an [ImageElement], then this element's image is
 * drawn to the canvas. If this element is an animated image, then this
 * element's poster frame is drawn. If this element has no poster frame, then
 * the first frame of animation is drawn.
 *
 * * If this object is a [VideoElement], then the frame at this element's current
 * playback position is drawn to the canvas.
 *
 * * If this object is a [CanvasElement], then this element's bitmap is drawn to
 * the canvas.
 *
 * **Note:** Currently all versions of Internet Explorer do not support
 * drawing a video element to a canvas. You may also encounter problems drawing
 * a video to a canvas in Firefox if the source of the video is a data URL.
 *
 * ## See also
 *
 * * [CanvasRenderingContext2D.drawImage]
 * * [CanvasRenderingContext2D.drawImageToRect]
 * * [CanvasRenderingContext2D.drawImageScaled]
 * * [CanvasRenderingContext2D.drawImageScaledFromSource]
 *
 * ## Other resources
 *
 * * [Image sources for 2D rendering
 *   contexts](https://html.spec.whatwg.org/multipage/scripting.html#image-sources-for-2d-rendering-contexts)
 *   from WHATWG.
 * * [Drawing images](https://html.spec.whatwg.org/multipage/scripting.html#dom-context-2d-drawimage)
 *   from WHATWG.
 */
abstract class CanvasImageSource {}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * Top-level container for a browser tab or window.
 *
 * In a web browser, a [WindowBase] object represents any browser window. This
 * object contains the window's state and its relation to other
 * windows, such as which window opened this window.
 *
 * **Note:** This class represents any window, while [Window] is
 * used to access the properties and content of the current window or tab.
 *
 * ## See also
 *
 * * [Window]
 *
 * ## Other resources
 *
 * * [DOM Window](https://developer.mozilla.org/en-US/docs/DOM/window) from MDN.
 * * [Window](http://www.w3.org/TR/Window/) from the W3C.
 */
abstract class WindowBase implements EventTarget {
  // Fields.

  /**
   * The current location of this window.
   *
   *     Location currentLocation = window.location;
   *     print(currentLocation.href); // 'http://www.example.com:80/'
   */
  LocationBase get location;

  /**
   * The current session history for this window.
   *
   * ## Other resources
   *
   * * [Session history and navigation
   *   specification](https://html.spec.whatwg.org/multipage/browsers.html#history)
   *   from WHATWG.
   */
  HistoryBase get history;

  /**
   * Indicates whether this window has been closed.
   *
   *     print(window.closed); // 'false'
   *     window.close();
   *     print(window.closed); // 'true'
   */
  bool get closed;

  /**
   * A reference to the window that opened this one.
   *
   *     Window thisWindow = window;
   *     WindowBase otherWindow = thisWindow.open('http://www.example.com/', 'foo');
   *     print(otherWindow.opener == thisWindow); // 'true'
   */
  WindowBase get opener;

  /**
   * A reference to the parent of this window.
   *
   * If this [WindowBase] has no parent, [parent] will return a reference to
   * the [WindowBase] itself.
   *
   *     IFrameElement myIFrame = new IFrameElement();
   *     window.document.body.elements.add(myIFrame);
   *     print(myIframe.contentWindow.parent == window) // 'true'
   *
   *     print(window.parent == window) // 'true'
   */
  WindowBase get parent;

  /**
   * A reference to the topmost window in the window hierarchy.
   *
   * If this [WindowBase] is the topmost [WindowBase], [top] will return a
   * reference to the [WindowBase] itself.
   *
   *     // Add an IFrame to the current window.
   *     IFrameElement myIFrame = new IFrameElement();
   *     window.document.body.elements.add(myIFrame);
   *
   *     // Add an IFrame inside of the other IFrame.
   *     IFrameElement innerIFrame = new IFrameElement();
   *     myIFrame.elements.add(innerIFrame);
   *
   *     print(myIframe.contentWindow.top == window) // 'true'
   *     print(innerIFrame.contentWindow.top == window) // 'true'
   *
   *     print(window.top == window) // 'true'
   */
  WindowBase get top;

  // Methods.
  /**
   * Closes the window.
   *
   * This method should only succeed if the [WindowBase] object is
   * **script-closeable** and the window calling [close] is allowed to navigate
   * the window.
   *
   * A window is script-closeable if it is either a window
   * that was opened by another window, or if it is a window with only one
   * document in its history.
   *
   * A window might not be allowed to navigate, and therefore close, another
   * window due to browser security features.
   *
   *     var other = window.open('http://www.example.com', 'foo');
   *     // Closes other window, as it is script-closeable.
   *     other.close();
   *     print(other.closed()); // 'true'
   *
   *     window.location('http://www.mysite.com', 'foo');
   *     // Does not close this window, as the history has changed.
   *     window.close();
   *     print(window.closed()); // 'false'
   *
   * See also:
   *
   * * [Window close discussion](http://www.w3.org/TR/html5/browsers.html#dom-window-close) from the W3C
   */
  void close();

  /**
   * Sends a cross-origin message.
   *
   * ## Other resources
   *
   * * [window.postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage)
   *   from MDN.
   * * [Cross-document messaging](https://html.spec.whatwg.org/multipage/comms.html#web-messaging)
   *   from WHATWG.
   */
  void postMessage(var message, String targetOrigin, [List<MessagePort> messagePorts]);
}

abstract class LocationBase {
  void set href(String val);
}

abstract class HistoryBase {
  void back();
  void forward();
  void go(int distance);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/** A Set that stores the CSS class names for an element. */
abstract class CssClassSet implements Set<String> {

  /**
   * Adds the class [value] to the element if it is not on it, removes it if it
   * is.
   *
   * If [shouldAdd] is true, then we always add that [value] to the element. If
   * [shouldAdd] is false then we always remove [value] from the element.
   *
   * If this corresponds to one element, returns `true` if [value] is present
   * after the operation, and returns `false` if [value] is absent after the
   * operation.
   *
   * If this corresponds to many elements, `null` is always returned.
   *
   * [value] must be a valid 'token' representing a single class, i.e. a
   * non-empty string containing no whitespace.  To toggle multiple classes, use
   * [toggleAll].
   */
  bool toggle(String value, [bool shouldAdd]);

  /**
   * Returns [:true:] if classes cannot be added or removed from this
   * [:CssClassSet:].
   */
  bool get frozen;

  /**
   * Determine if this element contains the class [value].
   *
   * This is the Dart equivalent of jQuery's
   * [hasClass](http://api.jquery.com/hasClass/).
   *
   * [value] must be a valid 'token' representing a single class, i.e. a
   * non-empty string containing no whitespace.
   */
  bool contains(Object value);

  /**
   * Add the class [value] to element.
   *
   * [add] and [addAll] are the Dart equivalent of jQuery's
   * [addClass](http://api.jquery.com/addClass/).
   *
   * If this CssClassSet corresponds to one element. Returns true if [value] was
   * added to the set, otherwise false.
   *
   * If this corresponds to many elements, `null` is always returned.
   *
   * [value] must be a valid 'token' representing a single class, i.e. a
   * non-empty string containing no whitespace.  To add multiple classes use
   * [addAll].
   */
  bool add(String value);

  /**
   * Remove the class [value] from element, and return true on successful
   * removal.
   *
   * [remove] and [removeAll] are the Dart equivalent of jQuery's
   * [removeClass](http://api.jquery.com/removeClass/).
   *
   * [value] must be a valid 'token' representing a single class, i.e. a
   * non-empty string containing no whitespace.  To remove multiple classes, use
   * [removeAll].
   */
  bool remove(Object value);

  /**
   * Add all classes specified in [iterable] to element.
   *
   * [add] and [addAll] are the Dart equivalent of jQuery's
   * [addClass](http://api.jquery.com/addClass/).
   *
   * Each element of [iterable] must be a valid 'token' representing a single
   * class, i.e. a non-empty string containing no whitespace.
   */
  void addAll(Iterable<String> iterable);

  /**
   * Remove all classes specified in [iterable] from element.
   *
   * [remove] and [removeAll] are the Dart equivalent of jQuery's
   * [removeClass](http://api.jquery.com/removeClass/).
   *
   * Each element of [iterable] must be a valid 'token' representing a single
   * class, i.e. a non-empty string containing no whitespace.
   */
  void removeAll(Iterable<Object> iterable);

  /**
   * Toggles all classes specified in [iterable] on element.
   *
   * Iterate through [iterable]'s items, and add it if it is not on it, or
   * remove it if it is. This is the Dart equivalent of jQuery's
   * [toggleClass](http://api.jquery.com/toggleClass/).
   * If [shouldAdd] is true, then we always add all the classes in [iterable]
   * element. If [shouldAdd] is false then we always remove all the classes in
   * [iterable] from the element.
   *
   * Each element of [iterable] must be a valid 'token' representing a single
   * class, i.e. a non-empty string containing no whitespace.
   */
  void toggleAll(Iterable<String> iterable, [bool shouldAdd]);
}
// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * A set (union) of the CSS classes that are present in a set of elements.
 * Implemented separately from _ElementCssClassSet for performance.
 */
class _MultiElementCssClassSet extends CssClassSetImpl {
  final Iterable<Element> _elementIterable;
  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(
        (_ElementCssClassSet e) => s.addAll(e.readClasses()));
    return s;
  }

  void writeClasses(Set<String> s) {
    var classes = s.join(' ');
    for (Element e in _elementIterable) {
      e.className = classes;
    }
  }

  /**
   * Helper method used to modify the set of css classes on this element.
   *
   *   f - callback with:
   *   s - a Set of all the css class name currently on this element.
   *
   *   After f returns, the modified set is written to the
   *       className property of this element.
   */
  modify( f(Set<String> s)) {
    _elementCssClassSetIterable.forEach((_ElementCssClassSet 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]) =>
      _elementCssClassSetIterable.fold(false,
          (bool changed, _ElementCssClassSet e) =>
              e.toggle(value, shouldAdd) || changed);

  /**
   * Remove the class [value] from element, and return true on successful
   * removal.
   *
   * This is the Dart equivalent of jQuery's
   * [removeClass](http://api.jquery.com/removeClass/).
   */
  bool remove(Object value) => _elementCssClassSetIterable.fold(false,
      (bool changed, _ElementCssClassSet e) => e.remove(value) || changed);
}

class _ElementCssClassSet extends CssClassSetImpl {

  final Element _element;

  _ElementCssClassSet(this._element);

  Set<String> readClasses() {
    var s = new LinkedHashSet<String>();
    var classname = _element.className;

    for (String name in classname.split(' ')) {
      String trimmed = name.trim();
      if (!trimmed.isEmpty) {
        s.add(trimmed);
      }
    }
    return s;
  }

  void writeClasses(Set<String> s) {
    _element.className = s.join(' ');
  }
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * A rectangle representing all the content of the element in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _ContentCssRect extends CssRect {

  _ContentCssRect(Element element) : super(element);

  num get height => _element.offsetHeight +
      _addOrSubtractToBoxModel(_HEIGHT, _CONTENT);

  num get width => _element.offsetWidth +
      _addOrSubtractToBoxModel(_WIDTH, _CONTENT);

  /**
   * Set the height to `newHeight`.
   *
   * newHeight can be either a [num] representing the height in pixels or a
   * [Dimension] object. Values of newHeight that are less than zero are
   * converted to effectively setting the height to 0. This is equivalent to the
   * `height` function in jQuery and the calculated `height` CSS value,
   * converted to a num in pixels.
   */
  set height(newHeight) {
    if (newHeight is Dimension) {
      if (newHeight.value < 0) newHeight = new Dimension.px(0);
      _element.style.height = newHeight.toString();
    } else if (newHeight is num) {
      if (newHeight < 0) newHeight = 0;
      _element.style.height = '${newHeight}px';
    } else {
      throw new ArgumentError("newHeight is not a Dimension or num");
    }
  }

  /**
   * Set the current computed width in pixels of this element.
   *
   * newWidth can be either a [num] representing the width in pixels or a
   * [Dimension] object. This is equivalent to the `width` function in jQuery
   * and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels.
   */
  set width(newWidth) {
    if (newWidth is Dimension) {
      if (newWidth.value < 0) newWidth = new Dimension.px(0);
      _element.style.width = newWidth.toString();
    } else if (newWidth is num) {
      if (newWidth < 0) newWidth = 0;
      _element.style.width = '${newWidth}px';
    } else {
      throw new ArgumentError("newWidth is not a Dimension or num");
    }
  }

  num get left => _element.getBoundingClientRect().left -
      _addOrSubtractToBoxModel(['left'], _CONTENT);
  num get top => _element.getBoundingClientRect().top -
      _addOrSubtractToBoxModel(['top'], _CONTENT);
}

/**
 * A list of element content rectangles in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _ContentCssListRect extends _ContentCssRect {
  List<Element> _elementList;

  _ContentCssListRect(List<Element> elementList) : super(elementList.first) {
    _elementList = elementList;
  }

  /**
   * Set the height to `newHeight`.
   *
   * Values of newHeight that are less than zero are converted to effectively
   * setting the height to 0. This is equivalent to the `height`
   * function in jQuery and the calculated `height` CSS value, converted to a
   * num in pixels.
   */
  set height(newHeight) {
    _elementList.forEach((e) => e.contentEdge.height = newHeight);
  }

  /**
   * Set the current computed width in pixels of this element.
   *
   * This is equivalent to the `width` function in jQuery and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels.
   */
  set width(newWidth) {
    _elementList.forEach((e) => e.contentEdge.width = newWidth);
  }
}

/**
 * A rectangle representing the dimensions of the space occupied by the
 * element's content + padding in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _PaddingCssRect extends CssRect {
  _PaddingCssRect(element) : super(element);
  num get height => _element.offsetHeight +
      _addOrSubtractToBoxModel(_HEIGHT, _PADDING);
  num get width => _element.offsetWidth +
      _addOrSubtractToBoxModel(_WIDTH, _PADDING);

  num get left => _element.getBoundingClientRect().left -
      _addOrSubtractToBoxModel(['left'], _PADDING);
  num get top => _element.getBoundingClientRect().top -
      _addOrSubtractToBoxModel(['top'], _PADDING);
}

/**
 * A rectangle representing the dimensions of the space occupied by the
 * element's content + padding + border in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _BorderCssRect extends CssRect {
  _BorderCssRect(element) : super(element);
  num get height => _element.offsetHeight;
  num get width => _element.offsetWidth;

  num get left => _element.getBoundingClientRect().left;
  num get top => _element.getBoundingClientRect().top;
}

/**
 * A rectangle representing the dimensions of the space occupied by the
 * element's content + padding + border + margin in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _MarginCssRect extends CssRect {
  _MarginCssRect(element) : super(element);
  num get height => _element.offsetHeight +
      _addOrSubtractToBoxModel(_HEIGHT, _MARGIN);
  num get width =>
      _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _MARGIN);

  num get left => _element.getBoundingClientRect().left -
      _addOrSubtractToBoxModel(['left'], _MARGIN);
  num get top => _element.getBoundingClientRect().top -
      _addOrSubtractToBoxModel(['top'], _MARGIN);
}

/**
 * A class for representing CSS dimensions.
 *
 * In contrast to the more general purpose [Rectangle] class, this class's
 * values are mutable, so one can change the height of an element
 * programmatically.
 *
 * _Important_ _note_: use of these methods will perform CSS calculations that
 * can trigger a browser reflow. Therefore, use of these properties _during_ an
 * animation frame is discouraged. See also:
 * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
 */
abstract class CssRect implements Rectangle<num> {
  Element _element;

  CssRect(this._element);

  num get left;

  num get top;

  /**
   * The height of this rectangle.
   *
   * This is equivalent to the `height` function in jQuery and the calculated
   * `height` CSS value, converted to a dimensionless num in pixels. Unlike
   * [getBoundingClientRect], `height` will return the same numerical width if
   * the element is hidden or not.
   */
  num get height;

  /**
   * The width of this rectangle.
   *
   * This is equivalent to the `width` function in jQuery and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels. Unlike
   * [getBoundingClientRect], `width` will return the same numerical width if
   * the element is hidden or not.
   */
  num get width;

  /**
   * Set the height to `newHeight`.
   *
   * newHeight can be either a [num] representing the height in pixels or a
   * [Dimension] object. Values of newHeight that are less than zero are
   * converted to effectively setting the height to 0. This is equivalent to the
   * `height` function in jQuery and the calculated `height` CSS value,
   * converted to a num in pixels.
   *
   * Note that only the content height can actually be set via this method.
   */
  set height(newHeight) {
    throw new UnsupportedError("Can only set height for content rect.");
  }

  /**
   * Set the current computed width in pixels of this element.
   *
   * newWidth can be either a [num] representing the width in pixels or a
   * [Dimension] object. This is equivalent to the `width` function in jQuery
   * and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels.
   *
   * Note that only the content width can be set via this method.
   */
  set width(newWidth) {
    throw new UnsupportedError("Can only set width for content rect.");
  }

  /**
   * Return a value that is used to modify the initial height or width
   * measurement of an element. Depending on the value (ideally an enum) passed
   * to augmentingMeasurement, we may need to add or subtract margin, padding,
   * or border values, depending on the measurement we're trying to obtain.
   */
  num _addOrSubtractToBoxModel(List<String> dimensions,
      String augmentingMeasurement) {
    // getComputedStyle always returns pixel values (hence, computed), so we're
    // always dealing with pixels in this method.
    var styles = _element.getComputedStyle();

    var val = 0;

    for (String measurement in dimensions) {
      // The border-box and default box model both exclude margin in the regular
      // height/width calculation, so add it if we want it for this measurement.
      if (augmentingMeasurement == _MARGIN) {
        val += new Dimension.css(styles.getPropertyValue(
            '$augmentingMeasurement-$measurement')).value;
      }

      // The border-box includes padding and border, so remove it if we want
      // just the content itself.
      if (augmentingMeasurement == _CONTENT) {
      	val -= new Dimension.css(
            styles.getPropertyValue('${_PADDING}-$measurement')).value;
      }

      // At this point, we don't wan't to augment with border or margin,
      // so remove border.
      if (augmentingMeasurement != _MARGIN) {
	      val -= new Dimension.css(styles.getPropertyValue(
            'border-${measurement}-width')).value;
      }
    }
    return val;
  }

  // TODO(jacobr): these methods are duplicated from _RectangleBase in dart:math
  // Ideally we would provide a RectangleMixin class that provides this implementation.
  // In an ideal world we would exp
  /** The x-coordinate of the right edge. */
  num get right => left + width;
  /** The y-coordinate of the bottom edge. */
  num get bottom => top + height;

  String toString() {
    return 'Rectangle ($left, $top) $width x $height';
  }

  bool operator ==(other) {
    if (other is !Rectangle) return false;
    return left == other.left && top == other.top && right == other.right &&
        bottom == other.bottom;
  }

  int get hashCode => _JenkinsSmiHash.hash4(left.hashCode, top.hashCode,
      right.hashCode, bottom.hashCode);

  /**
   * Computes the intersection of `this` and [other].
   *
   * The intersection of two axis-aligned rectangles, if any, is always another
   * axis-aligned rectangle.
   *
   * Returns the intersection of this and `other`, or `null` if they don't
   * intersect.
   */
  Rectangle<num> intersection(Rectangle<num> other) {
    var x0 = max(left, other.left);
    var x1 = min(left + width, other.left + other.width);

    if (x0 <= x1) {
      var y0 = max(top, other.top);
      var y1 = min(top + height, other.top + other.height);

      if (y0 <= y1) {
        return new Rectangle<num>(x0, y0, x1 - x0, y1 - y0);
      }
    }
    return null;
  }


  /**
   * Returns true if `this` intersects [other].
   */
  bool intersects(Rectangle<num> other) {
    return (left <= other.left + other.width &&
        other.left <= left + width &&
        top <= other.top + other.height &&
        other.top <= top + height);
  }

  /**
   * Returns a new rectangle which completely contains `this` and [other].
   */
  Rectangle<num> boundingBox(Rectangle<num> other) {
    var right = max(this.left + this.width, other.left + other.width);
    var bottom = max(this.top + this.height, other.top + other.height);

    var left = min(this.left, other.left);
    var top = min(this.top, other.top);

    return new Rectangle<num>(left, top, right - left, bottom - top);
  }

  /**
   * Tests whether `this` entirely contains [another].
   */
  bool containsRectangle(Rectangle<num> another) {
    return left <= another.left &&
           left + width >= another.left + another.width &&
           top <= another.top &&
           top + height >= another.top + another.height;
  }

  /**
   * Tests whether [another] is inside or along the edges of `this`.
   */
  bool containsPoint(Point<num> another) {
    return another.x >= left &&
           another.x <= left + width &&
           another.y >= top &&
           another.y <= top + height;
  }

  Point<num> get topLeft => new Point<num>(this.left, this.top);
  Point<num> get topRight => new Point<num>(this.left + this.width, this.top);
  Point<num> get bottomRight => new Point<num>(this.left + this.width,
      this.top + this.height);
  Point<num> get bottomLeft => new Point<num>(this.left,
      this.top + this.height);
}

final _HEIGHT = ['top', 'bottom'];
final _WIDTH = ['right', 'left'];
final _CONTENT = 'content';
final _PADDING = 'padding';
final _MARGIN = 'margin';

/**
 * 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<T>(e, _eventType, useCapture);

  /**
   * Gets an [ElementEventStream] for this event type, on the specified element.
   *
   * This will always return a broadcast stream so multiple listeners can be
   * used simultaneously.
   *
   * This may be used to capture DOM events:
   *
   *     Element.keyDownEvent.forElement(element, useCapture: true).listen(...);
   *
   *     // Alternate method:
   *     Element.keyDownEvent.forElement(element).capture(...);
   *
   * Or for listening to an event which will bubble through the DOM tree:
   *
   *     MediaElement.pauseEvent.forElement(document.body).listen(...);
   *
   * See also:
   *
   * [addEventListener](http://docs.webplatform.org/wiki/dom/methods/addEventListener)
   */
  ElementStream<T> forElement(Element e, {bool useCapture: false}) {
    return new _ElementEventStreamImpl<T>(e, _eventType, useCapture);
  }

  /**
   * Gets an [ElementEventStream] for this event type, on the list of elements.
   *
   * This will always return a broadcast stream so multiple listeners can be
   * used simultaneously.
   *
   * This may be used to capture DOM events:
   *
   *     Element.keyDownEvent._forElementList(element, useCapture: true).listen(...);
   *
   * See also:
   *
   * [addEventListener](http://docs.webplatform.org/wiki/dom/methods/addEventListener)
   */
  ElementStream<T> _forElementList(ElementList e, {bool useCapture: false}) {
    return new _ElementListEventStreamImpl<T>(e, _eventType, useCapture);
  }

  /**
   * Gets the type of the event which this would listen for on the specified
   * event target.
   *
   * The target is necessary because some browsers may use different event names
   * for the same purpose and the target allows differentiating browser support.
   */
  String getEventType(EventTarget target) {
    return _eventType;
  }
}

/** A specialized Stream available to [Element]s to enable event delegation. */
abstract class ElementStream<T extends Event> implements Stream<T> {
  /**
   * Return a stream that only fires when the particular event fires for
   * elements matching the specified CSS selector.
   *
   * This is the Dart equivalent to jQuery's
   * [delegate](http://api.jquery.com/delegate/).
   */
  Stream<T> matches(String selector);

  /**
   * Adds a capturing subscription to this stream.
   *
   * If the target of the event is a descendant of the element from which this
   * stream derives then [onData] is called before the event propagates down to
   * the target. This is the opposite of bubbling behavior, where the event
   * is first processed for the event target and then bubbles upward.
   *
   * ## Other resources
   *
   * * [Event Capture](http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture)
   *   from the W3C DOM Events specification.
   */
  StreamSubscription<T> capture(void onData(T event));
}

/**
 * Adapter for exposing DOM events as Dart streams.
 */
class _EventStream<T extends Event> extends Stream<T> {
  final EventTarget _target;
  final String _eventType;
  final bool _useCapture;

  _EventStream(this._target, this._eventType, this._useCapture);

  // DOM events are inherently multi-subscribers.
  Stream<T> asBroadcastStream({void onListen(StreamSubscription<T> subscription),
                               void onCancel(StreamSubscription<T> subscription)})
      => this;
  bool get isBroadcast => true;

  StreamSubscription<T> listen(void onData(T event),
      { Function onError,
        void onDone(),
        bool cancelOnError}) {

    return new _EventStreamSubscription<T>(
        this._target, this._eventType, onData, this._useCapture);
  }
}

bool _matchesWithAncestors(Event event, String selector) {
  var target = event.target;
  return target is Element ? target.matchesWithAncestors(selector) : false;
}

/**
 * Adapter for exposing DOM Element events as streams, while also allowing
 * event delegation.
 */
class _ElementEventStreamImpl<T extends Event> extends _EventStream<T>
    implements ElementStream<T> {
  _ElementEventStreamImpl(target, eventType, useCapture) :
      super(target, eventType, useCapture);

  Stream<T> matches(String selector) => this.where(
      (event) => _matchesWithAncestors(event, selector)).map((e) {
        e._selector = selector;
        return e;
      });

  StreamSubscription<T> capture(void onData(T event)) =>
    new _EventStreamSubscription<T>(
        this._target, this._eventType, onData, true);
}

/**
 * Adapter for exposing events on a collection of DOM Elements as streams,
 * while also allowing event delegation.
 */
class _ElementListEventStreamImpl<T extends Event> extends Stream<T>
    implements ElementStream<T> {
  final Iterable<Element> _targetList;
  final bool _useCapture;
  final String _eventType;

  _ElementListEventStreamImpl(
      this._targetList, this._eventType, this._useCapture);

  Stream<T> matches(String selector) => this.where(
      (event) => _matchesWithAncestors(event, selector)).map((e) {
        e._selector = selector;
        return e;
      });

  // Delegate all regular Stream behavior to a wrapped Stream.
  StreamSubscription<T> listen(void onData(T event),
      { Function onError,
        void onDone(),
        bool cancelOnError}) {
    var pool = new _StreamPool<T>.broadcast();
    for (var target in _targetList) {
      pool.add(new _EventStream<T>(target, _eventType, _useCapture));
    }
    return pool.stream.listen(onData, onError: onError, onDone: onDone,
          cancelOnError: cancelOnError);
  }

  StreamSubscription<T> capture(void onData(T event)) {
    var pool = new _StreamPool<T>.broadcast();
    for (var target in _targetList) {
      pool.add(new _EventStream<T>(target, _eventType, true));
    }
    return pool.stream.listen(onData);
  }

  Stream<T> asBroadcastStream({void onListen(StreamSubscription<T> subscription),
                               void onCancel(StreamSubscription<T> subscription)})
      => this;
  bool get isBroadcast => true;
}

// We would like this to just be EventListener<T> but that typdef cannot
// use generics until dartbug/26276 is fixed.
typedef _EventListener<T extends Event>(T event);

class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> {
  int _pauseCount = 0;
  EventTarget _target;
  final String _eventType;
  EventListener _onData;
  final bool _useCapture;

  // TODO(jacobr): for full strong mode correctness we should write
  // _onData = onData == null ? null : _wrapZone/*<Event, dynamic>*/((e) => onData(e as T))
  // but that breaks 114 co19 tests as well as multiple html tests as it is reasonable
  // to pass the wrong type of event object to an event listener as part of a
  // test.
  _EventStreamSubscription(this._target, this._eventType, void onData(T event),
      this._useCapture) : _onData = _wrapZone/*<Event, dynamic>*/(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/*<Event, dynamic>*/(handleData);
    _tryResume();
  }

  /// Has no effect.
  void onError(Function handleError) {}

  /// Has no effect.
  void onDone(void handleDone()) {}

  void pause([Future resumeSignal]) {
    if (_canceled) return;
    ++_pauseCount;
    _unlisten();

    if (resumeSignal != null) {
      resumeSignal.whenComplete(resume);
    }
  }

  bool get isPaused => _pauseCount > 0;

  void resume() {
    if (_canceled || !isPaused) return;
    --_pauseCount;
    _tryResume();
  }

  void _tryResume() {
    if (_onData != null && !isPaused) {
      _target.addEventListener(_eventType, _onData, _useCapture);
    }
  }

  void _unlisten() {
    if (_onData != null) {
      _target.removeEventListener(_eventType, _onData, _useCapture);
    }
  }

  Future/*<E>*/ asFuture/*<E>*/([var/*=E*/ futureValue]) {
    // We just need a future that will never succeed or fail.
    var completer = new Completer/*<E>*/();
    return completer.future;
  }
}

/**
 * A stream of custom events, which enables the user to "fire" (add) their own
 * custom events to a stream.
 */
abstract class CustomStream<T extends Event> implements Stream<T> {
  /**
   * Add the following custom event to the stream for dispatching to interested
   * listeners.
   */
  void add(T event);
}

class _CustomEventStreamImpl<T extends Event> extends Stream<T>
    implements CustomStream<T> {
  StreamController<T> _streamController;
  /** The type of event this stream is providing (e.g. "keydown"). */
  String _type;

  _CustomEventStreamImpl(String type) {
    _type = type;
    _streamController = new StreamController.broadcast(sync: true);
  }

  // Delegate all regular Stream behavior to our wrapped Stream.
  StreamSubscription<T> listen(void onData(T event),
      { Function onError,
        void onDone(),
        bool cancelOnError}) {
    return _streamController.stream.listen(onData, onError: onError,
        onDone: onDone, cancelOnError: cancelOnError);
  }

  Stream<T> asBroadcastStream({void onListen(StreamSubscription<T> subscription),
                               void onCancel(StreamSubscription<T> subscription)})
      => _streamController.stream;

  bool get isBroadcast => true;

  void add(T event) {
    if (event.type == _type) _streamController.add(event);
  }
}

class _CustomKeyEventStreamImpl extends _CustomEventStreamImpl<KeyEvent>
    implements CustomStream<KeyEvent> {
  _CustomKeyEventStreamImpl(String type) : super(type);

  void add(KeyEvent event) {
    if (event.type == _type) {
      event.currentTarget.dispatchEvent(event._parent);
      _streamController.add(event);
    }
  }
}

/**
 * A pool of streams whose events are unified and emitted through a central
 * stream.
 */
// TODO (efortuna): Remove this when Issue 12218 is addressed.
class _StreamPool<T> {
  StreamController<T> _controller;

  /// Subscriptions to the streams that make up the pool.
  var _subscriptions = new Map<Stream<T>, StreamSubscription<T>>();

  /**
   * Creates a new stream pool where [stream] can be listened to more than
   * once.
   *
   * Any events from buffered streams in the pool will be emitted immediately,
   * regardless of whether [stream] has any subscribers.
   */
  _StreamPool.broadcast() {
    _controller = new StreamController<T>.broadcast(sync: true,
        onCancel: close);
  }

  /**
   * The stream through which all events from streams in the pool are emitted.
   */
  Stream<T> get stream => _controller.stream;

  /**
   * Adds [stream] as a member of this pool.
   *
   * Any events from [stream] will be emitted through [this.stream]. If
   * [stream] is sync, they'll be emitted synchronously; if [stream] is async,
   * they'll be emitted asynchronously.
   */
  void add(Stream<T> stream) {
    if (_subscriptions.containsKey(stream)) return;
    _subscriptions[stream] = stream.listen(_controller.add,
        onError: _controller.addError,
        onDone: () => remove(stream));
  }

  /** Removes [stream] as a member of this pool. */
  void remove(Stream<T> stream) {
    var subscription = _subscriptions.remove(stream);
    if (subscription != null) subscription.cancel();
  }

  /** Removes all streams from this pool and closes [stream]. */
  void close() {
    for (var subscription in _subscriptions.values) {
      subscription.cancel();
    }
    _subscriptions.clear();
    _controller.close();
  }
}

/**
 * A factory to expose DOM events as streams, where the DOM event name has to
 * be determined on the fly (for example, mouse wheel events).
 */
class _CustomEventStreamProvider<T extends Event>
    implements EventStreamProvider<T> {

  final _eventTypeGetter;
  const _CustomEventStreamProvider(this._eventTypeGetter);

  Stream<T> forTarget(EventTarget e, {bool useCapture: false}) {
    return new _EventStream<T>(e, _eventTypeGetter(e), useCapture);
  }

  ElementStream<T> forElement(Element e, {bool useCapture: false}) {
    return new _ElementEventStreamImpl<T>(e, _eventTypeGetter(e), useCapture);
  }

  ElementStream<T> _forElementList(ElementList e,
      {bool useCapture: false}) {
    return new _ElementListEventStreamImpl<T>(e, _eventTypeGetter(e), useCapture);
  }

  String getEventType(EventTarget target) {
    return _eventTypeGetter(target);
  }

  String get _eventType =>
      throw new UnsupportedError('Access type through getEventType method.');
}
// DO NOT EDIT- this file is generated from running tool/generator.sh.

// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * A Dart DOM validator generated from Caja whitelists.
 *
 * This contains a whitelist of known HTML tagNames and attributes and will only
 * accept known good values.
 *
 * See also:
 *
 * * <https://code.google.com/p/google-caja/wiki/CajaWhitelists>
 */
class _Html5NodeValidator implements NodeValidator {

  static final Set<String> _allowedElements = new Set.from([
    'A',
    'ABBR',
    'ACRONYM',
    'ADDRESS',
    'AREA',
    'ARTICLE',
    'ASIDE',
    'AUDIO',
    'B',
    'BDI',
    'BDO',
    'BIG',
    'BLOCKQUOTE',
    'BR',
    'BUTTON',
    'CANVAS',
    'CAPTION',
    'CENTER',
    'CITE',
    'CODE',
    'COL',
    'COLGROUP',
    'COMMAND',
    'DATA',
    'DATALIST',
    'DD',
    'DEL',
    'DETAILS',
    'DFN',
    'DIR',
    'DIV',
    'DL',
    'DT',
    'EM',
    'FIELDSET',
    'FIGCAPTION',
    'FIGURE',
    'FONT',
    'FOOTER',
    'FORM',
    'H1',
    'H2',
    'H3',
    'H4',
    'H5',
    'H6',
    'HEADER',
    'HGROUP',
    'HR',
    'I',
    'IFRAME',
    'IMG',
    'INPUT',
    'INS',
    'KBD',
    'LABEL',
    'LEGEND',
    'LI',
    'MAP',
    'MARK',
    'MENU',
    'METER',
    'NAV',
    'NOBR',
    'OL',
    'OPTGROUP',
    'OPTION',
    'OUTPUT',
    'P',
    'PRE',
    'PROGRESS',
    'Q',
    'S',
    'SAMP',
    'SECTION',
    'SELECT',
    'SMALL',
    'SOURCE',
    'SPAN',
    'STRIKE',
    'STRONG',
    'SUB',
    'SUMMARY',
    'SUP',
    'TABLE',
    'TBODY',
    'TD',
    'TEXTAREA',
    'TFOOT',
    'TH',
    'THEAD',
    'TIME',
    'TR',
    'TRACK',
    'TT',
    'U',
    'UL',
    'VAR',
    'VIDEO',
    'WBR',
  ]);

  static const _standardAttributes = const <String>[
    '*::class',
    '*::dir',
    '*::draggable',
    '*::hidden',
    '*::id',
    '*::inert',
    '*::itemprop',
    '*::itemref',
    '*::itemscope',
    '*::lang',
    '*::spellcheck',
    '*::title',
    '*::translate',
    'A::accesskey',
    'A::coords',
    'A::hreflang',
    'A::name',
    'A::shape',
    'A::tabindex',
    'A::target',
    'A::type',
    'AREA::accesskey',
    'AREA::alt',
    'AREA::coords',
    'AREA::nohref',
    'AREA::shape',
    'AREA::tabindex',
    'AREA::target',
    'AUDIO::controls',
    'AUDIO::loop',
    'AUDIO::mediagroup',
    'AUDIO::muted',
    'AUDIO::preload',
    'BDO::dir',
    'BODY::alink',
    'BODY::bgcolor',
    'BODY::link',
    'BODY::text',
    'BODY::vlink',
    'BR::clear',
    'BUTTON::accesskey',
    'BUTTON::disabled',
    'BUTTON::name',
    'BUTTON::tabindex',
    'BUTTON::type',
    'BUTTON::value',
    'CANVAS::height',
    'CANVAS::width',
    'CAPTION::align',
    'COL::align',
    'COL::char',
    'COL::charoff',
    'COL::span',
    'COL::valign',
    'COL::width',
    'COLGROUP::align',
    'COLGROUP::char',
    'COLGROUP::charoff',
    'COLGROUP::span',
    'COLGROUP::valign',
    'COLGROUP::width',
    'COMMAND::checked',
    'COMMAND::command',
    'COMMAND::disabled',
    'COMMAND::label',
    'COMMAND::radiogroup',
    'COMMAND::type',
    'DATA::value',
    'DEL::datetime',
    'DETAILS::open',
    'DIR::compact',
    'DIV::align',
    'DL::compact',
    'FIELDSET::disabled',
    'FONT::color',
    'FONT::face',
    'FONT::size',
    'FORM::accept',
    'FORM::autocomplete',
    'FORM::enctype',
    'FORM::method',
    'FORM::name',
    'FORM::novalidate',
    'FORM::target',
    'FRAME::name',
    'H1::align',
    'H2::align',
    'H3::align',
    'H4::align',
    'H5::align',
    'H6::align',
    'HR::align',
    'HR::noshade',
    'HR::size',
    'HR::width',
    'HTML::version',
    'IFRAME::align',
    'IFRAME::frameborder',
    'IFRAME::height',
    'IFRAME::marginheight',
    'IFRAME::marginwidth',
    'IFRAME::width',
    'IMG::align',
    'IMG::alt',
    'IMG::border',
    'IMG::height',
    'IMG::hspace',
    'IMG::ismap',
    'IMG::name',
    'IMG::usemap',
    'IMG::vspace',
    'IMG::width',
    'INPUT::accept',
    'INPUT::accesskey',
    'INPUT::align',
    'INPUT::alt',
    'INPUT::autocomplete',
    'INPUT::autofocus',
    'INPUT::checked',
    'INPUT::disabled',
    'INPUT::inputmode',
    'INPUT::ismap',
    'INPUT::list',
    'INPUT::max',
    'INPUT::maxlength',
    'INPUT::min',
    'INPUT::multiple',
    'INPUT::name',
    'INPUT::placeholder',
    'INPUT::readonly',
    'INPUT::required',
    'INPUT::size',
    'INPUT::step',
    'INPUT::tabindex',
    'INPUT::type',
    'INPUT::usemap',
    'INPUT::value',
    'INS::datetime',
    'KEYGEN::disabled',
    'KEYGEN::keytype',
    'KEYGEN::name',
    'LABEL::accesskey',
    'LABEL::for',
    'LEGEND::accesskey',
    'LEGEND::align',
    'LI::type',
    'LI::value',
    'LINK::sizes',
    'MAP::name',
    'MENU::compact',
    'MENU::label',
    'MENU::type',
    'METER::high',
    'METER::low',
    'METER::max',
    'METER::min',
    'METER::value',
    'OBJECT::typemustmatch',
    'OL::compact',
    'OL::reversed',
    'OL::start',
    'OL::type',
    'OPTGROUP::disabled',
    'OPTGROUP::label',
    'OPTION::disabled',
    'OPTION::label',
    'OPTION::selected',
    'OPTION::value',
    'OUTPUT::for',
    'OUTPUT::name',
    'P::align',
    'PRE::width',
    'PROGRESS::max',
    'PROGRESS::min',
    'PROGRESS::value',
    'SELECT::autocomplete',
    'SELECT::disabled',
    'SELECT::multiple',
    'SELECT::name',
    'SELECT::required',
    'SELECT::size',
    'SELECT::tabindex',
    'SOURCE::type',
    'TABLE::align',
    'TABLE::bgcolor',
    'TABLE::border',
    'TABLE::cellpadding',
    'TABLE::cellspacing',
    'TABLE::frame',
    'TABLE::rules',
    'TABLE::summary',
    'TABLE::width',
    'TBODY::align',
    'TBODY::char',
    'TBODY::charoff',
    'TBODY::valign',
    'TD::abbr',
    'TD::align',
    'TD::axis',
    'TD::bgcolor',
    'TD::char',
    'TD::charoff',
    'TD::colspan',
    'TD::headers',
    'TD::height',
    'TD::nowrap',
    'TD::rowspan',
    'TD::scope',
    'TD::valign',
    'TD::width',
    'TEXTAREA::accesskey',
    'TEXTAREA::autocomplete',
    'TEXTAREA::cols',
    'TEXTAREA::disabled',
    'TEXTAREA::inputmode',
    'TEXTAREA::name',
    'TEXTAREA::placeholder',
    'TEXTAREA::readonly',
    'TEXTAREA::required',
    'TEXTAREA::rows',
    'TEXTAREA::tabindex',
    'TEXTAREA::wrap',
    'TFOOT::align',
    'TFOOT::char',
    'TFOOT::charoff',
    'TFOOT::valign',
    'TH::abbr',
    'TH::align',
    'TH::axis',
    'TH::bgcolor',
    'TH::char',
    'TH::charoff',
    'TH::colspan',
    'TH::headers',
    'TH::height',
    'TH::nowrap',
    'TH::rowspan',
    'TH::scope',
    'TH::valign',
    'TH::width',
    'THEAD::align',
    'THEAD::char',
    'THEAD::charoff',
    'THEAD::valign',
    'TR::align',
    'TR::bgcolor',
    'TR::char',
    'TR::charoff',
    'TR::valign',
    'TRACK::default',
    'TRACK::kind',
    'TRACK::label',
    'TRACK::srclang',
    'UL::compact',
    'UL::type',
    'VIDEO::controls',
    'VIDEO::height',
    'VIDEO::loop',
    'VIDEO::mediagroup',
    'VIDEO::muted',
    'VIDEO::preload',
    'VIDEO::width',
  ];

  static const _uriAttributes = const <String>[
    'A::href',
    'AREA::href',
    'BLOCKQUOTE::cite',
    'BODY::background',
    'COMMAND::icon',
    'DEL::cite',
    'FORM::action',
    'IMG::src',
    'INPUT::src',
    'INS::cite',
    'Q::cite',
    'VIDEO::poster',
  ];

  final UriPolicy uriPolicy;

  static final Map<String, Function> _attributeValidators = {};

  /**
   * All known URI attributes will be validated against the UriPolicy, if
   * [uriPolicy] is null then a default UriPolicy will be used.
   */
  _Html5NodeValidator({UriPolicy uriPolicy})
      :uriPolicy = uriPolicy != null ? uriPolicy : new UriPolicy() {

    if (_attributeValidators.isEmpty) {
      for (var attr in _standardAttributes) {
        _attributeValidators[attr] = _standardAttributeValidator;
      }

      for (var attr in _uriAttributes) {
        _attributeValidators[attr] = _uriAttributeValidator;
      }
    }
  }

  bool allowsElement(Element element) {
    return _allowedElements.contains(Element._safeTagName(element));
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    var tagName = Element._safeTagName(element);
    var validator = _attributeValidators['$tagName::$attributeName'];
    if (validator == null) {
      validator = _attributeValidators['*::$attributeName'];
    }
    if (validator == null) {
      return false;
    }
    return validator(element, attributeName, value, this);
  }

  static bool _standardAttributeValidator(Element element, String attributeName,
      String value, _Html5NodeValidator context) {
    return true;
  }

  static bool _uriAttributeValidator(Element element, String attributeName,
      String value, _Html5NodeValidator context) {
    return context.uriPolicy.allowsUri(value);
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


abstract class ImmutableListMixin<E> implements List<E> {
  // From Iterable<$E>:
  Iterator<E> get iterator {
    // Note: NodeLists are not fixed size. And most probably length shouldn't
    // be cached in both iterator _and_ forEach method. For now caching it
    // for consistency.
    return new FixedSizeListIterator<E>(this);
  }

  // From Collection<E>:
  void add(E value) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  void addAll(Iterable<E> iterable) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  // From List<E>:
  void sort([int compare(E a, E b)]) {
    throw new UnsupportedError("Cannot sort immutable List.");
  }

  void shuffle([Random random]) {
    throw new UnsupportedError("Cannot shuffle immutable List.");
  }

  void insert(int index, E element) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  void insertAll(int index, Iterable<E> iterable) {
    throw new UnsupportedError("Cannot add to immutable List.");
  }

  void setAll(int index, Iterable<E> iterable) {
    throw new UnsupportedError("Cannot modify an immutable List.");
  }

  E removeAt(int pos) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  E removeLast() {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  bool remove(Object object) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  void removeWhere(bool test(E element)) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  void retainWhere(bool test(E element)) {
    throw new UnsupportedError("Cannot remove from immutable List.");
  }

  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
    throw new UnsupportedError("Cannot setRange on immutable List.");
  }

  void removeRange(int start, int end) {
    throw new UnsupportedError("Cannot removeRange on immutable List.");
  }

  void replaceRange(int start, int end, Iterable<E> iterable) {
    throw new UnsupportedError("Cannot modify an immutable List.");
  }

  void fillRange(int start, int end, [E fillValue]) {
    throw new UnsupportedError("Cannot modify an immutable List.");
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * Defines the keycode values for keys that are returned by
 * KeyboardEvent.keyCode.
 *
 * Important note: There is substantial divergence in how different browsers
 * handle keycodes and their variants in different locales/keyboard layouts. We
 * provide these constants to help make code processing keys more readable.
 */
abstract class KeyCode {
  // These constant names were borrowed from Closure's Keycode enumeration
  // class.
  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keycodes.js.source.html
  static const int WIN_KEY_FF_LINUX = 0;
  static const int MAC_ENTER = 3;
  static const int BACKSPACE = 8;
  static const int TAB = 9;
  /** NUM_CENTER is also NUMLOCK for FF and Safari on Mac. */
  static const int NUM_CENTER = 12;
  static const int ENTER = 13;
  static const int SHIFT = 16;
  static const int CTRL = 17;
  static const int ALT = 18;
  static const int PAUSE = 19;
  static const int CAPS_LOCK = 20;
  static const int ESC = 27;
  static const int SPACE = 32;
  static const int PAGE_UP = 33;
  static const int PAGE_DOWN = 34;
  static const int END = 35;
  static const int HOME = 36;
  static const int LEFT = 37;
  static const int UP = 38;
  static const int RIGHT = 39;
  static const int DOWN = 40;
  static const int NUM_NORTH_EAST = 33;
  static const int NUM_SOUTH_EAST = 34;
  static const int NUM_SOUTH_WEST = 35;
  static const int NUM_NORTH_WEST = 36;
  static const int NUM_WEST = 37;
  static const int NUM_NORTH = 38;
  static const int NUM_EAST = 39;
  static const int NUM_SOUTH = 40;
  static const int PRINT_SCREEN = 44;
  static const int INSERT = 45;
  static const int NUM_INSERT = 45;
  static const int DELETE = 46;
  static const int NUM_DELETE = 46;
  static const int ZERO = 48;
  static const int ONE = 49;
  static const int TWO = 50;
  static const int THREE = 51;
  static const int FOUR = 52;
  static const int FIVE = 53;
  static const int SIX = 54;
  static const int SEVEN = 55;
  static const int EIGHT = 56;
  static const int NINE = 57;
  static const int FF_SEMICOLON = 59;
  static const int FF_EQUALS = 61;
  /**
   * CAUTION: The question mark is for US-keyboard layouts. It varies
   * for other locales and keyboard layouts.
   */
  static const int QUESTION_MARK = 63;
  static const int A = 65;
  static const int B = 66;
  static const int C = 67;
  static const int D = 68;
  static const int E = 69;
  static const int F = 70;
  static const int G = 71;
  static const int H = 72;
  static const int I = 73;
  static const int J = 74;
  static const int K = 75;
  static const int L = 76;
  static const int M = 77;
  static const int N = 78;
  static const int O = 79;
  static const int P = 80;
  static const int Q = 81;
  static const int R = 82;
  static const int S = 83;
  static const int T = 84;
  static const int U = 85;
  static const int V = 86;
  static const int W = 87;
  static const int X = 88;
  static const int Y = 89;
  static const int Z = 90;
  static const int META = 91;
  static const int WIN_KEY_LEFT = 91;
  static const int WIN_KEY_RIGHT = 92;
  static const int CONTEXT_MENU = 93;
  static const int NUM_ZERO = 96;
  static const int NUM_ONE = 97;
  static const int NUM_TWO = 98;
  static const int NUM_THREE = 99;
  static const int NUM_FOUR = 100;
  static const int NUM_FIVE = 101;
  static const int NUM_SIX = 102;
  static const int NUM_SEVEN = 103;
  static const int NUM_EIGHT = 104;
  static const int NUM_NINE = 105;
  static const int NUM_MULTIPLY = 106;
  static const int NUM_PLUS = 107;
  static const int NUM_MINUS = 109;
  static const int NUM_PERIOD = 110;
  static const int NUM_DIVISION = 111;
  static const int F1 = 112;
  static const int F2 = 113;
  static const int F3 = 114;
  static const int F4 = 115;
  static const int F5 = 116;
  static const int F6 = 117;
  static const int F7 = 118;
  static const int F8 = 119;
  static const int F9 = 120;
  static const int F10 = 121;
  static const int F11 = 122;
  static const int F12 = 123;
  static const int NUMLOCK = 144;
  static const int SCROLL_LOCK = 145;

  // OS-specific media keys like volume controls and browser controls.
  static const int FIRST_MEDIA_KEY = 166;
  static const int LAST_MEDIA_KEY = 183;

  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int SEMICOLON = 186;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int DASH = 189;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int EQUALS = 187;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int COMMA = 188;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int PERIOD = 190;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int SLASH = 191;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int APOSTROPHE = 192;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int TILDE = 192;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int SINGLE_QUOTE = 222;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int OPEN_SQUARE_BRACKET = 219;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int BACKSLASH = 220;
  /**
   * CAUTION: This constant requires localization for other locales and keyboard
   * layouts.
   */
  static const int CLOSE_SQUARE_BRACKET = 221;
  static const int WIN_KEY = 224;
  static const int MAC_FF_META = 224;
  static const int WIN_IME = 229;

  /** A sentinel value if the keycode could not be determined. */
  static const int UNKNOWN = -1;

  /**
   * Returns true if the keyCode produces a (US keyboard) character.
   * Note: This does not (yet) cover characters on non-US keyboards (Russian,
   * Hebrew, etc.).
   */
  static bool isCharacterKey(int keyCode) {
    if ((keyCode >= ZERO && keyCode <= NINE) ||
        (keyCode >= NUM_ZERO && keyCode <= NUM_MULTIPLY) ||
        (keyCode >= A && keyCode <= Z)) {
      return true;
    }

    // Safari sends zero key code for non-latin characters.
    if (Device.isWebKit && keyCode == 0) {
      return true;
    }

    return (keyCode == SPACE || keyCode == QUESTION_MARK || keyCode == NUM_PLUS
        || keyCode == NUM_MINUS || keyCode == NUM_PERIOD ||
        keyCode == NUM_DIVISION || keyCode == SEMICOLON ||
        keyCode == FF_SEMICOLON || keyCode == DASH || keyCode == EQUALS ||
        keyCode == FF_EQUALS || keyCode == COMMA || keyCode == PERIOD ||
        keyCode == SLASH || keyCode == APOSTROPHE || keyCode == SINGLE_QUOTE ||
        keyCode == OPEN_SQUARE_BRACKET || keyCode == BACKSLASH ||
        keyCode == CLOSE_SQUARE_BRACKET);
  }

  /**
   * Experimental helper function for converting keyCodes to keyNames for the
   * keyIdentifier attribute still used in browsers not updated with current
   * spec. This is an imperfect conversion! It will need to be refined, but
   * hopefully it can just completely go away once all the browsers update to
   * follow the DOM3 spec.
   */
  static String _convertKeyCodeToKeyName(int keyCode) {
    switch(keyCode) {
      case KeyCode.ALT: return _KeyName.ALT;
      case KeyCode.BACKSPACE: return _KeyName.BACKSPACE;
      case KeyCode.CAPS_LOCK: return _KeyName.CAPS_LOCK;
      case KeyCode.CTRL: return _KeyName.CONTROL;
      case KeyCode.DELETE: return _KeyName.DEL;
      case KeyCode.DOWN: return _KeyName.DOWN;
      case KeyCode.END: return _KeyName.END;
      case KeyCode.ENTER: return _KeyName.ENTER;
      case KeyCode.ESC: return _KeyName.ESC;
      case KeyCode.F1: return _KeyName.F1;
      case KeyCode.F2: return _KeyName.F2;
      case KeyCode.F3: return _KeyName.F3;
      case KeyCode.F4: return _KeyName.F4;
      case KeyCode.F5: return _KeyName.F5;
      case KeyCode.F6: return _KeyName.F6;
      case KeyCode.F7: return _KeyName.F7;
      case KeyCode.F8: return _KeyName.F8;
      case KeyCode.F9: return _KeyName.F9;
      case KeyCode.F10: return _KeyName.F10;
      case KeyCode.F11: return _KeyName.F11;
      case KeyCode.F12: return _KeyName.F12;
      case KeyCode.HOME: return _KeyName.HOME;
      case KeyCode.INSERT: return _KeyName.INSERT;
      case KeyCode.LEFT: return _KeyName.LEFT;
      case KeyCode.META: return _KeyName.META;
      case KeyCode.NUMLOCK: return _KeyName.NUM_LOCK;
      case KeyCode.PAGE_DOWN: return _KeyName.PAGE_DOWN;
      case KeyCode.PAGE_UP: return _KeyName.PAGE_UP;
      case KeyCode.PAUSE: return _KeyName.PAUSE;
      case KeyCode.PRINT_SCREEN: return _KeyName.PRINT_SCREEN;
      case KeyCode.RIGHT: return _KeyName.RIGHT;
      case KeyCode.SCROLL_LOCK: return _KeyName.SCROLL;
      case KeyCode.SHIFT: return _KeyName.SHIFT;
      case KeyCode.SPACE: return _KeyName.SPACEBAR;
      case KeyCode.TAB: return _KeyName.TAB;
      case KeyCode.UP: return _KeyName.UP;
      case KeyCode.WIN_IME:
      case KeyCode.WIN_KEY:
      case KeyCode.WIN_KEY_LEFT:
      case KeyCode.WIN_KEY_RIGHT:
        return _KeyName.WIN;
      default: return _KeyName.UNIDENTIFIED;
    }
    return _KeyName.UNIDENTIFIED;
  }
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * Defines the standard key locations returned by
 * KeyboardEvent.getKeyLocation.
 */
abstract class KeyLocation {

  /**
   * The event key is not distinguished as the left or right version
   * of the key, and did not originate from the numeric keypad (or did not
   * originate with a virtual key corresponding to the numeric keypad).
   */
  static const int STANDARD = 0;

  /**
   * The event key is in the left key location.
   */
  static const int LEFT = 1;

  /**
   * The event key is in the right key location.
   */
  static const int RIGHT = 2;

  /**
   * The event key originated on the numeric keypad or with a virtual key
   * corresponding to the numeric keypad.
   */
  static const int NUMPAD = 3;

  /**
   * The event key originated on a mobile device, either on a physical
   * keypad or a virtual keyboard.
   */
  static const int MOBILE = 4;

  /**
   * The event key originated on a game controller or a joystick on a mobile
   * device.
   */
  static const int JOYSTICK = 5;
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * Defines the standard keyboard identifier names for keys that are returned
 * by KeyboardEvent.getKeyboardIdentifier when the key does not have a direct
 * unicode mapping.
 */
abstract class _KeyName {

  /** The Accept (Commit, OK) key */
  static const String ACCEPT = "Accept";

  /** The Add key */
  static const String ADD = "Add";

  /** The Again key */
  static const String AGAIN = "Again";

  /** The All Candidates key */
  static const String ALL_CANDIDATES = "AllCandidates";

  /** The Alphanumeric key */
  static const String ALPHANUMERIC = "Alphanumeric";

  /** The Alt (Menu) key */
  static const String ALT = "Alt";

  /** The Alt-Graph key */
  static const String ALT_GRAPH = "AltGraph";

  /** The Application key */
  static const String APPS = "Apps";

  /** The ATTN key */
  static const String ATTN = "Attn";

  /** The Browser Back key */
  static const String BROWSER_BACK = "BrowserBack";

  /** The Browser Favorites key */
  static const String BROWSER_FAVORTIES = "BrowserFavorites";

  /** The Browser Forward key */
  static const String BROWSER_FORWARD = "BrowserForward";

  /** The Browser Home key */
  static const String BROWSER_NAME = "BrowserHome";

  /** The Browser Refresh key */
  static const String BROWSER_REFRESH = "BrowserRefresh";

  /** The Browser Search key */
  static const String BROWSER_SEARCH = "BrowserSearch";

  /** The Browser Stop key */
  static const String BROWSER_STOP = "BrowserStop";

  /** The Camera key */
  static const String CAMERA = "Camera";

  /** The Caps Lock (Capital) key */
  static const String CAPS_LOCK = "CapsLock";

  /** The Clear key */
  static const String CLEAR = "Clear";

  /** The Code Input key */
  static const String CODE_INPUT = "CodeInput";

  /** The Compose key */
  static const String COMPOSE = "Compose";

  /** The Control (Ctrl) key */
  static const String CONTROL = "Control";

  /** The Crsel key */
  static const String CRSEL = "Crsel";

  /** The Convert key */
  static const String CONVERT = "Convert";

  /** The Copy key */
  static const String COPY = "Copy";

  /** The Cut key */
  static const String CUT = "Cut";

  /** The Decimal key */
  static const String DECIMAL = "Decimal";

  /** The Divide key */
  static const String DIVIDE = "Divide";

  /** The Down Arrow key */
  static const String DOWN = "Down";

  /** The diagonal Down-Left Arrow key */
  static const String DOWN_LEFT = "DownLeft";

  /** The diagonal Down-Right Arrow key */
  static const String DOWN_RIGHT = "DownRight";

  /** The Eject key */
  static const String EJECT = "Eject";

  /** The End key */
  static const String END = "End";

  /**
   * The Enter key. Note: This key value must also be used for the Return
   *  (Macintosh numpad) key
   */
  static const String ENTER = "Enter";

  /** The Erase EOF key */
  static const String ERASE_EOF= "EraseEof";

  /** The Execute key */
  static const String EXECUTE = "Execute";

  /** The Exsel key */
  static const String EXSEL = "Exsel";

  /** The Function switch key */
  static const String FN = "Fn";

  /** The F1 key */
  static const String F1 = "F1";

  /** The F2 key */
  static const String F2 = "F2";

  /** The F3 key */
  static const String F3 = "F3";

  /** The F4 key */
  static const String F4 = "F4";

  /** The F5 key */
  static const String F5 = "F5";

  /** The F6 key */
  static const String F6 = "F6";

  /** The F7 key */
  static const String F7 = "F7";

  /** The F8 key */
  static const String F8 = "F8";

  /** The F9 key */
  static const String F9 = "F9";

  /** The F10 key */
  static const String F10 = "F10";

  /** The F11 key */
  static const String F11 = "F11";

  /** The F12 key */
  static const String F12 = "F12";

  /** The F13 key */
  static const String F13 = "F13";

  /** The F14 key */
  static const String F14 = "F14";

  /** The F15 key */
  static const String F15 = "F15";

  /** The F16 key */
  static const String F16 = "F16";

  /** The F17 key */
  static const String F17 = "F17";

  /** The F18 key */
  static const String F18 = "F18";

  /** The F19 key */
  static const String F19 = "F19";

  /** The F20 key */
  static const String F20 = "F20";

  /** The F21 key */
  static const String F21 = "F21";

  /** The F22 key */
  static const String F22 = "F22";

  /** The F23 key */
  static const String F23 = "F23";

  /** The F24 key */
  static const String F24 = "F24";

  /** The Final Mode (Final) key used on some asian keyboards */
  static const String FINAL_MODE = "FinalMode";

  /** The Find key */
  static const String FIND = "Find";

  /** The Full-Width Characters key */
  static const String FULL_WIDTH = "FullWidth";

  /** The Half-Width Characters key */
  static const String HALF_WIDTH = "HalfWidth";

  /** The Hangul (Korean characters) Mode key */
  static const String HANGUL_MODE = "HangulMode";

  /** The Hanja (Korean characters) Mode key */
  static const String HANJA_MODE = "HanjaMode";

  /** The Help key */
  static const String HELP = "Help";

  /** The Hiragana (Japanese Kana characters) key */
  static const String HIRAGANA = "Hiragana";

  /** The Home key */
  static const String HOME = "Home";

  /** The Insert (Ins) key */
  static const String INSERT = "Insert";

  /** The Japanese-Hiragana key */
  static const String JAPANESE_HIRAGANA = "JapaneseHiragana";

  /** The Japanese-Katakana key */
  static const String JAPANESE_KATAKANA = "JapaneseKatakana";

  /** The Japanese-Romaji key */
  static const String JAPANESE_ROMAJI = "JapaneseRomaji";

  /** The Junja Mode key */
  static const String JUNJA_MODE = "JunjaMode";

  /** The Kana Mode (Kana Lock) key */
  static const String KANA_MODE = "KanaMode";

  /**
   * The Kanji (Japanese name for ideographic characters of Chinese origin)
   * Mode key
   */
  static const String KANJI_MODE = "KanjiMode";

  /** The Katakana (Japanese Kana characters) key */
  static const String KATAKANA = "Katakana";

  /** The Start Application One key */
  static const String LAUNCH_APPLICATION_1 = "LaunchApplication1";

  /** The Start Application Two key */
  static const String LAUNCH_APPLICATION_2 = "LaunchApplication2";

  /** The Start Mail key */
  static const String LAUNCH_MAIL = "LaunchMail";

  /** The Left Arrow key */
  static const String LEFT = "Left";

  /** The Menu key */
  static const String MENU = "Menu";

  /**
   * The Meta key. Note: This key value shall be also used for the Apple
   * Command key
   */
  static const String META = "Meta";

  /** The Media Next Track key */
  static const String MEDIA_NEXT_TRACK = "MediaNextTrack";

  /** The Media Play Pause key */
  static const String MEDIA_PAUSE_PLAY = "MediaPlayPause";

  /** The Media Previous Track key */
  static const String MEDIA_PREVIOUS_TRACK = "MediaPreviousTrack";

  /** The Media Stop key */
  static const String MEDIA_STOP = "MediaStop";

  /** The Mode Change key */
  static const String MODE_CHANGE = "ModeChange";

  /** The Next Candidate function key */
  static const String NEXT_CANDIDATE = "NextCandidate";

  /** The Nonconvert (Don't Convert) key */
  static const String NON_CONVERT = "Nonconvert";

  /** The Number Lock key */
  static const String NUM_LOCK = "NumLock";

  /** The Page Down (Next) key */
  static const String PAGE_DOWN = "PageDown";

  /** The Page Up key */
  static const String PAGE_UP = "PageUp";

  /** The Paste key */
  static const String PASTE = "Paste";

  /** The Pause key */
  static const String PAUSE = "Pause";

  /** The Play key */
  static const String PLAY = "Play";

  /**
   * The Power key. Note: Some devices may not expose this key to the
   * operating environment
   */
  static const String POWER = "Power";

  /** The Previous Candidate function key */
  static const String PREVIOUS_CANDIDATE = "PreviousCandidate";

  /** The Print Screen (PrintScrn, SnapShot) key */
  static const String PRINT_SCREEN = "PrintScreen";

  /** The Process key */
  static const String PROCESS = "Process";

  /** The Props key */
  static const String PROPS = "Props";

  /** The Right Arrow key */
  static const String RIGHT = "Right";

  /** The Roman Characters function key */
  static const String ROMAN_CHARACTERS = "RomanCharacters";

  /** The Scroll Lock key */
  static const String SCROLL = "Scroll";

  /** The Select key */
  static const String SELECT = "Select";

  /** The Select Media key */
  static const String SELECT_MEDIA = "SelectMedia";

  /** The Separator key */
  static const String SEPARATOR = "Separator";

  /** The Shift key */
  static const String SHIFT = "Shift";

  /** The Soft1 key */
  static const String SOFT_1 = "Soft1";

  /** The Soft2 key */
  static const String SOFT_2 = "Soft2";

  /** The Soft3 key */
  static const String SOFT_3 = "Soft3";

  /** The Soft4 key */
  static const String SOFT_4 = "Soft4";

  /** The Stop key */
  static const String STOP = "Stop";

  /** The Subtract key */
  static const String SUBTRACT = "Subtract";

  /** The Symbol Lock key */
  static const String SYMBOL_LOCK = "SymbolLock";

  /** The Up Arrow key */
  static const String UP = "Up";

  /** The diagonal Up-Left Arrow key */
  static const String UP_LEFT = "UpLeft";

  /** The diagonal Up-Right Arrow key */
  static const String UP_RIGHT = "UpRight";

  /** The Undo key */
  static const String UNDO = "Undo";

  /** The Volume Down key */
  static const String VOLUME_DOWN = "VolumeDown";

  /** The Volume Mute key */
  static const String VOLUMN_MUTE = "VolumeMute";

  /** The Volume Up key */
  static const String VOLUMN_UP = "VolumeUp";

  /** The Windows Logo key */
  static const String WIN = "Win";

  /** The Zoom key */
  static const String ZOOM = "Zoom";

  /**
   * The Backspace (Back) key. Note: This key value shall be also used for the
   * key labeled 'delete' MacOS keyboards when not modified by the 'Fn' key
   */
  static const String BACKSPACE = "Backspace";

  /** The Horizontal Tabulation (Tab) key */
  static const String TAB = "Tab";

  /** The Cancel key */
  static const String CANCEL = "Cancel";

  /** The Escape (Esc) key */
  static const String ESC = "Esc";

  /** The Space (Spacebar) key:   */
  static const String SPACEBAR = "Spacebar";

  /**
   * The Delete (Del) Key. Note: This key value shall be also used for the key
   * labeled 'delete' MacOS keyboards when modified by the 'Fn' key
   */
  static const String DEL = "Del";

  /** The Combining Grave Accent (Greek Varia, Dead Grave) key */
  static const String DEAD_GRAVE = "DeadGrave";

  /**
   * The Combining Acute Accent (Stress Mark, Greek Oxia, Tonos, Dead Eacute)
   * key
   */
  static const String DEAD_EACUTE = "DeadEacute";

  /** The Combining Circumflex Accent (Hat, Dead Circumflex) key */
  static const String DEAD_CIRCUMFLEX = "DeadCircumflex";

  /** The Combining Tilde (Dead Tilde) key */
  static const String DEAD_TILDE = "DeadTilde";

  /** The Combining Macron (Long, Dead Macron) key */
  static const String DEAD_MACRON = "DeadMacron";

  /** The Combining Breve (Short, Dead Breve) key */
  static const String DEAD_BREVE = "DeadBreve";

  /** The Combining Dot Above (Derivative, Dead Above Dot) key */
  static const String DEAD_ABOVE_DOT = "DeadAboveDot";

  /**
   * The Combining Diaeresis (Double Dot Abode, Umlaut, Greek Dialytika,
   * Double Derivative, Dead Diaeresis) key
   */
  static const String DEAD_UMLAUT = "DeadUmlaut";

  /** The Combining Ring Above (Dead Above Ring) key */
  static const String DEAD_ABOVE_RING = "DeadAboveRing";

  /** The Combining Double Acute Accent (Dead Doubleacute) key */
  static const String DEAD_DOUBLEACUTE = "DeadDoubleacute";

  /** The Combining Caron (Hacek, V Above, Dead Caron) key */
  static const String DEAD_CARON = "DeadCaron";

  /** The Combining Cedilla (Dead Cedilla) key */
  static const String DEAD_CEDILLA = "DeadCedilla";

  /** The Combining Ogonek (Nasal Hook, Dead Ogonek) key */
  static const String DEAD_OGONEK = "DeadOgonek";

  /**
   * The Combining Greek Ypogegrammeni (Greek Non-Spacing Iota Below, Iota
   * Subscript, Dead Iota) key
   */
  static const String DEAD_IOTA = "DeadIota";

  /**
   * The Combining Katakana-Hiragana Voiced Sound Mark (Dead Voiced Sound) key
   */
  static const String DEAD_VOICED_SOUND = "DeadVoicedSound";

  /**
   * The Combining Katakana-Hiragana Semi-Voiced Sound Mark (Dead Semivoiced
   * Sound) key
   */
  static const String DEC_SEMIVOICED_SOUND= "DeadSemivoicedSound";

  /**
   * Key value used when an implementation is unable to identify another key
   * value, due to either hardware, platform, or software constraints
   */
  static const String UNIDENTIFIED = "Unidentified";
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * Internal class that does the actual calculations to determine keyCode and
 * charCode for keydown, keypress, and keyup events for all browsers.
 */
class _KeyboardEventHandler extends EventStreamProvider<KeyEvent> {
  // This code inspired by Closure's KeyHandling library.
  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keyhandler.js.source.html

  /**
   * The set of keys that have been pressed down without seeing their
   * corresponding keyup event.
   */
  final List<KeyEvent> _keyDownList = <KeyEvent>[];

  /** The type of KeyEvent we are tracking (keyup, keydown, keypress). */
  final String _type;

  /** The element we are watching for events to happen on. */
  final EventTarget _target;

  // The distance to shift from upper case alphabet Roman letters to lower case.
  static final int _ROMAN_ALPHABET_OFFSET = "a".codeUnits[0] - "A".codeUnits[0];

  /** Custom Stream (Controller) to produce KeyEvents for the stream. */
  _CustomKeyEventStreamImpl _stream;

  static const _EVENT_TYPE = 'KeyEvent';

  /**
   * An enumeration of key identifiers currently part of the W3C draft for DOM3
   * and their mappings to keyCodes.
   * http://www.w3.org/TR/DOM-Level-3-Events/keyset.html#KeySet-Set
   */
  static const Map<String, int> _keyIdentifier = const {
    'Up': KeyCode.UP,
    'Down': KeyCode.DOWN,
    'Left': KeyCode.LEFT,
    'Right': KeyCode.RIGHT,
    'Enter': KeyCode.ENTER,
    'F1': KeyCode.F1,
    'F2': KeyCode.F2,
    'F3': KeyCode.F3,
    'F4': KeyCode.F4,
    'F5': KeyCode.F5,
    'F6': KeyCode.F6,
    'F7': KeyCode.F7,
    'F8': KeyCode.F8,
    'F9': KeyCode.F9,
    'F10': KeyCode.F10,
    'F11': KeyCode.F11,
    'F12': KeyCode.F12,
    'U+007F': KeyCode.DELETE,
    'Home': KeyCode.HOME,
    'End': KeyCode.END,
    'PageUp': KeyCode.PAGE_UP,
    'PageDown': KeyCode.PAGE_DOWN,
    'Insert': KeyCode.INSERT
  };

  /** Return a stream for KeyEvents for the specified target. */
  // Note: this actually functions like a factory constructor.
  CustomStream<KeyEvent> forTarget(EventTarget e, {bool useCapture: false}) {
    var handler = new _KeyboardEventHandler.initializeAllEventListeners(
        _type, e);
    return handler._stream;
  }

  /**
   * General constructor, performs basic initialization for our improved
   * KeyboardEvent controller.
   */
  _KeyboardEventHandler(this._type):
      _stream = new _CustomKeyEventStreamImpl('event'), _target = null,
      super(_EVENT_TYPE);

  /**
   * Hook up all event listeners under the covers so we can estimate keycodes
   * and charcodes when they are not provided.
   */
  _KeyboardEventHandler.initializeAllEventListeners(this._type, this._target) :
      super(_EVENT_TYPE) {
    Element.keyDownEvent.forTarget(_target, useCapture: true).listen(
        processKeyDown);
    Element.keyPressEvent.forTarget(_target, useCapture: true).listen(
        processKeyPress);
    Element.keyUpEvent.forTarget(_target, useCapture: true).listen(
        processKeyUp);
    _stream = new _CustomKeyEventStreamImpl(_type);
  }

  /** Determine if caps lock is one of the currently depressed keys. */
  bool get _capsLockOn =>
      _keyDownList.any((var element) => element.keyCode == KeyCode.CAPS_LOCK);

  /**
   * Given the previously recorded keydown key codes, see if we can determine
   * the keycode of this keypress [event]. (Generally browsers only provide
   * charCode information for keypress events, but with a little
   * reverse-engineering, we can also determine the keyCode.) Returns
   * KeyCode.UNKNOWN if the keycode could not be determined.
   */
  int _determineKeyCodeForKeypress(KeyboardEvent event) {
    // Note: This function is a work in progress. We'll expand this function
    // once we get more information about other keyboards.
    for (var prevEvent in _keyDownList) {
      if (prevEvent._shadowCharCode == event.charCode) {
        return prevEvent.keyCode;
      }
      if ((event.shiftKey || _capsLockOn) && event.charCode >= "A".codeUnits[0]
          && event.charCode <= "Z".codeUnits[0] && event.charCode +
          _ROMAN_ALPHABET_OFFSET == prevEvent._shadowCharCode) {
        return prevEvent.keyCode;
      }
    }
    return KeyCode.UNKNOWN;
  }

  /**
   * Given the 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 = attributes
        ?.map /*<String>*/ ((name) => '$tagNameUpper::${name.toLowerCase()}');
    var uriAttrs = uriAttributes
        ?.map /*<String>*/ ((name) => '$tagNameUpper::${name.toLowerCase()}');
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }

    add(new _CustomElementNodeValidator(
        uriPolicy, [tagNameUpper], attrs, uriAttrs, false, true));
  }

  /**
   * Allow custom tag extensions with the specified type name and specified
   * attributes.
   *
   * This will allow tag extensions (such as <div is="x-foo"></div>),
   * but will not allow custom tags. Use [allowCustomElement] to allow
   * custom tags.
   */
  void allowTagExtension(String tagName, String baseName,
      {UriPolicy uriPolicy,
      Iterable<String> attributes,
      Iterable<String> uriAttributes}) {
    var baseNameUpper = baseName.toUpperCase();
    var tagNameUpper = tagName.toUpperCase();
    var attrs = attributes
        ?.map /*<String>*/ ((name) => '$baseNameUpper::${name.toLowerCase()}');
    var uriAttrs = uriAttributes
        ?.map /*<String>*/ ((name) => '$baseNameUpper::${name.toLowerCase()}');
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }

    add(new _CustomElementNodeValidator(uriPolicy,
        [tagNameUpper, baseNameUpper], attrs, uriAttrs, true, false));
  }

  void allowElement(String tagName,
      {UriPolicy uriPolicy,
      Iterable<String> attributes,
      Iterable<String> uriAttributes}) {
    allowCustomElement(tagName,
        uriPolicy: uriPolicy,
        attributes: attributes,
        uriAttributes: uriAttributes);
  }

  /**
   * Allow templating elements (such as <template> and template-related
   * attributes.
   *
   * This still requires other validators to allow regular attributes to be
   * bound (such as [allowHtml5]).
   */
  void allowTemplating() {
    add(new _TemplatingNodeValidator());
  }

  /**
   * Add an additional validator to the current list of validators.
   *
   * Elements and attributes will be accepted if they are accepted by any
   * validators.
   */
  void add(NodeValidator validator) {
    _validators.add(validator);
  }

  bool allowsElement(Element element) {
    return _validators.any((v) => v.allowsElement(element));
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    return _validators
        .any((v) => v.allowsAttribute(element, attributeName, value));
  }
}

class _SimpleNodeValidator implements NodeValidator {
  final Set<String> allowedElements = new Set<String>();
  final Set<String> allowedAttributes = new Set<String>();
  final Set<String> allowedUriAttributes = new Set<String>();
  final UriPolicy uriPolicy;

  factory _SimpleNodeValidator.allowNavigation(UriPolicy uriPolicy) {
    return new _SimpleNodeValidator(uriPolicy, allowedElements: const [
      'A',
      'FORM'
    ], allowedAttributes: const [
      'A::accesskey',
      'A::coords',
      'A::hreflang',
      'A::name',
      'A::shape',
      'A::tabindex',
      'A::target',
      'A::type',
      'FORM::accept',
      'FORM::autocomplete',
      'FORM::enctype',
      'FORM::method',
      'FORM::name',
      'FORM::novalidate',
      'FORM::target',
    ], allowedUriAttributes: const [
      'A::href',
      'FORM::action',
    ]);
  }

  factory _SimpleNodeValidator.allowImages(UriPolicy uriPolicy) {
    return new _SimpleNodeValidator(uriPolicy, allowedElements: const [
      'IMG'
    ], allowedAttributes: const [
      'IMG::align',
      'IMG::alt',
      'IMG::border',
      'IMG::height',
      'IMG::hspace',
      'IMG::ismap',
      'IMG::name',
      'IMG::usemap',
      'IMG::vspace',
      'IMG::width',
    ], allowedUriAttributes: const [
      'IMG::src',
    ]);
  }

  factory _SimpleNodeValidator.allowTextElements() {
    return new _SimpleNodeValidator(null, allowedElements: const [
      'B',
      'BLOCKQUOTE',
      'BR',
      'EM',
      'H1',
      'H2',
      'H3',
      'H4',
      'H5',
      'H6',
      'HR',
      'I',
      'LI',
      'OL',
      'P',
      'SPAN',
      'UL',
    ]);
  }

  /**
   * Elements must be uppercased tag names. For example `'IMG'`.
   * Attributes must be uppercased tag name followed by :: followed by
   * lowercase attribute name. For example `'IMG:src'`.
   */
  _SimpleNodeValidator(this.uriPolicy,
      {Iterable<String> allowedElements,
      Iterable<String> allowedAttributes,
      Iterable<String> allowedUriAttributes}) {
    this.allowedElements.addAll(allowedElements ?? const []);
    allowedAttributes = allowedAttributes ?? const [];
    allowedUriAttributes = allowedUriAttributes ?? const [];
    var legalAttributes = allowedAttributes
        .where((x) => !_Html5NodeValidator._uriAttributes.contains(x));
    var extraUriAttributes = allowedAttributes
        .where((x) => _Html5NodeValidator._uriAttributes.contains(x));
    this.allowedAttributes.addAll(legalAttributes);
    this.allowedUriAttributes.addAll(allowedUriAttributes);
    this.allowedUriAttributes.addAll(extraUriAttributes);
  }

  bool allowsElement(Element element) {
    return allowedElements.contains(Element._safeTagName(element));
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    var tagName = Element._safeTagName(element);
    if (allowedUriAttributes.contains('$tagName::$attributeName')) {
      return uriPolicy.allowsUri(value);
    } else if (allowedUriAttributes.contains('*::$attributeName')) {
      return uriPolicy.allowsUri(value);
    } else if (allowedAttributes.contains('$tagName::$attributeName')) {
      return true;
    } else if (allowedAttributes.contains('*::$attributeName')) {
      return true;
    } else if (allowedAttributes.contains('$tagName::*')) {
      return true;
    } else if (allowedAttributes.contains('*::*')) {
      return true;
    }
    return false;
  }
}

class _CustomElementNodeValidator extends _SimpleNodeValidator {
  final bool allowTypeExtension;
  final bool allowCustomTag;

  _CustomElementNodeValidator(
      UriPolicy uriPolicy,
      Iterable<String> allowedElements,
      Iterable<String> allowedAttributes,
      Iterable<String> allowedUriAttributes,
      bool allowTypeExtension,
      bool allowCustomTag)
      : this.allowTypeExtension = allowTypeExtension == true,
        this.allowCustomTag = allowCustomTag == true,
        super(uriPolicy,
            allowedElements: allowedElements,
            allowedAttributes: allowedAttributes,
            allowedUriAttributes: allowedUriAttributes);

  bool allowsElement(Element element) {
    if (allowTypeExtension) {
      var isAttr = element.attributes['is'];
      if (isAttr != null) {
        return allowedElements.contains(isAttr.toUpperCase()) &&
            allowedElements.contains(Element._safeTagName(element));
      }
    }
    return allowCustomTag &&
        allowedElements.contains(Element._safeTagName(element));
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (allowsElement(element)) {
      if (allowTypeExtension &&
          attributeName == 'is' &&
          allowedElements.contains(value.toUpperCase())) {
        return true;
      }
      return super.allowsAttribute(element, attributeName, value);
    }
    return false;
  }
}

class _TemplatingNodeValidator extends _SimpleNodeValidator {
  static const _TEMPLATE_ATTRS = const <String>[
    'bind',
    'if',
    'ref',
    'repeat',
    'syntax'
  ];

  final Set<String> _templateAttrs;

  _TemplatingNodeValidator()
      : _templateAttrs = new Set<String>.from(_TEMPLATE_ATTRS),
        super(null,
            allowedElements: ['TEMPLATE'],
            allowedAttributes:
                _TEMPLATE_ATTRS.map((attr) => 'TEMPLATE::$attr')) {}

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (super.allowsAttribute(element, attributeName, value)) {
      return true;
    }

    if (attributeName == 'template' && value == "") {
      return true;
    }

    if (element.attributes['template'] == "") {
      return _templateAttrs.contains(attributeName);
    }
    return false;
  }
}

class _SvgNodeValidator implements NodeValidator {
  bool allowsElement(Element element) {
    if (element is svg.ScriptElement) {
      return false;
    }
    // Firefox 37 has issues with creating foreign elements inside a
    // foreignobject tag as SvgElement. We don't want foreignobject contents
    // anyway, so just remove the whole tree outright. And we can't rely
    // on IE recognizing the SvgForeignObject type, so go by tagName. Bug 23144
    if (element is svg.SvgElement &&
        Element._safeTagName(element) == 'foreignObject') {
      return false;
    }
    if (element is svg.SvgElement) {
      return true;
    }
    return false;
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (attributeName == 'is' || attributeName.startsWith('on')) {
      return false;
    }
    return allowsElement(element);
  }
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * Contains the set of standard values returned by HTMLDocument.getReadyState.
 */
abstract class ReadyState {
  /**
   * Indicates the document is still loading and parsing.
   */
  static const String LOADING = "loading";

  /**
   * Indicates the document is finished parsing but is still loading
   * subresources.
   */
  static const String INTERACTIVE = "interactive";

  /**
   * Indicates the document and all subresources have been loaded.
   */
  static const String COMPLETE = "complete";
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.



/**
 * Interface used to validate that only accepted elements and attributes are
 * allowed while parsing HTML strings into DOM nodes.
 *
 * In general, customization of validation behavior should be done via the
 * [NodeValidatorBuilder] class to mitigate the chances of incorrectly
 * implementing validation rules.
 */
abstract class NodeValidator {

  /**
   * Construct a default NodeValidator which only accepts whitelisted HTML5
   * elements and attributes.
   *
   * If a uriPolicy is not specified then the default uriPolicy will be used.
   */
  factory NodeValidator({UriPolicy uriPolicy}) =>
      new _Html5NodeValidator(uriPolicy: uriPolicy);

  factory NodeValidator.throws(NodeValidator base) =>
      new _ThrowsNodeValidator(base);

  /**
   * Returns true if the tagName is an accepted type.
   */
  bool allowsElement(Element element);

  /**
   * Returns true if the attribute is allowed.
   *
   * The attributeName parameter will always be in lowercase.
   *
   * See [allowsElement] for format of tagName.
   */
  bool allowsAttribute(Element element, String attributeName, String value);
}

/**
 * Performs sanitization of a node tree after construction to ensure that it
 * does not contain any disallowed elements or attributes.
 *
 * In general custom implementations of this class should not be necessary and
 * all validation customization should be done in custom NodeValidators, but
 * custom implementations of this class can be created to perform more complex
 * tree sanitization.
 */
abstract class NodeTreeSanitizer {

  /**
   * Constructs a default tree sanitizer which will remove all elements and
   * attributes which are not allowed by the provided validator.
   */
  factory NodeTreeSanitizer(NodeValidator validator) =>
      new _ValidatingTreeSanitizer(validator);

  /**
   * Called with the root of the tree which is to be sanitized.
   *
   * This method needs to walk the entire tree and either remove elements and
   * attributes which are not recognized as safe or throw an exception which
   * will mark the entire tree as unsafe.
   */
  void sanitizeTree(Node node);

  /**
   * A sanitizer for trees that we trust. It does no validation and allows
   * any elements. It is also more efficient, since it can pass the text
   * directly through to the underlying APIs without creating a document
   * fragment to be sanitized.
   */
  static const trusted = const _TrustedHtmlTreeSanitizer();
}

/**
 * A sanitizer for trees that we trust. It does no validation and allows
 * any elements.
 */
class _TrustedHtmlTreeSanitizer implements NodeTreeSanitizer {
  const _TrustedHtmlTreeSanitizer();

  sanitizeTree(Node node) {}
}

/**
 * Defines the policy for what types of uris are allowed for particular
 * attribute values.
 *
 * This can be used to provide custom rules such as allowing all http:// URIs
 * for image attributes but only same-origin URIs for anchor tags.
 */
abstract class UriPolicy {
  /**
   * Constructs the default UriPolicy which is to only allow Uris to the same
   * origin as the application was launched from.
   *
   * This will block all ftp: mailto: URIs. It will also block accessing
   * https://example.com if the app is running from http://example.com.
   */
  factory UriPolicy() => new _SameOriginUriPolicy();

  /**
   * Checks if the uri is allowed on the specified attribute.
   *
   * The uri provided may or may not be a relative path.
   */
  bool allowsUri(String uri);
}

/**
 * Allows URIs to the same origin as the current application was loaded from
 * (such as https://example.com:80).
 */
class _SameOriginUriPolicy implements UriPolicy {
  final AnchorElement _hiddenAnchor = new AnchorElement();
  final Location _loc = window.location;

  bool allowsUri(String uri) {
    _hiddenAnchor.href = uri;
    // IE leaves an empty hostname for same-origin URIs.
    return (_hiddenAnchor.hostname == _loc.hostname &&
        _hiddenAnchor.port == _loc.port &&
        _hiddenAnchor.protocol == _loc.protocol) ||
        (_hiddenAnchor.hostname == '' &&
        _hiddenAnchor.port == '' &&
        (_hiddenAnchor.protocol == ':' || _hiddenAnchor.protocol == ''));
  }
}


class _ThrowsNodeValidator implements NodeValidator {
  final NodeValidator validator;

  _ThrowsNodeValidator(this.validator) {}

  bool allowsElement(Element element) {
    if (!validator.allowsElement(element)) {
      throw new ArgumentError(Element._safeTagName(element));
    }
    return true;
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (!validator.allowsAttribute(element, attributeName, value)) {
      throw new ArgumentError('${Element._safeTagName(element)}[$attributeName="$value"]');
    }
  }
}


/**
 * Standard tree sanitizer which validates a node tree against the provided
 * validator and removes any nodes or attributes which are not allowed.
 */
class _ValidatingTreeSanitizer implements NodeTreeSanitizer {
  NodeValidator validator;
  _ValidatingTreeSanitizer(this.validator) {}

  void sanitizeTree(Node node) {
    void walk(Node node, Node parent) {
      sanitizeNode(node, parent);

      var child = node.lastChild;
      while (null != child) {
        var nextChild;
        try {
          // Child may be removed during the walk, and we may not
          // even be able to get its previousNode.
          nextChild = child.previousNode;
        } catch (e) {
          // Child appears bad, remove it. We want to check the rest of the
          // children of node and, but we have no way of getting to the next
          // child, so start again from the last child.
          _removeNode(child, node);
          child = null;
          nextChild = node.lastChild;
        }
        if (child != null) walk(child, node);
        child = nextChild;
      }
    }
    walk(node, null);
  }

  /// Aggressively try to remove node.
  void _removeNode(Node node, Node parent) {
    // If we have the parent, it's presumably already passed more sanitization
    // or is the fragment, so ask it to remove the child. And if that fails
    // try to set the outer html.
    if (parent == null) {
      node.remove();
    } else {
      parent._removeChild(node);
    }
  }

  /// Sanitize the element, assuming we can't trust anything about it.
  void _sanitizeUntrustedElement(/* Element */ element, Node parent) {
    // If the _hasCorruptedAttributes does not successfully return false,
    // then we consider it corrupted and remove.
    // TODO(alanknight): This is a workaround because on Firefox
    // embed/object
    // tags typeof is "function", not "object". We don't recognize them, and
    // can't call methods. This does mean that you can't explicitly allow an
    // embed tag. The only thing that will let it through is a null
    // sanitizer that doesn't traverse the tree at all. But sanitizing while
    // allowing embeds seems quite unlikely. This is also the reason that we
    // can't declare the type of element, as an embed won't pass any type
    // check in dart2js.
    var corrupted = true;
    var attrs;
    var isAttr;
    try {
      // If getting/indexing attributes throws, count that as corrupt.
      attrs = element.attributes;
      isAttr = attrs['is'];
      var corruptedTest1 = Element._hasCorruptedAttributes(element);

      // On IE, erratically, the hasCorruptedAttributes test can return false,
      // even though it clearly is corrupted. A separate copy of the test
      // inlining just the basic check seems to help.
      corrupted = corruptedTest1 ? true : Element._hasCorruptedAttributesAdditionalCheck(element);
    } catch(e) {}
    var elementText = 'element unprintable';
    try {
      elementText = element.toString();
    } catch(e) {}
    try {
      var elementTagName = Element._safeTagName(element);
      _sanitizeElement(element, parent, corrupted, elementText, elementTagName,
          attrs, isAttr);
    } on ArgumentError { // Thrown by _ThrowsNodeValidator
      rethrow;
    } catch(e) {  // Unexpected exception sanitizing -> remove
      _removeNode(element, parent);
      window.console.warn('Removing corrupted element $elementText');
    }
  }

  /// Having done basic sanity checking on the element, and computed the
  /// important attributes we want to check, remove it if it's not valid
  /// or not allowed, either as a whole or particular attributes.
  void _sanitizeElement(Element element, Node parent, bool corrupted,
      String text, String tag, Map attrs, String isAttr) {
    if (false != corrupted) {
       _removeNode(element, parent);
      window.console.warn(
          'Removing element due to corrupted attributes on <$text>');
       return;
    }
    if (!validator.allowsElement(element)) {
      _removeNode(element, parent);
      window.console.warn(
          'Removing disallowed element <$tag> from $parent');
      return;
    }

    if (isAttr != null) {
      if (!validator.allowsAttribute(element, 'is', isAttr)) {
        _removeNode(element, parent);
        window.console.warn('Removing disallowed type extension '
            '<$tag is="$isAttr">');
        return;
      }
    }

    // TODO(blois): Need to be able to get all attributes, irrespective of
    // XMLNS.
    var keys = attrs.keys.toList();
    for (var i = attrs.length - 1; i >= 0; --i) {
      var name = keys[i];
      if (!validator.allowsAttribute(element, name.toLowerCase(),
          attrs[name])) {
        window.console.warn('Removing disallowed attribute '
            '<$tag $name="${attrs[name]}">');
        attrs.remove(name);
      }
    }

    if (element is TemplateElement) {
      TemplateElement template = element;
      sanitizeTree(template.content);
     }
  }

  /// Sanitize the node and its children recursively.
  void sanitizeNode(Node node, Node parent) {
    switch (node.nodeType) {
      case Node.ELEMENT_NODE:
        _sanitizeUntrustedElement(node, parent);
        break;
      case Node.COMMENT_NODE:
      case Node.DOCUMENT_FRAGMENT_NODE:
      case Node.TEXT_NODE:
      case Node.CDATA_SECTION_NODE:
        break;
      default:
        _removeNode(node, parent);
    }
  }
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * A list which just wraps another list, for either intercepting list calls or
 * retyping the list (for example, from List<A> to List<B> where B extends A).
 */
class _WrappedList<E extends Node> extends ListBase<E>
    implements NodeListWrapper {
  final List<Node> _list;

  _WrappedList(this._list);

  // Iterable APIs

  Iterator<E> get iterator => new _WrappedIterator<E>(_list.iterator);

  int get length => _list.length;

  // Collection APIs

  void add(E element) { _list.add(element); }

  bool remove(Object element) => _list.remove(element);

  void clear() { _list.clear(); }

  // List APIs

  E operator [](int index) => _downcast/*<Node, E>*/(_list[index]);

  void operator []=(int index, E value) { _list[index] = value; }

  set length(int newLength) { _list.length = newLength; }

  void sort([int compare(E a, E b)]) { _list.sort((Node a, Node b) => compare(_downcast/*<Node, E>*/(a), _downcast/*<Node, E>*/(b))); }

  int indexOf(Object element, [int start = 0]) => _list.indexOf(element, start);

  int lastIndexOf(Object element, [int start]) => _list.lastIndexOf(element, start);

  void insert(int index, E element) => _list.insert(index, element);

  E removeAt(int index) => _downcast/*<Node, E>*/(_list.removeAt(index));

  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
    _list.setRange(start, end, iterable, skipCount);
  }

  void removeRange(int start, int end) { _list.removeRange(start, end); }

  void replaceRange(int start, int end, Iterable<E> iterable) {
    _list.replaceRange(start, end, iterable);
  }

  void fillRange(int start, int end, [E fillValue]) {
    _list.fillRange(start, end, fillValue);
  }

  List<Node> get rawList => _list;
}

/**
 * Iterator wrapper for _WrappedList.
 */
class _WrappedIterator<E extends Node> implements Iterator<E> {
  Iterator<Node> _iterator;

  _WrappedIterator(this._iterator);

  bool moveNext() {
    return _iterator.moveNext();
  }

  E get current => _downcast/*<Node, E>*/(_iterator.current);
}

// ignore: STRONG_MODE_DOWN_CAST_COMPOSITE
/*=To*/ _downcast/*<From, To extends From>*/(dynamic /*=From*/ x) => x;
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


class _HttpRequestUtils {

  // Helper for factory HttpRequest.get
  static HttpRequest get(String url,
                            onComplete(HttpRequest request),
                            bool withCredentials) {
    final request = new HttpRequest();
    request.open('GET', url, async: true);

    request.withCredentials = withCredentials;

    request.onReadyStateChange.listen((e) {
      if (request.readyState == HttpRequest.DONE) {
        onComplete(request);
      }
    });

    request.send();

    return request;
  }
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


// Iterator for arrays with fixed size.
class FixedSizeListIterator<T> implements Iterator<T> {
  final List<T> _array;
  final int _length;  // Cache array length for faster access.
  int _position;
  T _current;
  
  FixedSizeListIterator(List<T> array)
      : _array = array,
        _position = -1,
        _length = array.length;

  bool moveNext() {
    int nextPosition = _position + 1;
    if (nextPosition < _length) {
      _current = _array[nextPosition];
      _position = nextPosition;
      return true;
    }
    _current = null;
    _position = _length;
    return false;
  }

  T get current => _current;
}

// Iterator for arrays with variable size.
class _VariableSizeListIterator<T> implements Iterator<T> {
  final List<T> _array;
  int _position;
  T _current;

  _VariableSizeListIterator(List<T> array)
      : _array = array,
        _position = -1;

  bool moveNext() {
    int nextPosition = _position + 1;
    if (nextPosition < _array.length) {
      _current = _array[nextPosition];
      _position = nextPosition;
      return true;
    }
    _current = null;
    _position = _array.length;
    return false;
  }

  T get current => _current;
}
// Copyright (c) 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;
  final String _extendsTag;

  _VMElementUpgrader(Document document, Type type, String extendsTag) :
      _type = type,
      _extendsTag = extendsTag,
      _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) {
    // Only exact type matches are supported- cannot be a subclass.
    if (element.runtimeType != _nativeType) {
      throw new ArgumentError('element is not subclass of $_nativeType');
    }
    return _createCustomUpgrader(_type, element);
  }
}

/// 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);
  if (cls.isAbstract) {
    throw new UnsupportedError('Invalid custom element '
        'class $className is abstract.');
  }

  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 {
  /** Needed because KeyboardEvent is implements.
   */
  /** The parent KeyboardEvent that this KeyEvent is wrapping and "fixing". */
  KeyboardEvent _parent;

  /** The "fixed" value of whether the alt key is being pressed. */
  bool _shadowAltKey;

  /** Calculated value of what the estimated charCode is for this event. */
  int _shadowCharCode;

  /** Calculated value of what the estimated keyCode is for this event. */
  int _shadowKeyCode;

  /** Calculated value of what the estimated keyCode is for this event. */
  int get keyCode => _shadowKeyCode;

  /** Calculated value of what the estimated charCode is for this event. */
  int get charCode => this.type == 'keypress' ? _shadowCharCode : 0;

  /** Calculated value of whether the alt key is pressed is for this event. */
  bool get altKey => _shadowAltKey;

  /** Calculated value of what the estimated keyCode is for this event. */
  int get which => keyCode;

  /** Accessor to the underlying keyCode value is the parent event. */
  int get _realKeyCode => _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;

  /** 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;
  /** True if the Meta (or Mac command) key is pressed during this event. */
  bool get metaKey => _parent.metaKey;
  /** True if the shift key was pressed during this event. */
  bool get shiftKey => _parent.shiftKey;
  Window get view => _parent.view;
  void _initUIEvent(String type, bool canBubble, bool cancelable,
      Window view, int detail) {
    throw new UnsupportedError("Cannot initialize a UI Event from a KeyEvent.");
  }
  String get _shadowKeyIdentifier => _parent._keyIdentifier;

  int get _charCode => charCode;
  int get _keyCode => keyCode;
  int get _which => which;
  String get _keyIdentifier {
    throw new UnsupportedError("keyIdentifier is unsupported.");
  }
  void _initKeyboardEvent(String type, bool canBubble, bool cancelable,
      Window view, String keyIdentifier, int keyLocation, bool ctrlKey,
      bool altKey, bool shiftKey, bool metaKey) {
    throw new UnsupportedError(
        "Cannot initialize a KeyboardEvent from a KeyEvent.");
  }
  @Experimental() // untriaged
  bool getModifierState(String keyArgument) => throw new UnimplementedError();
  @Experimental() // untriaged
  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.
 * TODO(jacobr): consider using dart JsNative.$setInstanceInterceptor
 * instead of using wrappers as that would allow passing these wrappers
 * back through dispatchEvent unlike the current implementation.
 * See https://github.com/dart-lang/sdk/issues/16869
 */
class _WrappedEvent implements Event {
  /** Needed because KeyboardEvent is implements.
   */
  final Event wrapped;

  /** The CSS selector involved with event delegation. */
  String _selector;

  _WrappedEvent(this.wrapped);

  bool get bubbles => wrapped.bubbles;

  bool get cancelable => wrapped.cancelable;

  EventTarget get currentTarget => wrapped.currentTarget;

  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.


// TODO(jacobr): remove these typedefs when dart:async supports generic types.
typedef R _wrapZoneCallback<A, R>(A a);
typedef R _wrapZoneBinaryCallback<A, B, R>(A a, B b);

_wrapZoneCallback/*<A, R>*/ _wrapZone/*<A, R>*/(_wrapZoneCallback/*<A, R>*/ callback) {
  // For performance reasons avoid wrapping if we are in the root zone.
  if (Zone.current == Zone.ROOT) return callback;
  if (callback == null) return null;
  // TODO(jacobr): we cast to _wrapZoneCallback/*<A, R>*/ to hack around missing
  // generic method support in zones.
  // ignore: STRONG_MODE_DOWN_CAST_COMPOSITE
  _wrapZoneCallback/*<A, R>*/ wrapped =
      Zone.current.bindUnaryCallback(callback, runGuarded: true);
  return wrapped;
}

_wrapZoneBinaryCallback/*<A, B, R>*/ _wrapBinaryZone/*<A, B, R>*/(_wrapZoneBinaryCallback/*<A, B, R>*/ callback) {
  if (Zone.current == Zone.ROOT) return callback;
  if (callback == null) return null;
  // We cast to _wrapZoneBinaryCallback/*<A, B, R>*/ to hack around missing
  // generic method support in zones.
  // ignore: STRONG_MODE_DOWN_CAST_COMPOSITE
  _wrapZoneBinaryCallback/*<A, B, R>*/ wrapped =
      Zone.current.bindBinaryCallback(callback, runGuarded: true);
  return wrapped;
}

/**
 * Alias for [querySelector]. Note this function is deprecated because its
 * semantics will be changing in the future.
 */
@deprecated
@Experimental()
Element query(String relativeSelectors) => document.query(relativeSelectors);
/**
 * Alias for [querySelectorAll]. Note this function is deprecated because its
 * semantics will be changing in the future.
 */
@deprecated
@Experimental()
ElementList<Element> queryAll(String relativeSelectors) => document.queryAll(relativeSelectors);

/**
 * Finds the first descendant element of this document that matches the
 * specified group of selectors.
 *
 * Unless your webpage contains multiple documents, the top-level
 * [querySelector]
 * method behaves the same as this method, so you should use it instead to
 * save typing a few characters.
 *
 * [selectors] should be a string using CSS selector syntax.
 *
 *     var element1 = document.querySelector('.className');
 *     var element2 = document.querySelector('#id');
 *
 * For details about CSS selector syntax, see the
 * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
 */
Element querySelector(String selectors) => document.querySelector(selectors);

/**
 * Finds all descendant elements of this document that match the specified
 * group of selectors.
 *
 * Unless your webpage contains multiple documents, the top-level
 * [querySelectorAll]
 * method behaves the same as this method, so you should use it instead to
 * save typing a few characters.
 *
 * [selectors] should be a string using CSS selector syntax.
 *
 *     var items = document.querySelectorAll('.itemClassName');
 *
 * For details about CSS selector syntax, see the
 * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
 */
ElementList<Element> querySelectorAll(String selectors) => document.querySelectorAll(selectors);

/// A utility for changing the Dart wrapper type for elements.
abstract class ElementUpgrader {
  /// Upgrade the specified element to be of the Dart type this was created for.
  ///
  /// After upgrading the element passed in is invalid and the returned value
  /// should be used instead.
  Element upgrade(Element element);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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;
}

/**
 * Manager for navigating between libraries from the devtools console.
 */
class _LibraryManager {
  /**
   * Current active library
   */
  static var _currentLibrary;
  static var _validCache = false;

  static List<Uri> _libraryUris;

  // List of all maps to check to determine if there is an exact match.
  static Map<String, List<Uri>> _fastPaths;

  static void _addFastPath(String key, Uri uri) {
    _fastPaths.putIfAbsent(key, () => <Uri>[]).add(uri);
  }

  static cache() {
    if (_validCache) return;
    _validCache = true;
    _libraryUris = <Uri>[];
    _fastPaths = new Map<String, List<Uri>>();
    var system = currentMirrorSystem();
    system.libraries.forEach((uri, library) {
      _libraryUris.add(uri);
      _addFastPath(uri.toString(), uri);
      _addFastPath(MirrorSystem.getName(library.simpleName), uri);
    });
  }

  static String get currentLibrary {
    if (_currentLibrary == null) {
      _currentLibrary =
          currentMirrorSystem().isolate.rootLibrary.uri.toString();
    }
    return _currentLibrary;
  }

  /**
   * Find libraries matching a given name.
   *
   * Uses heuristics to only return a single match when the user intent is
   * generally unambiguous.
   */
  static List<Uri> findMatches(String name) {
    cache();
    var nameAsFile = name.endsWith('.dart') ? name : '${name}.dart';
    // Perfect match first.
    var fastPatchMatches = _fastPaths[name];
    if (fastPatchMatches != null) {
      return fastPatchMatches.toList();
    }

    // Exact match for file path.
    var matches = new LinkedHashSet<Uri>();
    for (var uri in _libraryUris) {
      if (uri.path == name || uri.path == nameAsFile) matches.add(uri);
    }
    if (matches.isNotEmpty) return matches.toList();

    // Exact match for file name.
    if (name != nameAsFile) {
      for (var uri in _libraryUris) {
        if (uri.pathSegments.isNotEmpty &&
            (uri.pathSegments.last == nameAsFile)) {
          matches.add(uri);
        }
      }
      if (matches.isNotEmpty) return matches.toList();
    }

    for (var uri in _libraryUris) {
      if (uri.pathSegments.isNotEmpty && (uri.pathSegments.last == name)) {
        matches.add(uri);
      }
    }
    if (matches.isNotEmpty) return matches.toList();

    // Partial match on path.
    for (var uri in _libraryUris) {
      if (uri.path.contains(name)) {
        matches.add(uri);
      }
    }
    if (matches.isNotEmpty) return matches.toList();

    // Partial match on entire uri.
    for (var uri in _libraryUris) {
      if (uri.toString().contains(name)) {
        matches.add(uri);
      }
    }

    if (matches.isNotEmpty) return matches.toList();

    // Partial match on entire uri ignoring case.
    name = name.toLowerCase();
    for (var uri in _libraryUris) {
      if (uri.toString().toLowerCase().contains(name)) {
        matches.add(uri);
      }
    }
    return matches.toList();
  }

  static setLibrary([String name]) {
    // Bust cache in case library list has changed. Ideally we would listen for
    // when libraries are loaded and invalidate based on that.
    _validCache = false;
    cache();
    if (name == null) {
      window.console
        ..group("Current library: $_currentLibrary")
        ..groupCollapsed("All libraries:");
      _listLibraries();
      window.console..groupEnd()..groupEnd();
      return;
    }
    var matches = findMatches(name);
    if (matches.length != 1) {
      if (matches.length > 1) {
        window.console.warn("Ambiguous library name: $name");
      }
      showMatches(name, matches);
      return;
    }
    _currentLibrary = matches.first.toString();
    window.console.log("Set library to $_currentLibrary");
  }

  static getLibrary() {
    return currentLibrary;
  }

  static List<Uri> _sortUris(Iterable<Uri> uris) {
    return (uris.toList())
      ..sort((Uri a, Uri b) {
        if (a.scheme != b.scheme) {
          if (a.scheme == 'dart') return -1;
          if (b.scheme == 'dart') return 1;
          return a.scheme.compareTo(b.scheme);
        }
        return a.toString().compareTo(b.toString());
      });
  }

  static void listLibraries() {
    _validCache = false;
    cache();
    _listLibraries();
  }

  static void _listLibraries() {
    window.console.log(_sortUris(_libraryUris).join("\n"));
  }

  // Workaround to allow calling console.log with an arbitrary number of
  // arguments.
  static void _log(List<String> args) {
    js.JsNative.callMethod(window.console, 'log', args);
  }

  static showMatches(String key, Iterable<Uri> uris) {
    var boldPairs = [];
    var sb = new StringBuffer();
    if (uris.isEmpty) {
      window.console.group("All libraries:");
      _listLibraries();
      window.console
        ..groupEnd()
        ..error("No library names or URIs match '$key'");
      return;
    }
    sb.write("${uris.length} matches\n");
    var lowerCaseKey = key.toLowerCase();
    for (var uri in uris) {
      var txt = uri.toString();
      int index = txt.toLowerCase().indexOf(lowerCaseKey);
      if (index != -1) {
        // %c enables styling console log messages with css
        // specified at the end of the console.
        sb..write(txt.substring(0, index))..write('%c');
        var matchEnd = index + key.length;
        sb
          ..write(txt.substring(index, matchEnd))
          ..write('%c')
          ..write(txt.substring(matchEnd))
          ..write('\n');
        boldPairs..add('font-weight: bold')..add('font-weight: normal');
      }
    }
    _log([sb.toString()]..addAll(boldPairs));
  }
}

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 String getLibraryUrl() => _LibraryManager.currentLibrary;

  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 forwardingPrint(String message) =>
      _blink.Blink_Utils.forwardingPrint(message);
  static void spawnDomHelper(Function f, int replyTo) =>
      _blink.Blink_Utils.spawnDomHelper(f, replyTo);

  // TODO(vsm): Make this API compatible with spawnUri.  It should also
  // return a Future<Isolate>.
  // TODO(jacobr): IS THIS RIGHT? I worry we have broken conversion from Promise to Future.
  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;
      // Avoid being broken by bogus ':async_op' local passed in when within
      // an async method.
      if (arg.startsWith(':')) 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;
  }

  /**
   * Handle special console commands such as $lib and $libs that should not be
   * evaluated as Dart expressions and instead should be interpreted directly.
   * Commands supported:
   * library <-- shows the current library and lists all libraries.
   * library "library_uri" <-- select a specific library
   * library "library_uri_fragment"
   */
  static bool maybeHandleSpecialConsoleCommand(String expression) {
    expression = expression.trim();
    var setLibraryCommand = r'library ';
    if (expression == r'library') {
      _LibraryManager.setLibrary();
      return true;
    }
    if (expression.startsWith(setLibraryCommand)) {
      expression = expression.substring(setLibraryCommand.length);
      if (expression.length >= 2) {
        String start = expression[0];
        String end = expression[expression.length - 1];
        // TODO(jacobr): maybe we should require quotes.
        if ((start == "'" && end == "'") || (start == '"' && end == '"')) {
          expression = expression.substring(1, expression.length - 1);
        }
      }

      _LibraryManager.setLibrary(expression);
      return true;
    }
    return false;
  }

  /**
   * 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) {
        js.JsNative.callMethod(host, "_inspect", [o]);
        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);
}

class _DOMWindowCrossFrame extends DartHtmlDomObject implements WindowBase {
  _DOMWindowCrossFrame.internal();

  static _createSafe(win) {
    if (identical(win, window)) {
      // The current Window object is the only window object that should not
      // use _DOMWindowCrossFrame.
      return window;
    }
    return win is _DOMWindowCrossFrame ? win : _blink.Blink_Utils.setInstanceInterceptor(win, _DOMWindowCrossFrame);
  }

  // Fields.
  HistoryBase get history {
    var history =  _blink.BlinkWindow.instance.history_Getter_(this);
    return history is _HistoryCrossFrame ? history : _blink.Blink_Utils.setInstanceInterceptor(history, _HistoryCrossFrame);
  }

  LocationBase get location {
    var location = _blink.BlinkWindow.instance.location_Getter_(this);
    return location is _LocationCrossFrame ? location : _blink.Blink_Utils.setInstanceInterceptor(location, _LocationCrossFrame);
  }

  bool get closed => _blink.BlinkWindow.instance.closed_Getter_(this);
  WindowBase get opener => _convertNativeToDart_Window(_blink.BlinkWindow.instance.opener_Getter_(this));
  WindowBase get parent => _convertNativeToDart_Window(_blink.BlinkWindow.instance.parent_Getter_(this));
  WindowBase get top => _convertNativeToDart_Window(_blink.BlinkWindow.instance.top_Getter_(this));

  // Methods.
  void close() => _blink.BlinkWindow.instance.close_Callback_0_(this);
  void postMessage(Object message, String targetOrigin, [List<MessagePort> transfer]) => _blink.BlinkWindow.instance.postMessage_Callback_3_(this, convertDartToNative_SerializedScriptValue(message), targetOrigin, transfer);

  // 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 DartHtmlDomObject implements HistoryBase {
  _HistoryCrossFrame.internal();

  // Methods.
  void back() => _blink.BlinkHistory.instance.back_Callback_0_(this);
  void forward() => _blink.BlinkHistory.instance.forward_Callback_0_(this);
  void go([int delta]) {
    if (delta != null) {
      _blink.BlinkHistory.instance.go_Callback_1_(this, delta);
      return;
    }
    _blink.BlinkHistory.instance.go_Callback_0_(this);
    return;
  }

  // Implementation support.
  String get typeName => "History";
}

class _LocationCrossFrame extends DartHtmlDomObject implements LocationBase {
  _LocationCrossFrame.internal();

  // Fields.
  set href(String value) => _blink.BlinkLocation.instance.href_Setter_(this, value);

  // Implementation support.
  String get typeName => "Location";
}

// TODO(vsm): Remove DOM isolate code once we have Dartium isolates
// as workers.  This is only used to support
// printing and timers in background isolates. As workers they should
// be able to just do those things natively.

_makeSendPortFuture(spawnRequest) {
  final completer = new Completer<SendPort>.sync();
  final port = new ReceivePort();
  port.listen((result) {
    completer.complete(result);
    port.close();
  });
  // TODO: SendPort.hashCode is ugly way to access port id.
  spawnRequest(port.sendPort.hashCode);
  return completer.future;
}

Future<SendPort> _spawnDomHelper(Function f) => _makeSendPortFuture((portId) {
      _Utils.spawnDomHelper(f, portId);
    });

final Future<SendPort> __HELPER_ISOLATE_PORT =
    _spawnDomHelper(_helperIsolateMain);

// Tricky part.
// Once __HELPER_ISOLATE_PORT gets resolved, it will still delay in .then
// and to delay Timer.run is used. However, Timer.run will try to register
// another Timer and here we got stuck: event cannot be posted as then
// callback is not executed because it's delayed with timer.
// Therefore once future is resolved, it's unsafe to call .then on it
// in Timer code.
SendPort __SEND_PORT;

_sendToHelperIsolate(msg, SendPort replyTo) {
  if (__SEND_PORT != null) {
    __SEND_PORT.send([msg, replyTo]);
  } else {
    __HELPER_ISOLATE_PORT.then((port) {
      __SEND_PORT = port;
      __SEND_PORT.send([msg, replyTo]);
    });
  }
}

final _TIMER_REGISTRY = new Map<SendPort, Timer>();

const _NEW_TIMER = 'NEW_TIMER';
const _CANCEL_TIMER = 'CANCEL_TIMER';
const _TIMER_PING = 'TIMER_PING';
const _PRINT = 'PRINT';

_helperIsolateMain(originalSendPort) {
  var port = new ReceivePort();
  originalSendPort.send(port.sendPort);
  port.listen((args) {
    var msg = args.first;
    var replyTo = args.last;
    final cmd = msg[0];
    if (cmd == _NEW_TIMER) {
      final duration = new Duration(milliseconds: msg[1]);
      bool periodic = msg[2];
      ping() {
        replyTo.send(_TIMER_PING);
      }
      ;
      _TIMER_REGISTRY[replyTo] = periodic
          ? new Timer.periodic(duration, (_) {
              ping();
            })
          : new Timer(duration, ping);
    } else if (cmd == _CANCEL_TIMER) {
      _TIMER_REGISTRY.remove(replyTo).cancel();
    } else if (cmd == _PRINT) {
      final message = msg[1];
      // TODO(antonm): we need somehow identify those isolates.
      print('[From isolate] $message');
    }
  });
}

final _printClosure = (s) => window.console.log(s);
final _pureIsolatePrintClosure = (s) {
  _sendToHelperIsolate([_PRINT, s], null);
};

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);
    };

class _PureIsolateTimer implements Timer {
  bool _isActive = true;
  final ReceivePort _port = new ReceivePort();
  SendPort _sendPort; // Effectively final.

  //  static SendPort _SEND_PORT;

  _PureIsolateTimer(int milliSeconds, callback, repeating) {
    _sendPort = _port.sendPort;
    _port.listen((msg) {
      assert(msg == _TIMER_PING);
      _isActive = repeating;
      callback(this);
      if (!repeating) _cancel();
    });

    _send([_NEW_TIMER, milliSeconds, repeating]);
  }

  void cancel() {
    _cancel();
    _send([_CANCEL_TIMER]);
  }

  void _cancel() {
    _isActive = false;
    _port.close();
  }

  _send(msg) {
    _sendToHelperIsolate(msg, _sendPort);
  }

  bool get isActive => _isActive;
}

get _pureIsolateTimerFactoryClosure =>
    ((int milliSeconds, void callback(Timer time), bool repeating) =>
        new _PureIsolateTimer(milliSeconds, callback, repeating));

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"));

// Class for unsupported native browser 'DOM' objects.
class _UnsupportedBrowserObject extends DartHtmlDomObject {}
